Skip to main content
PermitCore returns an RFC 9457 application/problem+json body for every non-2xx response:
Branch your error handling on type (a stable URI), not on title or detail (human-readable, may change). status mirrors the HTTP status; instance is the request path; request_id also appears as the x-request-id response header — include it in support requests.

Error catalog

The type URI ends in the slug shown below; each links to a page explaining the error and how to fix it.

401 Unauthorized

Auth is checked before the resource, so a bad key returns invalid-credentials even on an unknown path or jurisdiction.

400 / 422 Bad request

403 Forbidden

404 Not Found

429 Too Many Requests

The emitted quota slug follows the pattern {daily\|monthly}-{requests\|exports}-quota-exceeded. When Retry-After is large (multiple hours), the quota has been exhausted for the window. Bring the key up a tier or wait for it to reset. Reset is a trailing 30-day rolling window, not a calendar month — monthly quotas restore progressively as usage ages out (the reset_at field / X-RateLimit-Reset header marks the next freed slot). Daily quotas restore in full at the next UTC midnight. See Rate limits.

5xx Server errors

Retry 5xx on the HTTP status (below) with exponential backoff. The type slug is stable for these too.

Retry guidance

Retryable status codes: 429 (respect Retry-After), 500, 502, 503, 504. All 4xx codes other than 429 are application errors and should NOT be retried — fix the request and resubmit.
Node.js

Diagnosing in production

  • Every response includes a x-request-id header (UUID). Include it in any support ticket — we can trace per-request.
  • Vercel deploy logs surface [cohort-distribution] <slug>: <error_type> for any caching layer failures.
  • For programmatic monitoring, the future /v1/keys/{prefix}/usage endpoint includes a recent_requests array with per-request status.