Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.authforge.cc/llms.txt

Use this file to discover all available pages before exploring further.

Developer API errors

All Developer API errors return a JSON object with an error code and a human-readable message:
{
  "error": "not_found",
  "message": "Resource not found"
}
HTTP StatusError CodeDescription
400bad_requestInvalid or missing request parameters. Check the request body and query parameters.
401invalid_api_keyMissing, malformed, or revoked API key. Verify your Authorization: Bearer header.
402no_creditsInsufficient credits to complete the operation. Purchase more credits in the dashboard.
403forbiddenThe target app or license doesn’t belong to your account.
404not_foundThe license key, webhook, or endpoint doesn’t exist.
429rate_limitedToo many requests. Back off and retry with exponential backoff. Burst limit: 100 req/s, sustained: 50 req/s.
500internal_errorUnexpected server error. Retry the request. If persistent, contact support.

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>"}:
{
  "status": "failed",
  "error": "invalid_key"
}
The HTTP status code matches the class of failure:
HTTP StatusError codes
400bad_request, malformed_request
401invalid_app, invalid_key, session_expired, replay_detected
403blocked, app_disabled, hwid_mismatch, revoke_requires_session
410expired, revoked
429rate_limited, no_credits, app_burn_cap_reached
500system_error
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:
{
  "status": "failed",
  "error": "rate_limited"
}
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)

Error CodeDescriptionUser-facing guidance
invalid_appThe App ID or App Secret is incorrect, or the app has been deactivated.This is a developer configuration error. Show “Authentication failed.”
app_disabledThe app owner’s account is suspended.Show “Authentication service temporarily unavailable.”
invalid_keyThe license key doesn’t exist or doesn’t belong to this app.Show “Invalid license key. Please check and try again.”
revokedThe license has been revoked.Show “This license has been deactivated. Contact support.”
expiredThe license has passed its expiration date.Show “Your license has expired.” with a renewal link if applicable.
hwid_mismatchAll HWID slots are full and the current device’s HWID doesn’t match any bound device.Show “This license is already in use on another device. Contact support to reset.”
no_creditsThe app developer’s account has insufficient credits.Show “Authentication service temporarily unavailable. Please try again later.” Never expose this to end users.
app_burn_cap_reachedThe app hit its configured hourly/daily credit burn cap.Show “Authentication service temporarily unavailable. Please try again later.”
blockedThe device’s HWID or IP is blacklisted, or not on a required whitelist.Show “Authentication failed. Contact support.”
rate_limitedToo many requests from this IP or license key. Back off and retry after 60 seconds.Retry with exponential backoff and jitter; wait at least 60 seconds before sustained retries.
replay_detectedThe nonce has already been used. Generate a fresh nonce for each request (SDKs do this automatically).This is a developer integration error if you are not using an official SDK.
bad_requestThe JSON body parsed successfully but failed schema validation (missing fields, invalid types). Includes a details array.This is a developer integration error.
malformed_requestThe request body is missing or is not valid JSON.This is a developer integration error.

Heartbeat errors (/auth/heartbeat)

Error CodeDescriptionUser-facing guidance
session_expiredThe session token is invalid or has expired. The SDK should re-authenticate.Prompt the user to re-enter their license key or restart the app to log in again.
revokedThe license has been revoked since the last heartbeat.Show “This license has been deactivated. Contact support.”
expiredThe license has expired since the last heartbeat.Show “Your license has expired.” with a renewal link if applicable.
app_disabledThe app owner’s account has been suspended.Show “Authentication service temporarily unavailable.”
no_creditsThe app developer’s account has insufficient credits. Returned on the billing milestone (every 10th successful heartbeat).Show “Authentication service temporarily unavailable. Please try again later.” Never expose this to end users.
app_burn_cap_reachedThe app hit its configured hourly/daily credit burn cap during heartbeat billing.Show “Authentication service temporarily unavailable. Please try again later.”
bad_requestThe JSON body parsed successfully but failed schema validation (missing fields, invalid types).This is a developer integration error.
malformed_requestThe request body is missing or is not valid JSON.This is a developer integration error.
system_errorAn unexpected failure occurred while processing the request (for example, credit deduction).Show “Authentication service temporarily unavailable.” Retry with backoff.
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)

Error CodeDescriptionUser-facing guidance
revoke_requires_sessionA pre-session self-ban request attempted revokeLicense: true. License revoke is only allowed for session-authenticated self-ban requests.This is a developer integration issue. Retry with revokeLicense: false, or call self-ban after login with sessionToken.
invalid_appappId or appSecret is invalid for pre-session self-ban.Treat as integration/configuration error.
invalid_keyThe provided pre-session licenseKey does not belong to the app.Treat as integration/configuration error.
session_expiredsessionToken is missing/invalid/expired for post-session self-ban.Re-authenticate before requesting self-ban.
replay_detectedPre-session nonce was reused.Always send a fresh nonce (official SDKs do this automatically).
rate_limitedToo many self-ban requests: 10/min per IP (all modes), 3/min per license key (pre-session requests with licenseKey only).Back off and retry with jittered exponential backoff.
expiredLicense is expired.Prompt renewal/support workflow.
revokedLicense was already revoked.Treat as already-locked state.
app_disabledApp or app owner is suspended/paused.Show generic service-unavailable messaging.
system_errorUnexpected server error.Retry with backoff; alert support if persistent.

SDK client-side errors

In addition to server errors, the SDK may detect issues locally before or after a server response:
ErrorDescription
nonce_mismatchThe nonce in the server response doesn’t match the one sent in the request. Possible replay attack.
signature_mismatchThe Ed25519 signature on the server response is invalid. Possible tampering.
HTTP/network errorsConnection timeout, DNS failure, or non-200 HTTP status. The SDK retries internally before failing.
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.