Skip to content

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.

TierRequests / minRequests / month
Free3010,000
Analyst500500,000
Pro1,0003,000,000
Enterprise5,00050,000,000

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.

Was this page helpful?