跳到正文
文档版本 r8
OpenAPIJSONYAML
指南 / Rate limits

Rate limits

Limits apply per organization and are shared by all of its projects and keys. A request over a limit gets HTTP 429 with a Retry-After header; nothing is created or held.

Markdown 文件在 Playground 试运行文档版本 r8

Default limits

LimitDefaultCounts
Generation creates120 per minute, bursts of up to 30Create a generation, and estimates that must measure an input video
Generation reads60 per secondGet and list generations, and other estimates
Open tasks100Tasks that are processing and have not started running yet
Running at once: video3Unfinished video tasks
Running at once: image10Unfinished image tasks
Running at once: audio10Unfinished audio tasks

The create limit is a token bucket: it holds up to 30 tokens and refills at 2 per second (120 per minute). Each create takes one token, so a burst of 30 is accepted at once and later creates are paced at the refill rate.

A task counts toward its media type's limit from acceptance until it closes, whether it succeeds, fails or is canceled. The current limits and how many tasks are running are shown on the API keys page in the console.

When you hit a limit

Every limited request gets HTTP 429 with a Retry-After header in seconds and an error body. Nothing is recorded and no Credits are held, so it is safe to send the same request again after the wait.

Response
HTTP/1.1 429 Too Many Requests
Retry-After: 5
Content-Type: application/json

{
  "error": {
    "code": "concurrency_limited",
    "message": "organization video concurrency limit reached; retry when a running task finishes",
    "retryable": true,
    "request_id": "9f2c41d07ab3e5c8a1d40be7c26f5e13"
  }
}
error.codeCauseRetry-After
concurrency_limitedAs many tasks of this media type are unfinished as the limit allows.5 seconds
rate_limitedThe create or read rate is used up, or the open-task backlog is full.Seconds until a token is available, at least 1

注意

A 429 is the only create error you may retry automatically, because the request was refused before a task existed. For a timeout or a dropped connection, read Interrupted submissions first.

Retry with backoff

Wait at least the Retry-After value, then send the request again. Cap the number of attempts and add jitter so many workers do not retry together.

Python

import random, time, requests

def create(session, body, attempts=5):
    for _ in range(attempts):
        res = session.post("https://api.vizoapi.com/v1/generations", json=body, timeout=60)
        if res.status_code != 429:
            return res
        wait = int(res.headers.get("Retry-After", "1"))
        time.sleep(wait + random.uniform(0, 1))
    return res

Node.js

export async function create(body, attempts = 5) {
  let res;
  for (let i = 0; i < attempts; i++) {
    res = await fetch("https://api.vizoapi.com/v1/generations", {
      method: "POST",
      headers: { Authorization: `Bearer ${process.env.VIZO_API_KEY}`, "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    if (res.status !== 429) return res;
    const wait = Number(res.headers.get("Retry-After") ?? "1");
    await new Promise((r) => setTimeout(r, (wait + Math.random()) * 1000));
  }
  return res;
}

Queue on your side

To run more tasks than the concurrency limit, keep your own queue and submit the next task when one closes. A webhook tells you the moment a task finishes, so you do not have to poll for free slots.

Poll a running task every 5 to 10 seconds at most. Reads share the per-second limit across your organization.

Raise a limit

Ask for a higher limit from the API keys page in the console. Tell us the media type, the expected volume and the peak number of tasks you run at once.