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
| Code | HTTP Status | Description |
|---|---|---|
unauthorized | 401 | Missing, invalid, or expired authentication token |
forbidden | 403 | Valid auth but insufficient scope or permissions |
bad_request | 400 | Malformed request body or invalid parameters |
not_found | 404 | Resource does not exist |
rate_limited | 429 | Too many requests -- wait and retry |
exchange_error | 502 | The upstream exchange returned an error |
internal_error | 500 | Unexpected server error |
Error Details
unauthorized (401)
{
"error": {
"code": "unauthorized",
"message": "invalid API key"
}
}Causes:
- Missing
Authorizationheader - 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
tradeendpoint with aread-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:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window (60) |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix 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/jsonWhen 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
- Check
X-RateLimit-Remainingbefore making burst requests - When receiving a 429, wait until
X-RateLimit-Resetbefore retrying - Use the
Retry-Afterheader value for backoff duration - Implement exponential backoff for automated retry logic
HTTP Status Code Summary
| Status | Meaning |
|---|---|
200 | Success |
201 | Created (new resource) |
400 | Bad request |
401 | Unauthorized |
403 | Forbidden |
404 | Not found |
429 | Rate limited |
500 | Internal server error |
502 | Exchange error (upstream) |