Skip to content

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.

  • Single requests — on 429 wait Retry-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.