Skip to main content

Developer API errors

All Developer API errors return a JSON object with an error code and a human-readable message:

Public auth errors (SDK)

The public auth endpoints (/auth/validate, /auth/heartbeat, and /auth/selfban) return errors as real HTTP status codes with a JSON body of the form {"status": "failed", "error": "<code>"}:
The HTTP status code matches the class of failure: Successful responses return 200 with status: "success". Public auth requests are protected by two layers of throttling:
  • API Gateway stage throttling: burst 200, sustained 100 req/s (default for every route on this API: /auth/validate, /auth/heartbeat, and /auth/selfban)
  • Application-level per-minute limits on /auth/validate only:
    • 30/min per IP
    • 5/min per license key
/auth/heartbeat is not IP rate-limited at the application layer. A flood of heartbeats only burns the victim’s credits, so a per-IP limit would add no security value and would interfere with legitimate high-frequency clients (e.g., 1 Hz server-side apps). Additional application limits on /auth/selfban: 10/min per IP (all self-ban requests), and 3/min per license key for pre-session requests that send licenseKey + app credentials. When a validate request exceeds either limit, the response is HTTP 429 with:
Successful /auth/validate responses include the X-RateLimit-Remaining header (the lower of the remaining IP and per-license validate quotas). /auth/heartbeat success responses do not include this header: application-level rate buckets apply only where documented above. The official SDKs parse both the HTTP status code and the JSON error field, so 429 responses surface as rate_limited automatically; no special handling is needed in your integration.

Validate errors (/auth/validate)

Heartbeat errors (/auth/heartbeat)

rate_limited and replay_detected are never returned from /auth/heartbeat. Heartbeats are not IP rate-limited and do not enforce nonce replay detection; replay protection is provided by the signed, short-lived session token.

Self-ban errors (/auth/selfban)


SDK client-side errors

In addition to server errors, the SDK may detect issues locally before or after a server response: These errors trigger the onFailure callback with the "login_failed" or "heartbeat_failed" reason.

Best practices for error handling

  1. Never expose internal error codes to end users. Map them to user-friendly messages.
  2. Log the actual error code for debugging, but show generic messages to users.
  3. Retry on transient errors (no_credits from your account, network errors) with exponential backoff.
  4. Don’t retry on permanent errors (invalid_key, revoked, hwid_mismatch); prompt the user to take action instead.
  5. Handle no_credits gracefully: this is a billing issue on your end, not the user’s problem.
See SDK Best Practices for detailed error handling guidance with code examples.