Standard error responses
Every operation can fail with the same two body shapes below. Operation docs list which status codes apply and link here instead of repeating these schemas.
Generic error (RFC 7807 Problem Details)
{
"type": "string — machine-readable code, e.g. \"RESOURCE_NOT_FOUND\", \"DUPLICATE_RESOURCE\"",
"title": "string — short human-readable summary",
"status": "integer — HTTP status, repeated in the body",
"detail": "string — detailed explanation"
}
Validation error (422) — generic error plus field details
{
"type": "VALIDATION_ERROR",
"title": "Validation failed - One or more fields are invalid",
"status": 422,
"detail": "Validation failed for one or more fields",
"errors": [
{ "field": "string", "message": "string", "attemptedValue": "the rejected value" }
]
}
Status codes
| Status | Meaning |
|---|---|
| 400 | Malformed request / invalid syntax. |
| 400 | MCP_WRONG_GATEWAY — the operation exists but belongs to a different verb tool; the message names the right one — re-issue there. |
| 401 | The API key is invalid, expired, empty, or was revoked since this connection was authorized — reconnect with a current key. (A refusal that is about scope comes back as 403, not 401; see below.) |
| 403 | SCOPE_NOT_ALLOWED — the key is valid, but this operation is not available to its scope. Do not reconnect; it will not help. Call account/get to see the key's keyType, then work within that scope. PLAN_REQUIRED — the key is valid and the feature needs a higher plan; detail says which, and a hint follows. |
| 404 | Resource missing or not accessible to your org. Delete responses may read "not found or delete failed". |
| 406 | Missing X-API-Key header. |
| 409 | Duplicate resource / constraint violation (e.g. tag title already exists for that type). |
| 415 | Content-Type must be application/json. |
| 422 | Field validation failed (shape above). Upstream messages can contain .NET type names; known patterns are rewritten to plain English with the original kept in raw_message. |
| 429 | Rate limit exceeded — 60 requests per 60-second window per API key, shared across every operation, never per endpoint. The body is RATE_LIMITED, carrying that rule as max/windowSeconds/scope and, when it is known, retryAfterSeconds. Wait, don't retry: a blocked request still spends the window, so retrying straight away extends the block — call-contract. |
| 500 | Upstream server error, surfaced compactly as {type: "UPSTREAM_ERROR", status, detail} (stack traces are never forwarded). |
Empty success: mutations (deletes, tag attach/detach, removals) succeed with 204 No Content;
such responses are surfaced as {ok: true, http_status, note} — success is explicit, no
verification read needed.