Errors
The Sharpe API uses RFC 9457 Problem Details for error responses. Every error is a flat JSON object with a machine-readable type URI, a human-readable title, the HTTP status code, a detailed message, and the request ID for debugging.
Error format
Every error response is a flat RFC 9457 Problem Details object at the top level. There is no ok field or nested error wrapper.
Properties
- Name
type- Type
- string
- Description
A URI reference that identifies the error type (e.g.,
https://www.sharpe.ai/errors/invalid_parameter). Use this for programmatic error handling.
- Name
title- Type
- string
- Description
A short, human-readable summary of the error.
- Name
status- Type
- integer
- Description
The HTTP status code.
- Name
detail- Type
- string
- Description
A human-readable explanation of what went wrong and how to fix it.
- Name
request_id- Type
- string
- Description
Unique request identifier (e.g.,
req_abc123def456ghij). Include this when contacting support.
- Name
doc_url- Type
- string
- Description
Link to the relevant documentation page for troubleshooting this error.
- Name
suggested_action- Type
- string
- Description
Actionable guidance on how to resolve this error.
{
"type": "https://www.sharpe.ai/errors/invalid_parameter",
"title": "Invalid Parameter",
"status": 400,
"detail": "Invalid parameter \"type\": Invalid enum value. Expected 'current' | 'accumulated' | 'history'",
"request_id": "req_abc123def456ghij",
"doc_url": "https://www.sharpe.ai/docs/errors#error-codes",
"suggested_action": "Check the parameter value against the endpoint documentation."
}
Error codes
Here is the complete list of error types returned by the Sharpe API. Use the type URI for programmatic branching and the status code for broad categorization.
- Name
invalid_api_key- Type
- 401
- Description
The provided API key is malformed or has been revoked. Double-check your
Authorization: BearerorX-API-Keyheader.
- Name
expired_api_key- Type
- 401
- Description
The API key has expired. Generate a new key from the Sharpe dashboard.
- Name
insufficient_scope- Type
- 403
- Description
Your API key does not have the required scope to access this resource. Check the scopes assigned to your key.
- Name
monthly_quota_exceeded- Type
- 403
- Description
You have exhausted your monthly request quota. Upgrade your plan or wait for the next billing cycle.
- Name
invalid_parameter- Type
- 400
- Description
A query parameter has an invalid value. Check the
detailfield for specifics.
- Name
missing_parameter- Type
- 400
- Description
A required query parameter is missing from the request.
- Name
rate_limit_exceeded- Type
- 429
- Description
You have exceeded your per-minute rate limit. Wait until the time indicated by the
X-RateLimit-Resetheader.
- Name
resource_not_found- Type
- 404
- Description
The requested endpoint or resource does not exist. Verify the URL path.
- Name
internal_error- Type
- 500
- Description
An unexpected error occurred on our side. These are automatically reported to our team.
- Name
upstream_error- Type
- 502
- Description
A dependency (database, exchange API) failed to respond. Retry with exponential backoff.
- Name
service_unavailable- Type
- 503
- Description
The API is temporarily unavailable due to maintenance or a data freshness issue. Retry with exponential backoff.
Retry guidance
Not all errors are retryable. Here is how to handle each category:
4xx client errors — do not retry
These indicate a problem with your request. Fix the issue before retrying.
- 400 — Fix the invalid or missing parameter
- 401 — Check your API key is valid and not expired
- 403 — Verify your plan includes access to this endpoint, or check your monthly quota
- 404 — Verify the URL
429 rate limit — retry with X-RateLimit-Reset
When you hit a rate limit, use the X-RateLimit-Reset header to calculate when the current window expires.
HTTP/2 429
x-ratelimit-limit: 500
x-ratelimit-remaining: 0
x-ratelimit-reset: 1743062472
x-request-id: req_abc123def456
Wait until the Unix timestamp in X-RateLimit-Reset before sending the next request.
5xx server errors — exponential backoff
For 500, 502, and 503 errors, retry with exponential backoff:
- Wait 1 second, then retry
- Wait 2 seconds, then retry
- Wait 4 seconds, then retry
- Continue doubling up to a maximum of 30 seconds
- After 5 retries, stop and alert your monitoring system
Always include the X-Request-Id from the failed response when contacting support.
This lets us trace the exact request through our infrastructure.
Troubleshooting
"My key works in cURL but fails in my app"
The most common cause is the Authorization header being stripped or malformed. Check that:
- The header is exactly
Authorization: Bearer sk_live_...with a single space afterBearer - Your HTTP client is not URL-encoding the header value
- No proxy or CDN between your app and
www.sharpe.aiis stripping theAuthorizationheader — if so, useX-API-Keyinstead
"I get 403 but my plan should include this endpoint"
A 403 can mean two things — check the type field in the error response:
insufficient_scope— Your key was created with restricted scopes. Generate a new key with the required scope, or contact support to update scopes on the existing key.monthly_quota_exceeded— You have hit your plan's monthly request limit. Check your usage atGET /v1/usageand either wait for the monthly reset or upgrade your plan.
"I keep hitting 429 even at low volume"
Rate limits are per-minute fixed windows. If you send 30 requests in 2 seconds (within a single 60-second window), you will exhaust a Free tier limit instantly. Spread requests evenly across the minute or implement the backoff pattern from the rate limits guide.
"I get 502 or 503 intermittently"
These mean an upstream dependency (database or exchange API) is temporarily unavailable. Retry with exponential backoff. If the error persists for more than 5 minutes, check status.sharpe.ai or contact support with the X-Request-Id.
"Response data is empty or stale"
Some endpoints depend on cron jobs that populate data on a schedule (e.g., funding rates every 5 minutes, heatmap every 5 minutes, narratives every 30 minutes). If you query immediately after a new endpoint is deployed, data may not yet be populated. The updated_at or meta.timestamp fields indicate data freshness.