Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ingestion-keys-init-logger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"braintrust": minor
---

feat: Support ingestion keys in `initLogger`
29 changes: 29 additions & 0 deletions js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,35 @@ If you use TypeScript or other transpilation plugins, place the Braintrust plugi

For deeper details, see the [auto-instrumentation architecture docs](src/auto-instrumentations/README.md).

## Ingestion Keys

An ingestion key lets public clients, like browsers, write traces into a single project without an API key.
Ingestion keys cannot read data, call models, or manage anything, so a logger that uses one never logs in, never looks up or creates the project, and ignores `BRAINTRUST_API_KEY`.

Pass the full ingestion URL of the key, or set it as `BRAINTRUST_INGESTION_KEY`:

```ts
import { initLogger } from "braintrust";

const logger = initLogger({
ingestionKey: "https://<data plane>/ingest?ingestKey=<key>",
});
```

Anyone with the key can write new rows into the project, and can update or delete any row of the project whose id they know, including rows logged with an API key.
Row ids are not secret, so treat everything in the project as writable by the key's users.
Uploaded attachments can only be referenced by rows written with the same key or a key it was rotated from.

An explicit `apiKey` takes precedence over `BRAINTRUST_INGESTION_KEY`, and combining it with `ingestionKey` throws.
A `state` only provides the masking function and current logger, while the logger keeps its own queue and ignores any login of the state.
`projectName` is ignored, and `projectId` or the ids of `orgProjectMetadata` are only sent along for the server to check.
`updateSpan({ exported })` updates project log spans through the current ingestion key logger, and spans exported without a project need `state: logger.loggingState` instead of falling back to an API key.
`ExternalAttachment` is not supported, since it can reference any object store content, so rows that contain one are not logged and the error is reported to `onFlushError`.
Attachments and large batches are uploaded through the ingestion URL as well.
Fields that ingestion keys do not support, like `classifications` or audit fields, are not logged, and logging comments throws.

To export OpenTelemetry spans, point a standard OTLP exporter at the ingestion URL with `/otel/v1/traces` appended and without the query string, and send the key in an `Authorization: Bearer <key>` header.

## Migration Guides

### Upgrading from 2.x to 3.x
Expand Down
Loading
Loading