PAPI
API Reference

Errors

Error response format, error codes, and rate limiting

Error Handling

All API errors follow a consistent JSON format with an error code and human-readable message.

Error Response Format

{
  "error": {
    "code": "unauthorized",
    "message": "invalid API key"
  }
}

Error Codes

CodeHTTP StatusDescription
unauthorized401Missing, invalid, or expired authentication token
forbidden403Valid auth but insufficient scope or permissions
bad_request400Malformed request body or invalid parameters
not_found404Resource does not exist
rate_limited429Too many requests -- wait and retry
exchange_error502The upstream exchange returned an error
internal_error500Unexpected server error

Error Details

unauthorized (401)

{
  "error": {
    "code": "unauthorized",
    "message": "invalid API key"
  }
}

Causes:

  • Missing Authorization header
  • Malformed Bearer token
  • API key has been revoked
  • JWT token has expired

forbidden (403)

{
  "error": {
    "code": "forbidden",
    "message": "insufficient scope: trade required"
  }
}

Causes:

  • API key does not have the required scope (e.g., calling a trade endpoint with a read-only key)
  • No exchange credentials stored for the requested exchange
  • Attempting to access admin endpoints without admin role

bad_request (400)

{
  "error": {
    "code": "bad_request",
    "message": "missing required field: market_id"
  }
}

Causes:

  • Missing required fields in request body
  • Invalid field values or types
  • Malformed JSON body
  • Invalid query parameters

not_found (404)

{
  "error": {
    "code": "not_found",
    "message": "market not found"
  }
}

Causes:

  • Market, order, or resource does not exist
  • Invalid market ID or ticker

rate_limited (429)

{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Try again in 45 seconds."
  }
}

See Rate Limiting below.

exchange_error (502)

{
  "error": {
    "code": "exchange_error",
    "message": "Polymarket: Insufficient balance for order"
  }
}

This wraps errors from the upstream exchange. The message includes the exchange name and the original error. Common causes:

  • Insufficient balance
  • Market is closed or paused
  • Invalid order parameters for the exchange
  • Exchange API is temporarily unavailable
  • Invalid or expired exchange credentials

internal_error (500)

{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred"
  }
}

Internal errors are logged server-side. If you consistently see this error, contact support.


Rate Limiting

Each API key is limited to 60 requests per minute. Rate limit state is tracked per-server-instance (in-memory), not globally coordinated.

Rate Limit Headers

Every response includes rate limit headers:

HeaderDescription
X-RateLimit-LimitMaximum requests per window (60)
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets

Example response headers:

HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1710763260
Content-Type: application/json

When Rate Limited

When you exceed the limit, you receive a 429 response:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1710763260
Retry-After: 45
Content-Type: application/json
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Try again in 45 seconds."
  }
}

Handling Rate Limits

  1. Check X-RateLimit-Remaining before making burst requests
  2. When receiving a 429, wait until X-RateLimit-Reset before retrying
  3. Use the Retry-After header value for backoff duration
  4. Implement exponential backoff for automated retry logic

HTTP Status Code Summary

StatusMeaning
200Success
201Created (new resource)
400Bad request
401Unauthorized
403Forbidden
404Not found
429Rate limited
500Internal server error
502Exchange error (upstream)

On this page