Skip to content
LUNAROUTEDocs

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.

Terminal window
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.

{
"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.

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.

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.

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. Compare peak_lanes against config.background_lanes: a peak at the cap means the pool ran full. An organization that never used overflow reports zeros with avg_lanes and queued_pct null, 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.

The endpoint never invents a limit or a zero — failures surface as null or an error, per source:

  • config or admission unavailable → that block is null with HTTP 200; the rest of the response stays intact.
  • Live read unavailable → HTTP 200 with the now fields null and ledger: "unknown"; history is still served.
  • Today’s partial day cannot be computed → HTTP 200 with history.tail set to null; the rolled-day windows stay intact and days_covered shrinks 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.