Skip to main content

No traces at all: check your baseUrl host

Traces are exported to {baseUrl}/api/v1/traces. The ingest endpoint lives on platform.belvedir.ai. Pointing baseUrl at any other host returns a 404 and the spans are dropped silently: the SDK keeps running and your app shows no error, but nothing is ever stored. Safest is to omit baseUrl entirely, since it defaults to https://platform.belvedir.ai. Set it only for a different platform host.

Using a legacy package or an old SDK version?

If your app still imports @fractalresearch/loop, fractal-loop, @belvedir/loop, or belvedir-loop, uses an fr_live_ key, or is pinned to an older SDK release, several silent failure modes apply that current belvedir releases have fixed. Upgrade to the latest belvedir on npm or PyPI and follow Migrating from Fractal.

Ingest or the router returns 402 or 429

Neither is a code bug. (A 401 is different: the key is unknown or revoked. Check that the request carries a current bv_live_ key from this project’s API Keys page.) A 402 from the router means the organization’s credit balance is used up. Buy credits on Organization Settings → Billing, or turn on Auto reload or pay as you go there with a saved card (saving a card alone does not restore traffic). A 402 from trace ingest means the project is not attached to an organization with billing: create one for it under Organizations. Trace ingestion itself is not billed. A 429 is the per-key rate limit. Ingest and outcome reports allow 2 requests per second sustained with a burst of 120; ingest additionally allows 20 new sessions per second with a burst of 2,000 (an exporter that stamps a fresh session id on every span trips that one). The router allows 25 requests per second with a burst of 300. Back off for the Retry-After seconds and retry.

No traces appearing on Vercel

The Belvedir SDK is built on OpenTelemetry, which requires the Node.js runtime. On Vercel, routes can default to the Edge runtime, where initialization fails: the logs show initialize() failed; the app will run untraced and no spans arrive. Add the following to any API route that makes LLM calls:

I see HTTP spans but no anthropic.chat / openai.chat span

The patch didn’t take. This happens when the LLM SDK was imported before initialize() ran. In Next.js, keep initialization in instrumentation.ts (not a route file) and restart next dev. If you see the initialize() ran after ... was imported warning on startup, that’s the cause. In a plain CommonJS Node process, call initialize() at the very top of your entry file, before importing OpenAI/Anthropic. In an ESM entry point (.mjs, or "type": "module" in package.json) the same failure happens with no warning at all: static imports hoist above the initialize() call and dynamic import() bypasses the require hook, so auto-instrumentation never sees the LLM SDK. In ESM, always pass the SDKs via instrumentModules. In Next.js there’s a second cause: the bundler inlines the LLM SDK into the route, or loads it as an ES module; either way the require() hook auto-instrumentation relies on never fires, even with serverExternalPackages set. The reliable fix is to pass your LLM SDKs to initialize() via instrumentModules so they are patched directly, no matter how they were loaded:
Also keep the LLM SDKs and belvedir itself external (serverExternalPackages on Next 15 and later; experimental.serverComponentsExternalPackages on Next 13/14, where the Next 15 key is silently ignored). An inlined copy is patched or flushed separately from the one your routes use, so spans drop with no error. Setup is in the Next.js guide.

AI SDK app (the ai package) produces no LLM spans

The AI SDK’s native provider packages (@ai-sdk/openai, @ai-sdk/anthropic) and plain "provider/model" gateway strings use protocols Belvedir does not instrument, so those calls produce no LLM spans and no warning. Make the calls with @ai-sdk/openai-compatible instead; the same models keep working, streaming included. See the AI SDK guide.

Conversations captured, but the last assistant reply is missing

When an app calls an OpenAI-compatible endpoint with raw fetch (Node) or requests/httpx (Python) and stream: true, current belvedir releases record the raw HTTP call too, including the full assistant message, tool calls, and usage once the stream ends. If the final reply is still missing, make sure you are on the latest belvedir (npm install belvedir@latest / pip install -U belvedir) and that the process lives long enough for the stream to finish before flush(); on an older release, route the call through the openai client (patched via instrumentModules in Node) instead of raw HTTP.

Spans appear locally but not in production

Serverless functions (Vercel, Lambda, Cloud Functions) can freeze or exit as soon as the response is sent, before the batched spans export. await flush() (Python: loop.flush()) at the end of every handler that makes LLM calls, before returning. See Configuration.

Spans from a background worker or thread are missing, or arrive without a session

initialize() is per process, so a queue worker, forked child, or subprocess that never called it exports nothing, and flush() there silently no-ops. Separately, the session context never crosses a thread, process, or queue boundary, so pass the session id in the job payload and re-open session(session_id=...) inside the worker. The Background workers guide has the pattern.

Traces show up but no tasks or task groups

Tasks and task groups only form for work wrapped in withSession (Python: session()). Make sure your agent runs inside it, and give the session a short period of inactivity: segmentation only runs once a session goes quiet. See How it works. A withSession call with no session id logs a warning; spans without a session never form tasks.

reportOutcome returns false (or POST /api/v1/outcomes returns 404)

The session hasn’t been ingested yet: outcomes can only attach to sessions Belvedir has seen. Call flush() first so the spans arrive, then retry, or report later from a webhook or job. Semantics are in the outcomes reference.

Traces missing in development

Ensure your BELVEDIR_API_KEY environment variable is set and that initialize() is called before any LLM client is created. Check your terminal for SDK warnings on startup.