Every plan gets the full endpoint catalog. Plans differ only in daily request volume - there is no per-endpoint gating anywhere in the API.Plans#
| Plan | Price | Requests per day |
|---|
| Free | $0 | 50 |
| Dev | 250/yr) | 5,000 |
| Pro | 49/mo billed annually) | 50,000 |
| Enterprise | Custom | Custom |
Upgrade, downgrade and billing live in the dashboard at app.sugra.ai. A plan change applies to your keys immediately.How the limit works#
The counter is per key, per UTC day. Every request to a data endpoint (/api/v1/..., /api/v2/...) counts as one, whatever the response size.
The counter resets at 00:00 UTC - not at your local midnight and not on a rolling 24-hour window.
An account can hold up to 5 keys and each key carries its own daily quota, so spreading traffic across keys raises the effective ceiling to up to 5x the plan limit. This is an intentional developer allowance, bounded at 5 keys.
System endpoints (/health, /about, /services, /sources) are public and do not count.
Every authenticated response reports the state of the counter:x-ratelimit-limit: 50
x-ratelimit-remaining: 37
x-ratelimit-reset: 2026-07-18T23:59:59Z
x-ratelimit-reset is the end of the current UTC day. Read x-ratelimit-remaining and back off before you hit zero; a client that only reacts to 429 wastes its last requests of the day on rejections.Over the limit: 429#
When the counter is exhausted, further requests return 429 Too Many Requests with a Retry-After header carrying the number of seconds until the UTC midnight reset. Honor it - retrying earlier only burns connections, the counter does not free up before the reset.Error catalog#
The API uses conventional HTTP status codes. JSON error bodies follow the FastAPI detail shape.| Status | Meaning | Body |
|---|
| 401 | Missing or invalid x-api-key | HTML help page - branch on the status code, not the body |
| 404 | Unknown path or no data for the requested entity | {"detail": "Not Found"} or an endpoint-specific detail string |
| 422 | Request validation failed (bad parameter value, malformed identifier) | {"detail": [...]} with the offending parameter named per entry |
| 429 | Daily quota exhausted | Detail string plus Retry-After seconds to the UTC midnight reset |
| 500 | Internal error on our side | {"error": "Internal server error"} |
| 502 | The upstream data source failed or returned an unusable payload | Endpoint-specific detail naming the failure class |
| 503 | A required dataset is still warming up after a deploy | Detail string; retry with backoff, warm-up completes in minutes |
401 covers both a missing and an unrecognized key; see Authentication for the semantics and an example.
404 on a valid path means the identifier resolved to nothing (an unknown ticker, an empty date range). The detail string distinguishes the cases where the endpoint documents them.
502 is retryable: sovereign and institutional upstreams have maintenance windows. Back off and retry; if a source degrades for longer, the status page reflects it.
503 responses are transient by design. Endpoints backed by large in-memory datasets (entity screening, some catalogs) return 503 with a clear detail while the dataset loads after a restart; they fail closed rather than serving partial answers.
Handling pattern#
For quota planning, x-ratelimit-remaining is authoritative and free to read - it rides on every successful response. Modified at 2026-07-18 19:05:31