detail string, and an X-Request-ID response header you can use to trace the request server-side. Understanding these patterns lets you write error handling once and apply it everywhere.
Error body format
All error responses useapplication/json with the following shape:
500 Internal server error responses, the body also includes the request ID:
Every response — including successful ones — includes an
X-Request-ID header. Save this value when you catch an error; it’s the fastest way to get help from support.HTTP status codes
Common errors and how to fix them
401 — Missing Bearer token
You sent a request to a protected endpoint without anAuthorization header.
Fix: Add Authorization: Bearer <session_token> to your request. If you don’t have a session token yet, see Authentication.
401 — Token expired
Your session token has passed its 30-minute TTL. Fix: CallPOST /auth/session with a fresh Clerk JWT to get a new session token, then retry the original request.
409 — Identical research request already in progress
You submitted a research job for an idea that is already running for your account. Fix: Wait for the current job to finish (subscribe toGET /research/{job_id}/events), then start a new one if needed. Alternatively, use a different idea, or use an Idempotency-Key header on POST /research to safely replay the same request.
429 — Too many requests
You’ve exceeded the rate limit for an endpoint. Check theRetry-After response header for the number of seconds to wait before retrying.
Fix: Slow down your request rate and respect the Retry-After value.
500 — BRIDGE_INVARIANT_VIOLATED
POST /ideas returns this when the server could not link a project to the new card. Every card created through POST /ideas is guaranteed to have a non-null project_id, and this error is returned rather than shipping a card the client can’t navigate to via GET /projects/{id}.
The response body includes a structured detail object instead of a plain string:
POST /ideas request — the auto-bridge is idempotent per user on the semantic content of the idea, so a retry will not create duplicate projects. If it persists, capture the X-Request-ID header and contact support.
502 — Bad gateway
An external service your request depended on — GitHub, Composio, or another third-party integration — returned an error. Fix: This is typically transient. Wait a moment and retry the request. If it persists, check theX-Request-ID header and contact support.
503 — Service unavailable
A critical dependency is down. Common causes:- JWKS not loaded — the Clerk auth service isn’t reachable. All auth requests will fail until it recovers.
- Embedding service down — semantic search endpoints will return
503until the embedding provider is reachable again.
Streaming errors
For endpoints that return NDJSON streams (GET /research/{job_id}/events, GET /build-graphs/{graph_id}/events, etc.), errors are delivered as a JSON line in the stream rather than as an HTTP error status:
string
required
Human-readable description of the error.
string
required
Machine-readable error code for programmatic handling.
boolean
required
If
true, the operation is safe to retry — for example, a transient external service failure. If false, retrying without changing your request will produce the same error.error event in a stream, check retryable. If it’s true, re-connect to the stream (using the cursor query parameter to resume from where you left off) after a short backoff. If it’s false, surface the message to the user and investigate the root cause before retrying.
Common streaming error codes
The most frequentcode values you’ll encounter on streaming endpoints:
Research
error events for EMPTY_OUTPUT and MODEL_EMPTY_DESPITE_EVIDENCE include an evidence_count field on data reporting how many sources the pipeline gathered. Use this to distinguish bad input (evidence_count: 0) from model-side extraction failures (evidence_count > 0).