Luma API 429 requests per minute: sliding window vs Sume

Luma counts requests in a sliding 60-second window and returns 429 if RPM or concurrent jobs fails. Sume returns 429 rate_limited: back off, reuse the key.

4 min readSume
All posts

Luma's Agents API refuses a generation request with HTTP 429 when either its requests-per-minute check or its concurrent-jobs check fails; RPM is measured over a sliding 60-second window. Sume also answers 429 when request volume passes an abuse-protection limit, with code rate_limited: back off, use retry-after when present, and retry with the same idempotency key.

How does Luma's sliding window work?

Per Luma's rate-limit guide, read 2026-10-01, each request is timestamped and the API counts requests in the last 60 seconds. There is no fixed reset boundary, so you do not get a full refill at a set minute: requests age out one by one. Successful POST /v1/generations responses (201) carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a 429 for RPM adds Retry-After.

What does Sume return on a rate limit?

The generation admission table lists 429 rate_limited as "API request volume exceeded an abuse-protection limit", with the client behavior "back off using retry-after when present". Submit rate limits are one of four separate controls; read, status and list endpoints can also be limited and should be treated as polling backpressure, not generation concurrency.

How do the two compare?

429 handling in the Luma and Sume docs, read 2026-10-01.
TopicLuma Agents APISume
WindowSliding 60 secondsNot described as a window in the admission docs
Second limit on the same 429Concurrent jobsSeparate queue_full code
Wait hintRetry-After on RPM 429retry-after when present
Retry safetyNot covered in the page readIdempotency-Key; a replay returns the original job
Support handleX-Request-Idx-sume-request-id on every response

How should I retry a Sume submit?

Send an Idempotency-Key so a retry cannot create a second paid job, wait for retry-after seconds, then resubmit with the same key and body. Reusing a key for a different payload returns 409 idempotency_conflict.

async function submit(body, key) {
  for (let attempt = 0; attempt < 5; attempt++) {
    const res = await fetch("https://api.sume.com/v1/videos", {
      method: "POST",
      headers: {
        Authorization: "Bearer " + process.env.SUME_API_KEY,
        "Content-Type": "application/json",
        "Idempotency-Key": key,
      },
      body: JSON.stringify(body),
    });
    if (res.status !== 429) return res;
    const wait = Number(res.headers.get("retry-after") ?? 2 ** attempt);
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
  throw new Error("still rate limited");
}

What do I quote when I ask for help?

The errors page says every response carries x-sume-request-id. Quote it with the error code, and do not send API keys or raw media URLs. For wait-time detail see how long to wait on a 429.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume