Browse documentation
Concept All API surfaces

Errors and request IDs

Distinguish JSON:API, GraphQL, token, and webhook failures; use stable codes, correlation IDs, and retryability without leaking credentials.

View as Markdown

Error shape depends on where a request failed. Keep the HTTP status, x-request-id, stable error code, and surface version together. Never attach a bearer token, client secret, trigger URL, or sensitive request body to a ticket.

JSON:API and API plug errors

Authentication, scope, rate-limit, idempotency, and JSON:API resource errors use an errors document. Plug-layer errors include a correlation ID in meta:

{
"errors": [
{
"code": "forbidden",
"status": "403",
"detail": "insufficient scope",
"meta": { "correlation_id": "req_example" }
}
]
}

The response header's x-request-id is the primary value to retain. Resource validation can include source pointers or field metadata; unexpected internal errors are intentionally generic.

GraphQL errors

A parsed GraphQL request can return HTTP 200 with both data and an errors array. Validation, an unknown model slug, a bad filter, query complexity, and depth limits are field/document errors rather than JSON:API errors:

{
"errors": [
{ "message": "Operation is too complex: complexity is 300 and maximum is 200" }
]
}

Transport failures before GraphQL execution, such as an invalid token or rate limit, use the API error envelope and their non-200 status. Check both the HTTP status and GraphQL errors before using data.

Token and webhook errors

Token exchange deliberately uses compact OAuth-style bodies such as {"error":"invalid_client"}. Webhook ingestion uses endpoint bodies such as {"error":"Unauthorized"} or {"error":"Processing temporarily unavailable"}. Use the endpoint reference for the exact status and retry guidance; do not parse human capitalization as a stable code.

Stable codes

unauthorized

HTTP 401. The bearer token is missing, invalid, expired, revoked, or no longer maps to a valid active account. Exchange once, retry once, then alert.

missing_credentials

HTTP 401 on webhook ingestion. The service-account bearer token is missing, invalid, or expired. Exchange once and retry once; repeated failure is a credential problem rather than a transient delivery failure.

forbidden

HTTP 403. Authentication succeeded but a scope, run-as policy, or object permission failed. Correct authorization; do not retry unchanged.

insufficient_scope

HTTP 403 on webhook ingestion. The selected service account lacks webhooks. Grant the exact scope or select the correct account.

invalid_client

HTTP 401 from token exchange. Client credentials are absent, invalid, inactive, revoked, or in the wrong rotation state. The response does not reveal which component failed.

unsupported_grant_type

HTTP 400. Send exactly grant_type: client_credentials.

not_found

HTTP 404. The route/resource is absent or not visible to the run-as member. Do not use it to infer cross-workspace existence.

invalid_request

HTTP 422. The JSON:API document failed stable resource validation. Correct the body before retrying.

idempotency_key_reused

HTTP 409. The same key identified a different method/path/body fingerprint. Reconcile the client operation; do not hide the conflict by generating a new key.

idempotency_key_in_progress

HTTP 409. Another request with the same key is still executing. Wait and retry the identical request with the same key.

rate_limited

HTTP 429. Pause the affected credential or trigger budget for the number of seconds in Retry-After.

payload_too_large

HTTP 413 on webhook ingestion. Reduce the actual body below the configured limit, 1 MiB by default. Changing only Content-Length cannot bypass the check.

processing_failed

HTTP 422 on webhook ingestion. Stable payload or workflow validation failed. Correct the delivery before retrying.

unsupported_trigger_authentication

HTTP 422 on webhook ingestion. The trigger has a legacy Basic or Bearer connector mode that conflicts with the mandatory service-account Authorization header. Reconfigure the connector to API key or HMAC before retrying.

temporarily_unavailable

HTTP 503 on webhook ingestion. A transient processing dependency failed. Wait for Retry-After, then retry with the same delivery key.

graphql_validation

GraphQL HTTP 200 error. Correct the query, variable type, model slug, filter, or enumerated value before retrying.

query_too_complex

GraphQL HTTP 200 error. Reduce selected fields, page size, nesting depth, or document size. Current defaults are complexity 200, depth 10, and 8,000 tokens.

Support checklist

Capture the request time, method, non-secret path template, status, stable code, x-request-id, x-api-version, retry count, and deployment release. Redact query values or bodies that contain tenant data. Then follow Idempotency and retries before repeating work.

Related documentation