MCP

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.