API conventions

Build predictable clients around lists, failures, and throttling.

Cursor pagination

List operations accept a limit from 1 to 100. When another page exists, the response includes an opaque cursor:

{
  "data": [],
  "meta": {
    "nextCursor": "opaque-value"
  }
}

Pass that value back as cursor without decoding or changing it. A cursor is tied to its query context; do not reuse it with different filters or resources.

SituationClient behavior
nextCursor is presentRequest the next page with the same filters
nextCursor is absentStop; the list is complete
Cursor is invalid or expiredRestart from the first page

Error envelope

Errors use a stable machine-readable code and a safe message:

{
  "error": {
    "code": "forbidden",
    "message": "You do not have access to this resource."
  }
}

Branch on error.code, not the prose message. Keep the response X-Request-ID when you need support.

StatusTypical meaningRetry?
400Invalid input or cursorFix the request
401Missing or invalid credentialRefresh or replace the credential
403Scope or current access is insufficientChange access, not retries
404Resource is unavailable to this actorDo not probe for ownership
409Idempotency conflict or request still in progressFollow the returned error code
429Rate limit reachedWait for Retry-After
5xxTemporary server failureRetry safe operations with backoff

Rate limits

Read RateLimit, RateLimit-Policy, and Retry-After from the response. Use bounded exponential backoff with jitter, and cap both retry count and total elapsed time. Never retry a mutation unless its operation documents an idempotency contract.

On this page