Rate limits and quotas¶
Three independent guards protect the API. Each answers HTTP 429 with its
own code, so a client can react to the right one.
| Guard | Scope | Applies to | Code |
|---|---|---|---|
| Burst rate limit | per API key | every request | rate_limited |
| Daily / monthly quota | per account | every data request (not account routes) | too_many_requests (details.reason: daily_quota_exceeded, monthly_quota_exceeded) |
| LLM spend cap | per account | LLM-backed endpoints on paid plans | llm_budget_exceeded (hourly), llm_budget_exhausted (monthly) |
Limits per plan¶
| Free | Hobby — $9 / month or $90 / year | Pro — $49 / month or $490 / year | |
|---|---|---|---|
| Burst | 60 requests | 300 requests | 1 500 requests |
| Sustained rate | 2 requests / second | 10 requests / second | 50 requests / second |
| Daily quota | 1 000 requests; 100 from 17 Nov 2026 | 1 000 requests | 10 000 requests |
| Monthly quota | 10 000 requests; 3 000 from 17 Nov 2026 | 30 000 requests | 300 000 requests |
| Active API keys | 1 | 5 | unlimited |
| LLM features | not included (403 plan_feature_unavailable) |
included: $5 a month, $1 an hour | included: $40 a month, $10 an hour |
| Commercial use | allowed | allowed | allowed |
| Uptime commitment (SLA) | none | none | none |
Prices, checkout and pay-as-you-go packs: see Pricing. The Free plan's quotas change on 17 November 2026 at 00:00 UTC — see the announcement.
The Free plan may be used in commercial products within these limits — see the
Terms of Service. The plan catalog is also served live at
GET /v1/plans.
The quota counts every request made with your API key to a data endpoint. Account
routes — /v1/auth/*, /v1/tenant/*, /v1/api-keys*, /v1/plans and /v1/billing/* —
never count, so you can always check usage, manage keys and buy a plan.
Pay as you go. If you bought request packs, a request past your daily or monthly quota
goes through and uses one credit instead of answering 429; the X-Credits-Remaining header
says how many are left. Credits never pay for LLM features.
Burst rate limit¶
A token bucket per API key: the bucket holds the plan's burst and refills at the sustained rate. When it is empty:
{
"error": {
"code": "rate_limited",
"message_key": "errors.common.rate_limited",
"message": "Too many requests. Retry shortly."
}
}
A Retry-After header says how many seconds to wait. Retrying inside that window
does not refill the bucket faster.
Daily and monthly quota¶
When an account has used its daily or monthly requests and has no pay-as-you-go credits left:
{
"error": {
"code": "too_many_requests",
"message": "Request quota exhausted for this billing window.",
"details": {
"reason": "daily_quota_exceeded",
"window": "day",
"limit": 1000,
"used": 1001
}
}
}
Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset
headers tell you when the window resets. Watch your usage with
GET /v1/tenant/usage.
LLM endpoints and the spend cap¶
These endpoints write text with a large language model and are available on paid
plans only. On the Free plan they answer 403 plan_feature_unavailable before any
model is called — see Paid (LLM) endpoints.
| Endpoint | LLM |
|---|---|
POST /v1/llm/theme/{theme}, /chart-reading, /dasha-forecast, /muhurta-reasoning and their /stream versions |
always (a cached copy may be returned) |
POST /v1/interpretations/natal, /relationship, /forecast |
always (a cached copy may be returned) |
POST /v1/interpretations with use_llm_rewrite: true |
only with that flag |
GET /v1/geolocation/places |
on paid plans the model helps read free-text place names; on Free the search uses the place database only |
On paid plans, spend is tracked per account over a rolling hour. When the plan's hourly cap is spent:
{
"error": {
"code": "llm_budget_exceeded",
"message_key": "errors.llm.budget_exceeded",
"message": "LLM cost budget exceeded for tenant.",
"details": { "tenant_id": "tenant-a", "cap_usd": 5.0, "spent_usd": 5.12 }
}
}
The check happens before the model is called. If the model provider itself is
down, LLM endpoints answer 503 with the provider error code (for example
llm_all_providers_failed) — safe to retry later.
Recommended client behaviour¶
- Single requests — on
429waitRetry-After, retry once. - Batches — keep a local limiter at or below your sustained rate.
- Background sync — exponential backoff with jitter, capped at 60 s.
Monthly LLM budget¶
Hobby and Pro include LLM features up to a monthly budget ($5 and $40), counted per calendar month in UTC. Once it is spent, LLM-backed endpoints answer until the 1st of the next month:
{
"error": {
"code": "llm_budget_exhausted",
"message": "Your plan's LLM budget for this month is used up. ...",
"details": {"budget_usd": 5.0, "spent_usd": 5.0123, "resets_at": "2026-11-01T00:00:00+00:00"}
}
}
with a Retry-After header. Every other endpoint keeps working.