Skip to main content

Traces not appearing in the dashboard

Symptom: You initialized the SDK and made LLM calls, but the dashboard shows no data after 15–30 seconds.
Before working through the checklist below, run zespan doctor — it checks your API key, API reachability, whether spans are actually arriving, and the most common wrapper-ordering mistake in one command, and tells you exactly which of these sections applies:
Verify the API key you passed to init() starts with zsp_ and matches the one shown in Settings → API Keys for your project. A typo or a key from a different project will cause all events to be silently dropped (the SDK logs a warning, but does not throw).Enable debug: true to see SDK activity:
The SDK batches events and flushes them every 2 seconds by default. If your script or Lambda handler exits before the flush fires, events are lost. Call flush() explicitly before the process ends:
See the Serverless guide for environment-specific patterns.
If you self-host Zespan, make sure you set baseURL to your API server’s address. The default is https://api.zespan.com.
The SDK sends events to https://api.zespan.com over HTTPS (port 443). If your environment blocks outbound traffic, allowlist this endpoint. Use debug: true to see if flush requests are failing with network errors.
zespan.init() must be called before any wrapped LLM client is created.

Cost showing $0.00 for all events

Symptom: Traces appear in the dashboard but the cost_usd column is always zero.
The SDK computes cost from a built-in pricing table keyed on the exact model string. If you use a model ID the SDK doesn’t recognise, cost_usd is set to 0 rather than throwing an error.Check your model strings against the supported models reference. Common mismatches:If you use a model not in the table, open an issue on GitHub — we add new models with each release.
If input_tokens or output_tokens are 0, cost will also be 0. This can happen if the provider response doesn’t include usage data — for example, streaming calls where you don’t consume the full stream before closing it.For streaming calls, make sure you iterate the full response before the function returns:

Parent-child spans not linking (broken trace tree)

Symptom: Multi-step agent workflows show as separate disconnected traces instead of a nested tree.
The SDK propagates trace context automatically through async calls. If you break the async chain — for example, by using setTimeout, setImmediate, or a non-async callback — context is lost.Always use await for async operations inside withZespanContext or withAgent:
If you call wrapped LLM clients outside a withZespanContext block, each call gets its own isolated trace context and cannot link to siblings.Wrap your entire request handler:
If you don’t await withAgent(...), the agent span may close before inner spans complete, breaking the parent-child link.

Events missing in serverless (Lambda / Vercel / Cloud Run)

See the complete Serverless deployment guide for environment-specific patterns. Quick fix: call flush() before your handler returns.

Verification email didn’t arrive

Check your spam folder, then click Resend verification email on the Check your email screen or on the sign-in page’s Your email isn’t verified yet prompt. You can resend once every 60 seconds. If you mistyped your address, click Use a different email. See Sign-up and onboarding.

401 Unauthorized from the ingest endpoint

Cause: One of the following:
  1. The API key was revoked or rotated and the old key is still in use
  2. The x-api-key header is missing from the request
  3. The key belongs to a different project
Go to Settings → API Keys, check that the key prefix matches the one your application is using, and rotate if necessary.

429 or 503 responses and retries

Ingest allows 300 requests per minute per project. A 429 or 503 response carries a Retry-After header, and both SDKs wait that long (up to 60 seconds) before retrying. While they retry, your events are kept in memory, not lost — see Delivery behaviour. Every error response also includes a requestId; quote it when you contact support. See API reference → Errors.

Rate limit 429 with “Monthly quota exceeded”

This is not a per-minute rate limit — it means your organization has exhausted its monthly event quota. Retrying later in the same month will not succeed. Options:
  • Upgrade your plan from Settings → Billing
  • Reduce your SDK sampleRate to send fewer events: zespan.init({ sampleRate: 0.5 })
  • Wait for your quota to reset at the start of next month

Prompt text not showing in trace detail

Cause: Prompt storage is on by default but may have been disabled. Verify storePrompts is not set to false in your init() call — PII redaction is applied to all stored text before transmission:
Review your data retention policy before enabling this. Once stored, prompt text is subject to your plan’s retention window.

Python SDK not capturing async OpenAI calls

zespan.patch_openai() patches both sync and async clients. If async calls are still not traced, verify:
  1. patch_openai() is called before any openai module is imported in your actual call path
  2. You are using openai.AsyncOpenAI() (not a pre-initialized client from before the patch)

Still stuck?

Enable debug: true in your SDK init and share the console output. Open an issue on GitHub or email support@zespan.com.