Reference
Rate limits
Lumin meters one thing: successful tools/call requests against a monthly allowance, scoped per credential. There is no daily cap and no per-second throttle to tune around.
| Plan | Included | Scope |
|---|---|---|
| Free | 300 tool calls / month | Per credential |
| Pay as you go | Top up any amount, from 1 USD for 400 calls, never expires | Tops up the same meter |
| Custom limits | By arrangement | Per-key monthly override |
What counts
- Only
tools/callconsumes allowance. Protocol traffic,initialize,tools/list, notifications, is never counted or blocked. - Only successfully executed tool calls count. A failed call, whether validation, auth, or a server fault, is free, so retry loops and pre-flight checks cost nothing.
- One call is one call. No tool is weighted, and no tool is gated behind a plan: all 221 are on every plan.
- The 3 meta-tools are metered like any other.
set_birth_profile,get_reading_protocolandget_tool_catalogeach cost one call when they succeed.
Budget per reading, not per request
A reading is not one call. The mandatory floors are 20 calls for a life-area question, 12 for a focused one, and 5 for a factual lookup, with full readings typically spending 25 to 40. So 300 calls a month is roughly seven to twelve full readings. Size your budget on readings and read reading depth and call floors for the arithmetic.
Scope: per account, per lane
On API key auth the meter is per account: every key created from the same Lumin account shares one allowance, so five keys is five names for one meter, and revoking a key does not reset it. On OAuth the meter is the signed-in account's own, separate from its keys. One account used from three clients is still one meter per lane.
Refresh
The monthly allowance refreshes on the 1st of each month at 00:00 UTC. Prepaid pack calls sit outside the refresh cycle: they never expire and are drawn down only after the monthly allowance is spent.
Headers
Any request that gets past authentication carries the current meter state, so you can watch your budget without a separate endpoint. A 401 (no credentials, or credentials rejected) returns before this middleware runs, so it carries none of these:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 187A 429 additionally carries Retry-After in seconds. Note that it points at the monthly refresh, so it can be days, not seconds. Sleeping on it is almost never the right move.
A call drawn from the call pack balance, because the free allowance alone could not cover it, carries one more header, X-CallPack-Balance, the remaining pack balance after the draw. It is not sent on a call the free allowance covered outright.
The 429 shape
When both the free allowance and the call pack balance are used up, tools/call requests return HTTP 429 with a JSON-RPC error object, code -32000:
{
"jsonrpc": "2.0",
"id": 2,
"error": {
"code": -32000,
"message": "Monthly call allowance reached (300 tool calls this month) and no call pack balance remains on this account. The allowance refreshes on the 1st of the month, UTC. Call packs: https://lumin.guru/pricing",
"data": {
"retryAfterSeconds": 604800,
"limit": 300,
"remaining": 0,
"packBalance": 0,
"resetAt": "2026-08-01T00:00:00.000Z"
}
}
}resetAt is the ISO timestamp of the 1st of next month, UTC. retryAfterSeconds matches the Retry-After header. packBalance is the call pack balance at the moment of the 429, which a 429 only happens when that is exhausted, so it always reads 0 here. The right handling is to surface the situation to your user or buy a call pack, not to queue a retry.
Custom limits
Custom limits for bigger integrations, write to contact@lumin.guru. The override is applied per key by the Lumin team, so the change is invisible to your client code: same headers, same 429 shape, a bigger number.