Proofademic API

Error Handling

HTTP status codes, error response format, and common error examples.

Error Response Format

All API errors return a JSON object with an error field (string). Some errors include a code field for programmatic handling and a details object with additional context.

{
  "error": "Human-readable error message",
  "code": "machine_readable_code",
  "details": { ... }
}
FieldTypePresentDescription
errorstringAlwaysHuman-readable error description
codestringSometimesMachine-readable error code for programmatic handling
detailsobjectSometimesAdditional context about the error

HTTP Status Codes

Status CodeMeaningDescription
200OKRequest successful
202AcceptedAsync job accepted for processing
400Bad RequestInvalid request parameters or payload
401UnauthorizedMissing or invalid API key
403ForbiddenAPI key lacks required scope, or insufficient credits
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error
503Service UnavailableAI detection service temporarily unavailable

Common Errors

Missing API Key

Status: 401

{
  "error": "API key is required. Please provide it in X-API-Key header."
}

Invalid API Key

Status: 401

{
  "error": "Invalid API key."
}

Expired or Inactive API Key

Status: 401

{
  "error": "API key is invalid, inactive, or expired."
}

Missing Required Scope

Status: 403

{
  "detail": "API key does not have required scope: AI Detector"
}

API Key Limit Reached

Status: 403

{
  "error": "API key limit reached",
  "code": "key_limit_reached",
  "details": {
    "active_keys": 5,
    "max_keys": 5,
    "plan": "1M"
  }
}

Invalid Request Payload

Status: 400

{
  "error": "Invalid payload",
  "code": "invalid_payload",
  "details": {
    "content": ["This field is required."]
  }
}

Insufficient Credits

Status: 403

{
  "error": "Insufficient credits",
  "code": "insufficient_credits",
  "details": {
    "credits": 50,
    "required": 120
  }
}

Credits Exhausted (Paid Plan)

Status: 403

{
  "error": "Credits exhausted. Credits reset on next billing cycle.",
  "code": "credits_exhausted",
  "details": {
    "plan": "1M",
    "credits": 0
  }
}

Trial Expired

Status: 403

{
  "error": "Trial expired, please subscribe",
  "code": "trial_expired"
}

Rate Limit Exceeded

Status: 429

The response includes a Retry-After header indicating how many seconds to wait.

Too Many Pending Jobs

Status: 429

{
  "error": "Too many pending jobs. Wait for existing jobs to complete.",
  "code": "too_many_pending_jobs",
  "details": {
    "pending": 5,
    "limit": 5
  }
}

Service Unavailable

Status: 503

{
  "error": "No active detector services configured"
}

Rate Limits

Rate limits are applied at multiple levels:

ScopeDefault Limit
Per IP (burst)60 requests / minute
Per IP (sustained)3,000 requests / hour
Per user (global)60 requests / minute
Detector (sync)10 requests / minute
API key creation10 requests / minute

Rate limits may vary by plan. Higher-tier plans may have higher limits.

Async requests are not subject to the per-minute rate limit — they are constrained by credits and the pending jobs limit (varies by plan, see Async Jobs).

Best Practices

  • Always check the HTTP status code before parsing the response body.
  • Use the code field (when present) for programmatic error handling instead of parsing the error string.
  • Implement retry logic with exponential backoff for 429 and 5xx errors.
  • Do not retry 400, 401, or 403 errors — these indicate a problem with the request that must be fixed.
  • Log error responses for debugging.

On this page