Rate Limits
All API requests are rate-limited based on your subscription tier. Limits are applied per API key.
Usage is tracked against two public meters:
- Chart requests: every call to a Chart API endpoint (chart, composite, astrology, transits, returns, retrogrades, multi-chart). Most calls count as 1 chart request; transit ranges and multi-chart batches count more (see below).
- SAGE responses: every answered SAGE query. One query is one SAGE response (0 on a cache hit).
The two meters are independent. A chart request never draws down your SAGE responses and vice versa.
Tier limits
Every key includes the Free floor and adds whatever paid tier you subscribe to on top.
| Tier | Chart requests / mo | SAGE responses / mo | Rate limit | MCP scope | Cap behaviour |
|---|---|---|---|---|---|
| Free | 100 | 25 | 10 RPM | None | Hard cap |
| Chart | 20,000 | -- | 60 RPM | None | Hard cap |
| SAGE | -- | 3,000 | 100 RPM | SAGE tools | Hard cap |
| Advanced | 40,000 | 4,000 | 120 RPM | Chart + SAGE tools | Soft cap |
| Pro | 100,000 | 10,000 | 300 RPM | Chart + SAGE tools | Soft cap |
| Enterprise | Unlimited | Unlimited | Custom | Custom | Soft cap |
Chart is $22/mo or $199/yr. SAGE is $29/mo or $299/yr. Advanced is $44/mo or $399/yr. Pro is $100/mo or $899/yr. Enterprise is by contact. SAGE queries run at roughly 100 RPM regardless of tier.
Free is a floor every key gets
Free is not a separate signup. Every key already includes at least 100 chart requests and 25 SAGE responses per month, even with no paid subscription. A paid tier adds its allowance on top of that floor.
Tiers stack
Subscribe again and the allowances add. You can hold up to 3 active subscriptions per product, and their chart-request and SAGE-response allowances sum. A second Chart subscription gives you 40,000 chart requests, not a replacement.
What counts toward each meter
Most endpoints count 1 chart request per call. Transit ranges and SAGE queries count differently:
| Endpoint type | Meter | Count |
|---|---|---|
Chart endpoints (/api/chart, /api/composite, /api/astrology) | Chart requests | 1 per call |
Multi-chart batch (/api/multi-chart) | Chart requests | 1 per successful chart |
Planetary returns (/api/returns) | Chart requests | 1 per request |
| Transit endpoints (daily granularity) | Chart requests | 1 per day in range |
| Transit endpoints (hourly granularity) | Chart requests | 24 per day in range |
| Transit endpoints (minute granularity) | Chart requests | 1,440 per day in range |
Transit periods (/api/transits/periods) | Chart requests | 1 per request |
Retrograde periods (/api/retrogrades) | Chart requests | 1 per request |
SAGE query (/api/sage) | SAGE responses | 1 per answer (0 on cache hit) |
MCP tool calls (/mcp) | Same as the wrapped REST endpoint | -- |
Failed requests (4xx/5xx responses) are not counted against either meter.
Rate limit and quota headers
Every API response includes the rate limit and quota headers below:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per minute for this key |
X-RateLimit-Remaining | Requests remaining in the current 60-second window |
X-Quota-Meter | Which meter this response counted against: chart or sage |
X-Quota-Limit | Monthly allowance for that meter |
X-Quota-Used | Amount of that meter consumed this billing period |
X-Quota-Remaining | Amount of that meter remaining this billing period |
The X-Quota-* headers describe the meter named in X-Quota-Meter. A chart endpoint reports chart; a SAGE query reports sage. Read them to track your remaining allowance without a separate usage call.
Exceeding limits
When you exceed the per-minute rate limit, you'll receive a 429 Too Many Requests response:
{
"success": false,
"error": "Rate limit exceeded",
"message": "Your plan allows 120 requests per minute. Please slow down.",
"retryAfter": 60
}
When your monthly allowance for a meter is exhausted, the API returns a 429 naming the meter that ran out:
{
"success": false,
"error": "Monthly Chart request limit reached",
"meter": "chart",
"limit": 20000,
"used": 20000,
"upgrade_url": "https://dev.totalhumandesign.com/dashboard/billing"
}
SAGE returns the same shape with "meter": "sage". Subscribe to a higher tier or wait for the next billing period to reset.
