Skip to content
API / API errors
  1. Docs
  2. API
  3. API errors

API errors

Every error code of the Space Context API, its HTTP status and what to do: requests, scans, uploads, failed scans, terminal sign-in, x402 and the console.

Open .md

Errors share one envelope: { "error": { "code", "message", "request_id", … } }. Branch on code, never on message. Quote request_id when you contact support.

Requests

CodeStatusMeaning, and what to do
VALIDATION_ERROR400A parameter or field is missing or invalid; the message says which.
MISSING_AUTH_HEADER401No Authorization: Bearer … header.
INVALID_TOKEN401The key does not exist or was revoked.
USER_NOT_FOUND401The account of the key was deleted.
INSUFFICIENT_SCOPE403The key lacks a scope; required_scopes lists it.
PRO_REQUIRED403Spaces scanned with the app need Space Context Pro (only when the service turns this rule on; today every account reads its app spaces).
NOT_FOUND404No such space, scan or record for this key (test and live data are separate).
RATE_LIMIT_EXCEEDED429Wait retry_after seconds (also in Retry-After, except for the daily limits of search, questions and frame checks). daily_limit comes with the daily allowance of new spaces or scans; max_streams when the account already holds its open event streams (poll GET /scans/{id} instead). On a live POST /scans/{id}/start it also means five scans of the account already failed today because of their footage (refunded): live scans resume at midnight UTC; check frames first with POST /frames/check. See Limits.
INTERNAL_ERROR500Retry later; if it persists, contact support with the request id.

Spaces, search and questions

CodeStatusMeaning
ENRICHMENT_PENDING409A space scanned with the app is being screened; retry in a minute, or use a key with spaces:sensitive.
SEARCH_UNAVAILABLE503Search is temporarily unavailable.

When the deep pass of a space scanned with the app could not finish, the document stays at the base level with enrichment.status: "failed"; reading it again retries (a few times). STALE_ANALYSIS in that case means the space was recorded again in the meantime.

Scans and uploads

CodeStatusMeaning
INVALID_STATE409The scan is not in a state for this (for example uploading to a started scan, deleting a space with a scan in progress).
UPLOAD_INCOMPLETE409Start refused: frames missing, or the video missing or of another size than declared.
INVALID_CONTENT_TYPE400On create: the video’s content_type is not one the API reads (video/mp4, video/quicktime, video/x-m4v, video/3gpp, video/webm, video/x-matroska, video/matroska). Nothing is created or charged; convert the video to MP4 first (Scans).
INVALID_CONTENT_TYPE415On an upload: a frame (or POST /frames/check) that is not a JPEG, PNG or WebP image, or a video sent with a Content-Type other than the declared one.
FILE_TOO_LARGE413A frame over 2 MB, or a video over 95 MB sent through the API itself (max_bytes): a bigger video goes only to the direct upload link. A video whose Content-Length is not the declared size is 400 VALIDATION_ERROR.
EMPTY_FILE400The upload has no bytes.
SCANS_IN_PROGRESS429On start: ten scans of the account are already processing; start again when one finishes. On create: twenty scans are waiting for their upload (max_open_scans); upload and start them, or cancel some with DELETE /scans/{id}.
INSUFFICIENT_FUNDS402The balance does not cover the scan; balance_cents and price_cents say by how much.
SPENDING_CAP_REACHED402The key’s monthly cap is reached.
FRAME_CHECK_UNAVAILABLE503POST /frames/check cannot run right now; try again shortly.

A scan that fails after starting carries its reason in scan.error.code, and is refunded:

scan.error.codeMeaning
VIDEO_UNREADABLEThe video could not be decoded, or its length could not be read. A WebM recorded in a browser (MediaRecorder) states none: an API with its own ffmpeg (limits.max_video_bytes of GET /v1 above 100 MB) measures it; elsewhere remux it first (ffmpeg -i in.webm -c copy out.webm).
VIDEO_TOO_LONGOver 10 minutes.
FOOTAGE_UNUSABLEEvery frame was too dark, blurred or covered, or showed no place (a drawing, a screen). Refused before the analysis; film again in good light.
ANALYSIS_EMPTYNo space was recognised in the frames.
AI_ANALYSIS_FAILED, AI_OVERLOADEDThe analysis failed; scan again later.
PROCESSING_TIMEOUTProcessing took more than 2 hours.
UPLOAD_EXPIREDNot started within 24 hours (status cancelled, never charged).

Terminal sign-in (POST /auth/device/token)

CodeStatusMeaning
AUTHORIZATION_PENDING400Not decided yet in the console; poll again after interval seconds.
SLOW_DOWN400Polled faster than interval; wait longer.
DEVICE_CODE_EXPIRED400The code lived its ten minutes; start again.
DEVICE_CODE_INVALID400Unknown device code, or the key was already handed out.
ACCESS_DENIED403Denied in the console.

Agents that pay (POST /agent/credits)

CodeStatusMeaning
PAYMENT_REQUIRED402No payment yet: the options are in the PAYMENT-REQUIRED header (and in error.payment_required).
PAYMENT_INVALID400PAYMENT-SIGNATURE is malformed or does not match what was asked (amount, network, asset, recipient, fee payer, signature); reason says which.
PAYMENT_FAILED402The facilitator refused or could not settle the payment (for example not enough USDC); nothing was charged.
PAYMENT_FAILED502The settlement could not be confirmed: it may have gone through. Write to support with nonce (Base) or signature (Solana).
AGENT_KEY_REQUIRED403rotate_key, or the first key of the other mode, without one of the account’s current keys; nothing was charged.
PAYMENTS_UNAVAILABLE503The chosen network cannot be served right now; try later or pay on the other one.

Details and examples: Agents that pay (x402).

Evidence frames

CodeStatusMeaning
SIGNED_URL_INVALID401Not a valid evidence link.
SIGNED_URL_EXPIRED401The link expired; read the document again for a fresh one.
MEDIA_NOT_FOUND404The frame no longer exists.

Console

CodeStatusMeaning
INVALID_CREDENTIALS401Wrong or expired sign-in code.
SIGN_IN_UNAVAILABLE503That sign-in provider is not configured on this deployment.
PAYMENT_METHOD_REQUIRED402Creating or starting a live scan (POST /spaces/{id}/scans, POST /scans/{id}/start), checking a live frame (POST /frames/check) or creating a live key with scans:write (POST /keys, or approving a terminal sign-in) needs a card on file (or a top-up already paid): add one under Billing → Add a card (nothing is charged), or create a test key or a key without scans:write. Connecting an assistant with scanning allowed shows the same choice.
PAYMENTS_UNAVAILABLE503Card payments are temporarily unavailable.
PAYMENT_FAILED502Stripe could not create the payment page; try again.

Space Context docs · llms.txt · download Edit on GitHub

esc

↑↓ navigate↵ openesc close