Skip to main content
Every error the ManticScore API returns follows the same structure: an HTTP status code that tells you the class of problem, a JSON body with a human-readable 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 use application/json with the following shape:
For 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 an Authorization 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: Call POST /auth/session with a fresh Clerk JWT to get a new session token, then retry the original request.
Refresh proactively — call POST /auth/session a few minutes before the token expires rather than waiting for a 401. Store the expires_in value and set a timer.

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 to GET /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 the Retry-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:
Fix: This is typically transient. Retry the same 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 the X-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 503 until the embedding provider is reachable again.
Fix: Retry after a few seconds. These states are typically self-resolving.

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.
When you receive an 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.
A streaming error event is followed by a done event. The HTTP connection itself closes cleanly — you won’t receive a non-200 status code for in-stream errors.

Common streaming error codes

The most frequent code 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).
When retryable is false, the operation will not succeed by replaying the same input. Surface the message to the user and have them adjust their input before re-submitting.