Error handling
Decide what to retry, what to fix, and when to send a user back to the dashboard after a CoreSpeed failure.
This page is about the operational decision. The status codes, error codes, and envelopes themselves are listed once, in Errors & status codes.
Read both layers
A CoreSpeed call can fail at two levels, and only one of them shows up in the HTTP status:
- Transport and identity — HTTP
4xx/5xx. The tool never ran. Identity, billing, and catch-all failures use the nestederrorenvelope; connector routes answer with a flat one ({"error": "admin_required"}). A handler that assumeserroris always an object will miss the flat codes — both shapes are listed in Errors & status codes. - Tool execution — HTTP
200withresult.isError: true. The request was authorized, then the tool refused or failed.
Treating a 200 as success is the most common integration bug against this
surface. Branch on isError before interpreting a result.
Who fixes what
| Failure | Owner | Move |
|---|---|---|
401 on every call | The client | Fix the header form, or replace a revoked key. |
402 payment_required | An org admin | Top up. Discovery and account reads keep working meanwhile. |
402 key_spend_limit_exceeded | An org admin | Raise the key's cap, or wait for the monthly reset. |
403 org_suspended | Support | No client-side or billing fix exists. |
404 endpoint_not_found | The client | A retired per-connector or per-engine URL was called. Use POST /mcp. |
needs_reauth on an account | The end user | Reauthorize in the dashboard. |
Tool absent from tools/list | An org admin or the end user | The capability is disabled, or the account is not connected for this caller. |
Reauthorization is not a key problem
needs_reauth means the upstream OAuth grant can no longer be used. The
connector stays known and its tools stay visible — calls just fail until the
account is reauthorized.
Send the user to Dashboard → Connectors. Do not rotate the CoreSpeed key and do not rewrite client configuration: neither one is broken.
Retry rules
401,402,403,404— do not retry. Nothing changes without an action by the client, an admin, or support.500— retry with backoff, and keep the request id for support.- Tool-level
isError— retry only when the message names a transient upstream condition. A hold, a spend cap, orjwt_session_requiredwill not clear on retry.
Spend caps are boundaries, not reservations
A cap is checked at the request boundary. An action already in flight can finish above the remaining amount before its final cost is recorded — so a cap bounds what starts, not what completes. See Usage & budgets.