Errors
Every error uses the same envelope with a stable code, a message, an optional param, and the request id.
Envelope
{
"error": {
"type": "validation_error",
"code": "validation_failed",
"message": "Request validation failed.",
"param": "email",
"requestId": "request-id"
}
}
Keep the requestId for debugging.
Common codes
| Code | Caller action |
|---|---|
invalid_api_key | Check the environment value and bearer header format. |
api_key_revoked | Stop and request a new key. |
api_key_expired | Stop and request a new key. |
api_actor_inactive | Stop and issue a key to an active user. |
missing_scope | Use a key with the required scope. |
missing_permission | Use an acting user with the required ShelfCycle permission. |
rate_limited | Wait for Retry-After. Retry POSTs with the same idempotency key. |
validation_failed | Fix the field named in param. |
not_found | Re-search and confirm the id. Cross-org records also return not_found. |
idempotency_key_required | Send a stable Idempotency-Key for POST requests. |
idempotency_key_reused | Retry with the original body or choose a new key for a new source event. |
duplicate_contact | Use the existing contact or ask for confirmation. |
stale_record | Refresh context and ask before retrying. |
archived_record | Do not write to archived records. |
unsupported_linked_record | Remove unsupported records. Orders cannot be note subjects or links in v1. |
not_api_created | Do not patch that note through v1. |
Rate limits
Default private v1 limits are 60 read requests per minute per key and endpoint, and 20 write requests per minute per key and endpoint.
On 429 rate_limited, read Retry-After and wait before retrying. Successful authenticated requests and rate-limited requests include X-RateLimit-Remaining when the rate-limit check runs.
Guardrail
Stop on stale_record, missing_scope, rate_limited, revoked or expired key errors, and unsupported record-type errors. Do not keep retrying without new information.
