The Seedance API rate limits are published, and they are two numbers rather than one. On Volcengine Ark, doubao-seedance-2-5-260628 carries 最大 RPM: 企业用户: 600 个人用户: 180 and 最大并发: 企业用户: 10 个人用户: 3. Both columns carry one qualifier: 非刚性保障,受平台负载/调用方式影响,详见文档. Offline inference is 暂不支持. The API overview covers the call shapes.
The published limits, verbatim
Ark keeps these in its model list, under a column headed 在线推理限流. The rows below are the vendor’s own cells, not a summary.
| Model ID | 最大 RPM | 最大并发 | 离线推理限流 |
|---|---|---|---|
doubao-seedance-2-5-260628 | 企业用户 600 / 个人用户 180 | 企业用户 10 / 个人用户 3 | 暂不支持 |
doubao-seedance-2-0-260128 | 非 4k:600 / 180;4k:15 / 15 | 非 4k:10 / 3;4k:1 / 1 | 暂不支持 |
doubao-seedance-2-0-fast-260128 | 企业用户 600 / 个人用户 180 | 企业用户 10 / 个人用户 3 | 暂不支持 |
doubao-seedance-2-0-mini-260615 | 企业用户 600 / 个人用户 180 | 企业用户 10 / 个人用户 3 | 暂不支持 |
Search this query and you meet four mutually contradictory third-party tables before you meet the vendor’s. One reseller publishes 30 requests per 60 seconds per account; a second publishes Generation 100/min; a third reports 每分鐘請求: 20–60; a fourth lists Requests per minute 60 and Concurrent generations 5. Each labels its numbers as its own, and none is Ark’s. The endpoint reference is where the request surface itself lives.
curl -X POST https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ARK_API_KEY" \
-d '{
"model": "doubao-seedance-2-5-260628",
"content": [
{ "type": "text", "text": "A workshop at dawn, hands assembling a clock movement." }
],
"ratio": "16:9",
"duration": 5
}'
Concurrency and RPM are two budgets

The two published numbers behave differently, and conflating them is the usual planning mistake.
RPM counts submissions per minute. A video task costs one request to create and one per poll to check, so a tight polling loop is a request generator. Concurrency counts tasks in flight at the same time, and a single Seedance job holds a slot for minutes.
Reading the budget as in-flight jobs
That difference changes what you measure. Ten concurrent tasks at 600 RPM means the rate limit is not your constraint; your own job duration is. If a generation takes three minutes, ten slots deliver roughly three completions per minute, and the remaining 590 requests per minute are polls you are spending to watch them.
import json
import os
import threading
from concurrent.futures import ThreadPoolExecutor
import requests
ARK = "https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks"
BUDGET = 10 # 最大并发: 企业用户: 10 个人用户: 3
slots = threading.Semaphore(BUDGET)
def run(payload, api_key):
with slots: # one slot held for the whole generation, released on exit
created = requests.post(
ARK,
headers={"Authorization": f"Bearer {api_key}"},
json=payload,
timeout=60,
)
created.raise_for_status()
task_id = created.json()["id"]
while True:
polled = requests.get(
f"{ARK}/{task_id}",
headers={"Authorization": f"Bearer {api_key}"},
timeout=60,
)
polled.raise_for_status()
body = polled.json()
if body["status"] in {"succeeded", "failed", "expired", "cancelled"}:
return task_id, body["status"]
with ThreadPoolExecutor(max_workers=BUDGET) as pool:
futures = [pool.submit(run, {"model": "doubao-seedance-2-5-260628",
"content": [{"type": "text", "text": "A workshop at dawn."}],
"ratio": "16:9", "duration": 5}, os.environ["ARK_API_KEY"])
for _ in range(40)]
for future in futures:
print(*future.result())
curl -s -X GET \
"https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks?page_num=1&page_size=100&filter.status=running" \
-H "Authorization: Bearer $ARK_API_KEY" | jq '.items | length'
The quota is per account, not per key
Ark states this plainly: 每个账号(含主账号下的所有子账号,合并计算). Every sub-account under a main account draws on one shared ceiling.
The consequence is that a per-key budget is a fiction. If two services each hold a key and each is tuned to ten concurrent tasks, together they ask for twenty. Enforce the ceiling where your services can see it — one queue with one dispatcher, or a counter in shared storage — rather than inside each client.
Why you get throttled with quota left
Ark explains this in its FAQ, and the sentence is the most useful one in the topic: 方舟对于模型限流的逻辑使用的是预扣机制,来保障您已提交的请求的完成率。即在收到请求时会根据输入和输出长度预扣除本时间窗口的 TPM 配额.
Reservation up front, against a window. A request is charged before it runs, based on its input and expected output length. Submit several long jobs in one window and you can be refused while a dashboard still shows headroom, because that headroom was reserved and not yet consumed. The vendor’s stated reason is stability: without reservation, a burst of long requests would starve everything already submitted.
Backing off when you do get throttled
Ark publishes no throttle contract — no documented status code and no retry header. The script below records what it receives instead of assuming a code.
import random
import time
import requests
ARK = "https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks"
def submit(payload, api_key, attempts=6):
"""Submit one task. Backs off on any non-2xx and keeps the first body seen."""
for attempt in range(attempts):
response = requests.post(
ARK,
headers={"Authorization": f"Bearer {api_key}"},
json=payload,
timeout=60,
)
if response.ok:
return response.json()
# Ark does not publish which code means throttled, so log it rather
# than hardcoding a guess.
print("status", response.status_code, response.text[:200])
delay = min(2**attempt, 60) * (0.5 + random.random())
time.sleep(delay)
raise RuntimeError("gave up after repeated non-2xx responses")
The Retry-After header is absent on purpose. It is what third-party gateways implement, not what Ark documents.
Resolution changes the budget
For the 2.0 family the model list splits the row by output resolution. The non-4K tier keeps 最大 RPM: 企业用户: 600 个人用户: 180 and 最大并发: 企业用户: 10 个人用户: 3. The 4K tier collapses to 最大 RPM 企业用户:15 个人用户:15 and 最大并发 企业用户:1 个人用户:1.
The 2.0 4K row
Concurrency of one serialises the 4K tier completely: a second 4K job has nowhere to go until the first finishes. A four-way 4K batch against a ten-slot mental model is off by forty times on rate and ten times on concurrency.
For 2.5 the vendor publishes one set of numbers and no resolution split, so do not carry the 2.0 4K figures across. Whether resolution moves the 2.5 ceiling is not stated, which matters before you promise a client a 4K schedule.
What the vendor has not published
Not published as of this review:
- The HTTP status code returned when a request is throttled. No
429appears in any official page reviewed here, so third-party429handling is gateway-specific. - Any retry header, including
Retry-After, or any header from theX-RateLimit-*family. - Per-endpoint QPS ceilings. A previously cited page now serves unrelated content, and no official page reviewed carries those figures.
- Whether resolution changes the ceiling for
doubao-seedance-2-5-260628. - Queue depth, expected wait times and success-rate guarantees.
- Any free quota for this model.
Two published details are easy to miss. The ceiling is a non-binding target, per 非刚性保障, so the numbers describe intent rather than a guarantee. And the escalation path is explicit: 如需提升,请联系客户经理或者提交 工单。
Frequently asked questions
How many requests per minute does Seedance allow? 最大 RPM: 企业用户: 600 个人用户: 180 for the Seedance models on Ark, published in the model list.
How many tasks can run at once? 最大并发: 企业用户: 10 个人用户: 3. For the 2.0 4K tier it drops to 最大并发 企业用户:1 个人用户:1.
Does a poll count against the limit? The published figure is a request rate, and a poll is a request. The polling loop is where most of your request budget goes if you are not careful.
Is the limit per key or per account? Per account: 每个账号(含主账号下的所有子账号,合并计算). Split your services across keys and they still share one ceiling.
What error do I get when throttled? The vendor publishes none. Log the actual response rather than branching on an assumed 429, and read the price formula instead of your error logs when you want to know what a burst costs.
Recheck the model list before you size a queue. The numbers are non-binding and the page changes without notice.