Rate Limits
The Sharpe API enforces rate limits per API key to ensure fair usage and platform stability. Limits are applied as requests per minute and requests per month.
Current limits
Limits are enforced per key at one of four internal plan tiers. Every API key is currently issued on the Free tier — there are no paid plans today. Higher tiers are granted on request.
| Tier | Requests / min | Requests / month |
|---|---|---|
| Free | 30 | 10,000 |
| Analyst | 500 | 500,000 |
| Pro | 1,000 | 3,000,000 |
| Enterprise | 5,000 | 50,000,000 |
Need higher limits? Contact us — higher-tier keys are granted on request.
Rate limit and quota headers
Every authenticated v1 API response includes headers so you can track per-minute rate limits and monthly quota usage in real time:
- Name
X-RateLimit-Limit- Type
- integer
- Description
Maximum requests allowed per minute for your tier.
- Name
X-RateLimit-Remaining- Type
- integer
- Description
Requests remaining in the current one-minute window.
- Name
X-RateLimit-Reset- Type
- integer
- Description
Unix timestamp (seconds) when the current window resets.
- Name
X-Quota-Limit- Type
- integer
- Description
Monthly request quota for your tier.
- Name
X-Quota-Remaining- Type
- integer
- Description
Monthly requests remaining in the current billing period.
- Name
X-Quota-Reset- Type
- string
- Description
ISO 8601 timestamp when the monthly quota resets. Included when the quota store returns a reset timestamp.
- Name
X-Request-Id- Type
- string
- Description
Unique identifier for this request. Include when contacting support.
Example response headers
HTTP/2 200
x-ratelimit-limit: 30
x-ratelimit-remaining: 27
x-ratelimit-reset: 1743062460
x-quota-limit: 10000
x-quota-remaining: 9812
x-quota-reset: 2026-04-01T00:00:00.000Z
x-request-id: req_abc123def456
429 Too Many Requests
When you exceed the per-minute rate limit, the API returns a 429 status. If you exceed your monthly quota, it returns a 403 with type monthly_quota_exceeded.
The response body follows the standard RFC 9457 error format. The detail field tells you whether you hit the per-minute rate limit or the monthly quota.
Response properties
- Name
type- Type
- string
- Description
rate_limit_exceeded(429) for per-minute limits,monthly_quota_exceeded(403) for monthly caps.
- Name
detail- Type
- string
- Description
Human-readable explanation of which limit was exceeded.
- Name
doc_url- Type
- string
- Description
Link to relevant documentation page for the error.
429 response body
{
"type": "https://www.sharpe.ai/errors/rate_limit_exceeded",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "Rate limit of 500 requests per minute exceeded.",
"request_id": "req_abc123def456",
"doc_url": "https://www.sharpe.ai/docs/rate-limits",
"suggested_action": "Wait until the time in the X-RateLimit-Reset header before retrying. Upgrade your plan for higher limits."
}
429 response headers
HTTP/2 429
x-ratelimit-limit: 500
x-ratelimit-remaining: 0
x-ratelimit-reset: 1743062472
x-quota-limit: 500000
x-quota-remaining: 499811
x-quota-reset: 2026-04-01T00:00:00.000Z
retry-after: 12
x-request-id: req_abc123def456
Best practices
Monitor your usage
Read X-RateLimit-Remaining and X-Quota-Remaining on every authenticated v1 response. When either drops below 10% of its limit, slow down, queue requests, or move heavy jobs to the next reset window.
Implement backoff
When you receive a 429, use the Retry-After header when present, or fall back to X-RateLimit-Reset to calculate how long to wait before retrying.
Backoff example
async function fetchWithRetry(url: string, headers: HeadersInit) {
const res = await fetch(url, { headers })
if (res.status === 429) {
const retryAfter = parseInt(res.headers.get('Retry-After') ?? '0', 10)
const reset = parseInt(res.headers.get('X-RateLimit-Reset') ?? '0', 10)
const waitMs = retryAfter > 0
? retryAfter * 1000
: Math.max(reset * 1000 - Date.now(), 1000)
await new Promise((resolve) => setTimeout(resolve, waitMs))
return fetch(url, { headers })
}
return res
}
Cache responses
Many Sharpe API endpoints return data that updates on a known schedule (for example, funding-rate snapshots refresh live to every few minutes, while heatmaps refresh about every 5 minutes). Cache responses locally and respect Cache-Control headers to avoid redundant requests.
Use bulk endpoints
Prefer endpoints that return data for multiple symbols in a single request rather than making one request per symbol. For example, /v1/funding/rates?type=current without a coin parameter returns all rates at once.