Zum Inhalt
Lumean API

Limits and the 429 code

Five different limits with five different remedies hide behind a single 429 code. How to tell them apart with one look at the response.

Übersetzung in Arbeit

Diese Seite ist noch nicht in Ihre Sprache übersetzt — die Fassung unten ist auf English. Text und Codebeispiele sind dieselben.

A 429 in the Lumean API is not one limit but five. They have different causes, different response bodies and, most importantly, different remedies: what fixes one is useless against the other four. The generic “wait and retry” is guaranteed to work in exactly two cases out of five.

Stolperfalle

The key rate limit does not send a Retry-After header, contrary to the introductory text in the OpenAPI spec, which promises it for every 429. The missing header and the missing reason in the body are the fastest way to tell the request-rate limit from the token quota.

How to tell them apart at a glance

Two checks in this order are enough: does the body have a reason field, and did a Retry-After header arrive. The first check separates the request-rate limit from the four order-related limits; the second tells you whether you can simply wait.

Fünf Quellen für 429Der Entscheidungsbaum: steht ein reason im Body und kommt ein Retry-After-Header?HTTP 429kein reasonohne reasonkein Retry-Afterreason vorhandentoken_quota_exceededRetry-After vorhandenlimit_exceededkein Retry-Afterconcurrency_limit_exceededkein Retry-Afterpolicy_cooldown_activeRetry-After vorhanden

Five sources

SourcereasonRetry-AfterWhat to do
Key request ratenonoYour own backoff based on the key's windows
Key token quotatoken_quota_exceededyesWait retry_after seconds
Subscription usage limitlimit_exceedednoCheck GET /usage, buy more, or wait for the next period
Concurrent task slotsconcurrency_limit_exceedednoWait for your own orders to finish
Content policy cooldownpolicy_cooldown_activeyesFix the text; don't retry it as is

Key request rate

A limit on the key's own limits.requests.per_minute|per_hour|per_day windows. The body is a bare envelope { "success": false, "message": "…" }: no reason, no Retry-After, no X-RateLimit-*. Go by the key's configured windows and implement exponential backoff yourself.

An important nuance: by default a key has no request-rate limit at all. A numeric default applies only if the operator has set one in the environment. The effective windows are shown in your dashboard. If you got this 429 while the windows are empty, you are almost certainly looking at one of the four limiters below.

Key token quota

It counts tokens, not requests: the accounting unit of work volume (this is not money and not LMC). The per_minute, per_hour, per_day, per_month windows come from the key's limits.tokens.*. The check happens before creation: the order is not created and not charged.

429token_quota_exceededtoken_quota_exceeded — key token quota exhausted
Was passiert ist
The order was not created. This is the only 429 with a detailed body: `window` (the first window violated), `limit`, `used`, `requested`, `reset_at`, `retry_after`. It comes together with a `Retry-After` header.
Was jetzt zu tun ist
Wait until `reset_at` — or `retry_after` seconds; it is the same value. The presence of `Retry-After` is exactly how you tell this case apart from the key rate limit, which has no such header at all. If you cannot wait, reduce `requested`: split the text into parts so that each one fits into what remains in the window (`limit − used`).
Code-Seite öffnen

The body contains window (the first window exceeded), limit, used, requested, reset_at and retry_after, which is enough to queue the job until the exact moment instead of polling the API blindly.

Subscription usage limit

This is about your plan, not the key: the monthly generation volume is used up. The body contains only message and reason: "limit_exceeded", with no quota fields and no Retry-After. Pausing won't help: the response won't change until the end of the billing period.

Concurrent task slots

concurrency_limit_exceeded limits neither rate nor volume but the number of your orders in progress at the same time. A batch of hundreds of orders sent in a single burst hits exactly this limit. The fix is not a pause between requests but waiting for the already running orders to finish: a retry right after any of them reaches a terminal status will go through.

The effective ceiling and the current number of active orders are in GET /usage, in the entry with limit_type: "concurrent". Its period_start, period_end and resets_in are null: this limit has no period, so waiting for “the end of the month” is pointless.

Content policy cooldown

Five tasks in a row blocked by the content policy restrict creating new ones for 5 minutes, for 10 on repeat offenses, then for 15 (it goes no higher). This is the only order-related 429 that carries Retry-After, along with the retry_after (seconds) and retry_at (ISO-8601) fields.

Infrastructure failures don't move the counter: only content blocks count, and any successful task resets both the counter and the level reached.

Richtig

Wait for retry_at, and before then fix the wording in the text that the policy rejected.

Falsch

Retry the same text after the cooldown expires: it will hit the block again, raise the level to 10 minutes, and cost money on every attempt.

What to do as an integrator

  1. Read reason before Retry-After: it alone answers the question “is this about rate, volume, plan, concurrency, or text”.
  2. Respect Retry-After when it is present. When it is absent, a timer-based retry helps only with the request-rate limit; in the other cases you need GET /usage or a text fix.
  3. Don't confuse 429 with 402. The 402 code payg_topup_required is not a rejection but a payment fork: the server offers to pay for the missing tokens from your LMC balance. A blind retry is useless here; you need to repeat the request with confirm_payg_topup and quote_token.
  4. Cap the number of attempts. Three of the five sources don't clear up on their own, and an endless retry loop won't bring the order a single second closer to completion.

Tipp

Not sure which of the five you got? Paste the response body into the diagnostic tool on the “Errors” page: it parses reason and the headers and shows the matching card.

Diese Seite einer KI geben

.md öffnenllm.md

Aktualisiert 04.09.2026 · Spezifikation 0.0.1