Capacity & admission
GET /v1/capacity answers two questions in one call: what governs my
capacity — the explicit configuration behind your plan (priority concurrent
requests, overflow capacity, and whether automatic overflow is on) — and
what has actually been happening: how many requests were served
immediately, served after waiting, or refused, day by day.
This is an account surface, served from https://api.lunaroute.com — not the
inference endpoint. Authentication is the
same lr_ API key you use for inference; the key’s organization is the
subject of every field and there is no org parameter to pass. Platform
management keys (lr_platform_) do not work here.
Make a request
Section titled “Make a request”curl https://api.lunaroute.com/v1/capacity \ -H "LUNAROUTE-API-KEY: $LUNAROUTE_API_KEY"Older CLI integrations can keep calling GET /v1/cli/capacity — it is the
same handler and returns the same response. The endpoint is rate-limited to
60 requests per minute per key.
Response
Section titled “Response”{ "success": true, "generated_at": "2026-10-23T16:04:11Z", "data": { "now": { "limit": 4, "in_use": 3, "available": 1, "saturated": false, "ledger": "up", "sampled_at": "2026-10-23T16:04:11Z", "background": { "limit": 8, "in_use": 8, "available": 0, "saturated": true } }, "config": { "plan": "max", "priority_lanes": 4, "background_lanes": 8, "overflow_routing": "enabled" }, "history": { "as_of": "2026-10-22", "rollup_computed_at": "2026-10-23T00:05:12Z", "tail": { "through": "2026-10-23T16:04:11Z", "calculated_at": "2026-10-23T16:04:11Z" }, "last_7d": { "days_active": 7, "days_covered": 7, "peak_lanes": 4, "avg_lanes": 1.817, "p95_lanes": 3, "lane_hours": 305.3, "queued_pct": 6.2 }, "last_30d": { "days_active": 28, "days_covered": 30, "peak_lanes": 4, "avg_lanes": 1.402, "p95_lanes": 4, "lane_hours": 1009.5, "queued_pct": 8.1 } }, "admission": { "as_of": "2026-10-22", "last_7d": [ { "day": "2026-10-16", "accepted": 11402, "deferred": 388, "denied": 0, "denied_after_wait": 0, "avg_queue_wait_ms": 142.7 }, { "day": "2026-10-17", "accepted": 12130, "deferred": 512, "denied": 2, "denied_after_wait": 0, "avg_queue_wait_ms": 176.4 }, { "day": "2026-10-18", "accepted": 894, "deferred": 12, "denied": 0, "denied_after_wait": 0, "avg_queue_wait_ms": 88.0 }, { "day": "2026-10-19", "accepted": 12871, "deferred": 641, "denied": 5, "denied_after_wait": 2, "avg_queue_wait_ms": 233.9 }, { "day": "2026-10-20", "accepted": 13304, "deferred": 702, "denied": 1, "denied_after_wait": 1, "avg_queue_wait_ms": 260.2 }, { "day": "2026-10-21", "accepted": 12596, "deferred": 577, "denied": 3, "denied_after_wait": 0, "avg_queue_wait_ms": 198.5 }, { "day": "2026-10-22", "accepted": 11834, "deferred": 412, "denied": 7, "denied_after_wait": 2, "avg_queue_wait_ms": 187.0 } ], "last_30d": [ { "day": "2026-09-23", "accepted": 10978, "deferred": 287, "denied": 0, "denied_after_wait": 0, "avg_queue_wait_ms": 112.4 }, { "day": "2026-09-24", "accepted": 11021, "deferred": 301, "denied": 0, "denied_after_wait": 0, "avg_queue_wait_ms": 118.2 } ] } }}The real response carries 7 entries in last_7d and 30 in last_30d;
last_30d above is truncated for readability. Values are illustrative; field
names are exact.
now — live occupancy
Section titled “now — live occupancy”| Field | Meaning |
|---|---|
limit |
Your enforced priority concurrent-request allowance. |
in_use |
Requests in flight right now. |
available |
limit − in_use, floored at 0. |
saturated |
true when in_use ≥ limit. |
ledger |
up, degraded, or unknown — the health of the shared permit ledger behind the count. |
sampled_at |
When the live read was taken. |
background |
The overflow pool, in the same shape: limit, in_use, available, saturated. |
When ledger is degraded or unknown, treat in_use and saturated as
advisory: the count can be stale or missing. A missing value is null, never
a fabricated zero. Read the whole block together — a single field cannot tell
“the organization is idle” from “the count is unavailable right now”.
The flat figures are the priority pool. A request running via overflow holds an
overflow slot rather than a priority one, so it does not appear in in_use — it
appears in now.background instead.
now.background.limit equals your config.background_lanes. The two null
shapes differ: limit: null means the cap could not be read (unknown), while
limit: 0 means your organization has no overflow capacity at all — a closed
pool, which is never reported as saturated and always reports available: 0
— those two answers do not depend on the count. For a pool with capacity, a
background count that could not be read leaves in_use, available and
saturated null while limit still reports the cap.
saturated is an observation, not a promise: all your overflow capacity is in
use at that instant. When ledger is up and overflow is enforced, requests
that can wait queue for a free slot — and a request can still be refused when
the queue is full or its wait runs out. Those refusals are what denied and
denied_after_wait count in admission.
config — your capacity settings
Section titled “config — your capacity settings”| Field | Meaning |
|---|---|
plan |
Your plan slug. |
priority_lanes |
Your effective priority concurrent requests, including organization-admin overrides. |
background_lanes |
Your effective overflow capacity — how many additional requests may run via overflow. |
overflow_routing |
enabled or disabled: whether a request beyond your priority allowance automatically uses overflow capacity when it is free. Automatic spill applies to eligible managed text-generation requests; requests explicitly marked background (such as background image generation) reach overflow capacity by their own marking, not through this switch. See Concurrency & overflow. |
Two different null shapes matter here. An organization with no capacity
record at all reports priority_lanes: null — unknown, not zero. A
free-plan organization reports background_lanes: 0 — entitled to zero
overflow, a real value. What the numbers mean (and what happens when you
exceed them) is covered in Concurrency & overflow.
admission — what happened to your requests
Section titled “admission — what happened to your requests”One entry per complete UTC day — today is never included, so a bursty
afternoon cannot read as a collapse. as_of is the last complete day;
last_7d is the last 7 days ending there and last_30d the last 30.
| Field | Meaning |
|---|---|
accepted |
Requests served without waiting. Requests served through automatic overflow appear here too. |
deferred |
Requests that waited in the queue, then were served. |
denied |
Requests refused immediately with a 429 — the queue was full. |
denied_after_wait |
Requests that waited in the queue and were then refused anyway with a 429 — the park deadline expired, or the waiter was evicted. |
avg_queue_wait_ms |
Average time requests that waited actually spent waiting, regardless of outcome; null when nothing waited that day. |
Together with the 429 semantics in Errors & rate limits,
this reads as the story of a capacity problem: rising deferred and
avg_queue_wait_ms means your work is queuing; nonzero denied or
denied_after_wait means it is falling off. That is the signal for adding
capacity or scheduling background work off-peak.
Counts cover the shared concurrency your priority and overflow requests draw on — image generation uses the same pool, and so do System One decision requests unless your organization has a dedicated System One allocation (an entitlement), which runs in its own pool and is excluded here. Traffic that never contends for the shared pool is always excluded: requests routed with your own provider keys, embeddings, and dedicated-capacity traffic.
history — concurrency analytics
Section titled “history — concurrency analytics”The rolled daily view of occupancy, with a live partial for today. The measures
described here are the priority pool; each window also carries a background
object with the same measures for the overflow pool:
as_of— last complete rolled day;rollup_computed_at— when the nightly rollup ran.tail— today’s partial day, computed on request (through= the sample instant).last_7d/last_30d— window summaries:days_active(days with traffic),days_covered(days with rollup data, plus the tail),peak_lanes(peak concurrent requests),avg_lanes(average across days that had traffic — idle days are not averaged in),p95_lanes(95th percentile of per-minute occupancy),lane_hours(total served time),queued_pct(share of measured requests that waited).last_7d.background/last_30d.background— the same measures for the overflow pool. Comparepeak_lanesagainstconfig.background_lanes: a peak at the cap means the pool ran full. An organization that never used overflow reports zeros withavg_lanesandqueued_pctnull, not averages of nothing.
History is cached for about 5 minutes; now and admission are computed per
call. generated_at tells you when the response was assembled.
Degraded behavior
Section titled “Degraded behavior”The endpoint never invents a limit or a zero — failures surface as null or
an error, per source:
configoradmissionunavailable → that block isnullwith HTTP 200; the rest of the response stays intact.- Live read unavailable → HTTP 200 with the
nowfieldsnullandledger: "unknown"; history is still served. - Today’s partial day cannot be computed → HTTP 200 with
history.tailset tonull; the rolled-day windows stay intact anddays_coveredshrinks accordingly. - Rolled history unavailable → the one hard failure: HTTP 500 with the standard error envelope.
Build consumers that treat an absent block as “unknown”, not as zero.
See also
Section titled “See also”- Concurrency & overflow — what priority and overflow mean, queues, per-member caps.
- Errors & rate limits — the
429behavior these buckets count. - Management API keys — automation for administrators (a different key class, different host paths).