erroris a sentence that says what to change.codeis stable. Branch on it, not onerror. New codes may be added; none is renamed.requestIdmatches theX-Request-Idresponse header. Quote it to support. You can send your ownX-Request-Id.detailsappears on validation errors, one entry per field, with what is accepted (allowed,minimum,maximum,expected).
402 (and a 403 plan_required) also carries resolveUrl, the dashboard page where a person fixes it: resume the plan, buy credits or manage billing. GET /v1/billing lists all of these links.
Over MCP, an error comes back as a tool result with isError: true and this body as its text. A tool called without a required path argument (for example get_action with no actionId) answers invalid_request with “actionId is required” before any request is made.
Codes
Rate limits
Limits are per API key.
Every response with a key carries
X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (seconds until the bucket is full). Over the limit you get 429 rate_limited with Retry-After in seconds.
At most 4 of these slow reads run at once per key: GET /v1/analytics/overview, /v1/analytics/prompts, /v1/analytics/metrics, /v1/keywords and /v1/opportunities/{id}/brief. The fifth gets 429 too_many_concurrent with Retry-After: 2.
Across all keys, the API runs at most 2 of these slow reads at once. A slow read over that cap waits up to 5 seconds for a slot, then gets 429 too_many_concurrent with Retry-After: 5. Wait that long and retry; the cap protects every other request from slowing down.
Agent connect has no key, so it is limited per IP address: 10 new sessions per 10 minutes, and 120 polls per minute. Its 429 uses the same error body (rate_limited) and Retry-After.
Idempotency
SendIdempotency-Key: <any string, 1 to 255 characters> on a write you might retry. It is honoured on POST /v1/prompts, /v1/prompts/bulk, /v1/visibility-runs, /v1/plan-batches, /v1/opportunities/{id}/plan-requests, /v1/content, /v1/actions/{id}/executions, /v1/site-changes/{id}/pull-requests, /v1/research-requests, /v1/brand/competitors and /v1/webhooks.
- The same key with the same request within 24 hours returns the first response again, with
Idempotent-Replayed: trueand the usualX-Request-IdandX-RateLimit-*headers. - Only successful responses are kept, so a failed attempt can be retried with the same key.
- The same key with a different method, path or body answers
422 idempotency_key_reused. - The same key while the first request is still running answers
409 conflict. Retry shortly.
Support
Email jia@spreadjam.com or mal@spreadjam.com with therequestId.