Menu
Platform
AI
App store purchases
Database
Flags
Jobs and cron
Localization
Monitoring
Notifications
Payments
Queues
Sandboxes
Webhooks
Getting Started
Authentication
KV Store
Deploy & Infrastructure
Reference
Errors
One problem body, a stable code, and the codes worth retrying.
A failed call on the one API's contract routes answers with one JSON body, sent
as application/problem+json. The shape follows RFC 9457, the Problem Details
standard, with the fields Sylphx adds to it. A few older routes, such as
whoami and the organization routes, still answer a plain JSON error body with
an error code; read the HTTP status first and the code or error field
second.
#The error body
| Field | Type | What it is |
|---|---|---|
type | string | A link that identifies the kind of problem. |
title | string | A short human summary of the problem. |
status | number | The HTTP status of the response. |
detail | string | What went wrong in this instance. |
instance | string | The request id, the same value as the `Sylphx-Request-Id` response header. |
code | string | The stable machine code, written in upper snake case. |
grpc_status | string | The same failure as a gRPC status. |
retryable | boolean | Whether retrying the same call can succeed. |
effect | string | Whether the call had any effect: `none`, `applied`, or `unknown` when the platform cannot tell. |
retry_after_ms | string | How long to wait before retrying, as a decimal number of milliseconds carried in a string. Present only when the wait is known. |
details | array | Field-level detail, as an array of objects. Present only when the problem is about specific fields. |
Branch on the code
Branch on code, never on status. The code is stable and names the
problem exactly; the status is a summary of it.
#The codes
This is the complete set.
UNKNOWN_FIELDINVALID_FIELDPAGE_TOKEN_MISMATCHIDEMPOTENCY_KEY_REUSED, HTTP 422IDEMPOTENCY_IN_PROGRESSETAG_MISMATCHRESOURCE_NOT_FOUNDRESOURCE_ALREADY_EXISTSUNAUTHENTICATEDPERMISSION_DENIEDDELETION_PROTECTEDRECONCILE_FAILEDPLAN_LIMIT_REACHED, HTTP 402SPEND_LIMIT_REACHED, HTTP 402RATE_LIMITED, HTTP 429INVALID_STATEINTERNAL, HTTP 500UNAVAILABLE, HTTP 503UNIMPLEMENTED, HTTP 501NOT_YET_PROPAGATED, HTTP 401DEADLINE_EXCEEDED, HTTP 504NOT_FOUND, HTTP 404CONTRACT_SKEW, HTTP 503NO_CAPACITY, HTTP 503SHAPE_NOT_OFFERED, HTTP 422STALE_GENERATION, HTTP 409RESOURCE_IN_USE, HTTP 409CONTROL_HELD, HTTP 409CONTROL_HELD_BY_HUMAN, HTTP 409
#Codes that change what you do
#RATE_LIMITED
You sent more requests in a second than your plan allows. The call is retryable,
and retry_after_ms says how long to wait. The rate limits of each plan are on
Plans, usage and limits.
#SPEND_LIMIT_REACHED and PLAN_LIMIT_REACHED
Both answer HTTP 402. PLAN_LIMIT_REACHED means the call would pass an
allowance of your plan; SPEND_LIMIT_REACHED means it would pass the monthly
spend cap of your organization. Neither is a fault: the call was refused before
it was billed. Make room under the plan or under the cap, then call again.
#NOT_YET_PROPAGATED
A brand-new key can take a moment to work. The call is retryable: retry it, and it succeeds once the key is in place.
#ETAG_MISMATCH and STALE_GENERATION
Both mean the state you aimed at has moved. ETAG_MISMATCH means the etag you
sent is not the resource's current one; STALE_GENERATION means the lease
generation or control epoch you named is no longer the current one. Read the
resource again, take the new meta, and reapply the change.
#IDEMPOTENCY_IN_PROGRESS
An earlier call carrying the same idempotency key has not finished yet. It is retryable: wait, then send the same call again rather than a new one.
#UNAVAILABLE
The service is temporarily unavailable. The call is retryable: back off and try again.
#Retrying
These codes are retryable: IDEMPOTENCY_IN_PROGRESS, ETAG_MISMATCH,
RATE_LIMITED, UNAVAILABLE, NOT_YET_PROPAGATED, DEADLINE_EXCEEDED and
CONTRACT_SKEW.
When retryable is true, retry with exponential backoff. When retry_after_ms
is present, wait at least the number of milliseconds it names before the next
attempt.
#In the client library
The TypeScript SDK throws SylphxError, which carries code, status,
retryable, effect, detail, requestId and the raw problem body. It
retries 429, 502, 503 and 504 on its own, honouring Retry-After.
curl -sS https://api.sylphx.com/v1/whoami \
-H "Authorization: Bearer $SYLPHX_API_KEY"
# HTTP 429
{
"title": "Too many requests",
"status": 429,
"detail": "Rate limit exceeded for this key.",
"instance": "9f2c1a7d4b6e0f31",
"code": "RATE_LIMITED",
"retryable": true,
"retry_after_ms": "1000"
}When you ask for support, quote the request id. It is the instance in the
body, and the same value the response carried in Sylphx-Request-Id.