Skip to content

Import from Braintrust

Connect Braintrust on the Imports page. Metergraph imports spans in a project’s logs whose span_attributes.type is llm, then keeps the selected project level with Braintrust on a schedule.

Braintrust reads LLM spans through the POST /btql query endpoint. Task, tool, function and eval spans are not imported, and scores and evals are never read.

Credential A Braintrust API key, sent as a bearer token
Scope A project name or project id, at most 255 characters (import_connections.py, MAX_SCOPE_LENGTH)
Host https://api.braintrust.dev, the US data plane, by default. Use https://api-eu.braintrust.dev for the EU plane, or your own data plane (import_connections.py, SOURCE_POLICIES; imports.js, baseUrlHelp)

The hosted importer stores the credential encrypted and does not need a Metergraph ingest key. The relay appendix is the path that uses an ingest key (import_providers/__init__.py, module docstring).

In Braintrust, open Settings, go to Organization > API keys, select + API key, give the key a name, and select Create. Copy the key when it is shown because Braintrust does not show it again. Use the sk-... API key, not a provider key from AI providers.

The key inherits the creator’s Braintrust permissions, so the creator must have Read permission on the project and its logs. A service token with the same project Read access also works. See Braintrust’s API key and service token instructions and access control documentation.

  1. Open Imports, select Connect, and choose Braintrust.

  2. Enter the project name or id and a Braintrust API key with permission to read that project’s logs. The project field is limited to 255 characters (import_connections.py, MAX_SCOPE_LENGTH).

  3. Import from defaults to 7 days ago and cannot be in the future. On hosted Metergraph it cannot be more than 90 days back; a self-hosted operator can set that floor from 1 to 366 days (imports.js, defaultInitialSince; config.py, scheduled_imports_max_backfill_days). Run defaults to Every minute. The picker offers Every minute, Every 5 minutes, Every 15 minutes, Every 30 minutes, Every hour, Every 6 hours and Daily. Braintrust has a 1-minute floor and a one-day ceiling (imports.js, INTERVAL_OPTIONS; import_connections.py, CURSOR_MINIMUM_INTERVAL_SECONDS, MAX_INTERVAL_SECONDS, DEFAULT_INTERVAL_SECONDS).

  4. Leave API base URL blank for the US data plane. Open Self-hosted Braintrust to enter https://api-eu.braintrust.dev for the EU plane or your own data plane. The endpoint must be https:// and reachable from the public internet (imports.js, baseUrlHelp; import_egress.py, check_url).

  5. Optionally select Test connection. It checks the key and project with the provider within 6 seconds (braintrust.py, probe, TEST_TIMEOUT_SECONDS). Then select Connect. Connect saves the project and credential without contacting Braintrust. If the workspace already has a checkpoint for the source and project, the connection resumes from it rather than the start date (api/import_connections.py, create_import_connection).

  6. On Imports, inspect Imported through, Calls in selected range, Rows pushed per run, Success rate, Next run and Run history. Then open Traces and check the provider, model, tokens, status, route and timestamp.

Field Where it comes from
Route The LLM span’s own name, falling back to braintrust/backfill. The hosted import has no route override. --route is relay-only
Timestamp The span’s created time, kept as the original
Provider and model Inferred from the span
Tokens The span’s metrics, including cache reads, cache writes and reasoning
Cost Braintrust’s estimated_cost
Latency The span’s own start and end
Status error when the span recorded an error, otherwise success
Content The span’s input and output, copied verbatim
Tool calls and tool names Extracted from the span’s output
Trace, span and parent span The span’s root span id, span id and first span parent
Tags Braintrust span tags under braintrust_tags, and the project id under braintrust_project_id
  • Environment. Braintrust rows arrive with no environment set, so they fall outside any environment filter in the dashboard.
  • Function attribution, streaming detail, outcomes and repository identity, as on every import path.
  • Task, tool, function and eval spans, scores and evals, which are never read.
Symptom Likely cause What to do
Test connection says “Braintrust refused the key” The key is invalid, revoked, cannot read the project, or was sent to the wrong data plane (Braintrust answered 401 or 403) Check the key, the project’s Read permission, and the base URL, then test again
Test connection says “Braintrust could not run the query” The project name or id does not match a project in the key’s organization (Braintrust answered 400 or 404) Copy the exact project name or id from Braintrust, then test again
A scheduled run says “Braintrust could not run the query” The project name or id does not match a project in the key’s organization, or the key creator cannot read the project logs Copy the exact project name or id from Braintrust and verify the creator has Read access to the project and its logs
Test connection says “Could not reach Braintrust at” The base URL is wrong or unreachable Check the URL and public internet reachability (import_egress.py)
A failed hosted run says lease released The importer released its coordination lease after a provider request failed (metergraphrelay/provider_sync.py) Fix the key, project, permissions or data plane, then retry. The lease message is cleanup, not the root cause
The endpoint is refused The hosted egress policy blocks a private, loopback, link-local or metadata address Use a public endpoint, or use the relay appendix (import_egress.py, module docstring)
The query times out Relay only: a pull has no --since on a large project Relay only: bound every pull query with --since
Every route is OpenAI Chat Completion Relay only: the SDK wrapper names spans after the method Relay only: pass --route
Nothing comes back from an EU project Relay only: the relay is querying the US data plane Relay only: set BRAINTRUST_BASE_URL=https://api-eu.braintrust.dev

These are Braintrust errors. A 401 or 403 from Metergraph instead means the Metergraph token is not an ingest key. See the shared import troubleshooting.

Use the relay when the hosted importer cannot reach the Braintrust data plane, or when you need relay-only selector behavior. Set the US or EU base URL in the relay setup as needed.

metergraphrelay pull braintrust --project my-project \
--since 2026-08-01T00:00:00Z --output braintrust.jsonl
metergraphrelay push braintrust.jsonl
Selector Meaning
--project Required project name or id. Repeatable
--since / --until Bound span created time. --since is inclusive and --until is exclusive
-n, --count Caps spans, not traces. The default is 100 (braintrust.py, PAGE_LIMIT)
--route Relay-only route override
metergraphrelay sync braintrust --source-scope my-project \
--initial-since 2026-08-01T00:00:00Z --project my-project

--source-scope is a permanent label for the project and selector set. --initial-since seeds only the first run. The relay and hosted paths share a checkpoint for the same source and scope, so do not run both against one scope. The full contract is in the overview appendix.