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

CodeCaller action
invalid_api_keyCheck the environment value and bearer header format.
api_key_revokedStop and request a new key.
api_key_expiredStop and request a new key.
api_actor_inactiveStop and issue a key to an active user.
missing_scopeUse a key with the required scope.
missing_permissionUse an acting user with the required ShelfCycle permission.
rate_limitedWait for Retry-After. Retry POSTs with the same idempotency key.
validation_failedFix the field named in param.
not_foundRe-search and confirm the id. Cross-org records also return not_found.
idempotency_key_requiredSend a stable Idempotency-Key for POST requests.
idempotency_key_reusedRetry with the original body or choose a new key for a new source event.
duplicate_contactUse the existing contact or ask for confirmation.
stale_recordRefresh context and ask before retrying.
archived_recordDo not write to archived records.
unsupported_linked_recordRemove unsupported records. Orders cannot be note subjects or links in v1.
not_api_createdDo 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.