API & MCP
Errors
One error shape for REST and MCP, with a stable code an agent can act on.
Every failure has the same shape — as the REST response body, and as the text of an MCP tool result with
isError: true:
{
"error": {
"code": "rate_limited",
"message": "rate limit reached (300/min)",
"request_id": "req_4f1c…",
"retry_after": 2
}
}code | HTTP | Meaning | What to do |
|---|---|---|---|
invalid_argument | 400 | An argument is missing, malformed or unknown (the message names it) | Fix the call |
unauthenticated | 401 | No, unknown, revoked or expired credential | Re-authenticate |
payment_required | 402 | No active plan, or a paid action while payment is failing | Update billing |
forbidden | 403 | The credential lacks the scope | Use a key / grant with that scope |
not_found | 404 | No such list, job or task in your organization | Check the id |
conflict | 409 | E.g. a list with that name already exists | Pick another name |
quota_exceeded | 429 | The 5-hour or weekly allowance, a list size or the list count is used up — details.window and details.resets_at say which and until when | Wait until resets_at (also retry_after), or upgrade |
rate_limited | 429 | Too many requests or concurrent calls | Wait retry_after seconds |
unavailable | 503 | A dependency is overloaded or down | Wait retry_after seconds |
timeout | 504 | The operation exceeded its deadline and was cancelled | Narrow the query or retry |
internal | 500 | Our bug | Retry; quote request_id to support |
retry_after is also sent as the Retry-After header on REST. Another organization’s list, job or task is
always not_found — the API never confirms that someone else’s id exists.