Skip to main content

Error Catalog

Most non-rate-limit errors use the standard response:

{
"error": "string",
"code": "STRING_CODE",
"timestamp": "2025-01-12T10:30:00Z",
"details": { }
}

Common codes:

  • UNAUTHORIZED: Missing or invalid API key.
  • FORBIDDEN: Authenticated but insufficient permissions.
  • RATE_LIMIT_EXCEEDED: Standard application-level rate-limit error code where the standard envelope is used.
  • INVALID_NFT_FORMAT: Ensure NFT identifiers match the target blockchain format.
  • OWNERSHIP_VALIDATION_FAILED: On-chain ownership check failed during inventory or action validation.

Remediation tips accompany responses in details when available.

HTTP 429 Responses

HTTP 429 responses do not all use the standard error envelope. Select the retry strategy from the response fields and headers described below.

Coordinated request limit

The global, critical-operation, and route-specific coordinated limiters share this body:

{
"error": "Rate limit exceeded",
"message": "API rate limit exceeded. Please try again later.",
"retryAfter": 37,
"limit": 1000,
"remaining": 0,
"resetTime": "2026-08-07T01:15:00.000Z"
}

retryAfter is seconds. The Retry-After header uses the same unit and reset window, but the two values are calculated independently and can differ at a second boundary. Prefer Retry-After when the header is present. Coordinated responses also include:

Retry-After: 37
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1786065300
X-RateLimit-Used: 1001

X-RateLimit-Reset is Unix epoch seconds. The other X-RateLimit-* values are integer request counts.

Signup daily quota

Public signup also enforces a daily IP/email quota. That quota returns this body without Retry-After or X-RateLimit-* headers:

{
"success": false,
"error": "Signup rate limit exceeded. Please try later."
}

Do not retry this variant in a tight loop because the response does not expose its reset time.

Broadcast concurrency backpressure

Wallet-broadcast reporting can reject excess concurrent work independently of the coordinated request limit:

{
"success": false,
"error": "Too many concurrent broadcast requests. Please retry in a moment.",
"retryAfterMs": 2000
}

retryAfterMs is milliseconds. This backpressure variant does not set Retry-After or X-RateLimit-* headers. Wait for the body-provided duration before retrying.

Shared Rate-Limit Enforcement Unavailable (HTTP 503)

Critical mutations and provider-backed reads fail closed if shared rate-limit enforcement is unavailable. This is a service-availability response, not an HTTP 429 quota or backpressure response:

{
"error": "Service 'request protection' is temporarily unavailable",
"code": "SERVICE_UNAVAILABLE",
"details": {
"service": "request protection"
},
"timestamp": "2026-08-07T01:15:00.000Z"
}

The shared-enforcement failure also includes:

Retry-After: 30

The header value is seconds. Treat this 503 as a temporary service failure, not as evidence that the caller exhausted a request quota.