Seedance 2.0 FastReferencia de la API
Todo lo que necesitas para llamar a Seedance 2.0 Fast desde código: un inicio rápido en tres pasos, cada campo con sus límites, la fórmula de precios, webhooks e idempotencia. La misma API /v1 ejecuta las herramientas MCP; con sesión por MCP gastas el saldo creativo, y con una clave de API, el saldo de la API para desarrolladores.
El acceso a la API para desarrolladores requiere aprobación previa.
Inicio rápidoen tres llamadas
Configura una clave, envía la tarea con un límite de precio y luego lee el resultado.
- 01
Configura tu clave
El acceso a la API para desarrolladores requiere aprobación previa: pídelo en el estudio, en Claves de API. La clave se muestra una sola vez, así que guárdala en una variable de entorno.
export API_KEY="sk_test_…" - 02
Envía la tarea
Envía el clip por POST con un Idempotency-Key y un límite max_credits (o un quote_id). Recibes un 202 y una tarea en cola de inmediato, y los créditos se retienen.
curl https://api.pershot.app/v1/videos/generations \ -H "Authorization: Bearer $API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "model": "seedance-2.0-fast", "prompt": "Perfume mist in hard side light. Slow push-in, black background, grain.", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true, "max_credits": 34 }'{ "id": "job_01J9ZK4T8W", "object": "job", "kind": "video", "status": "queued", "money_status": "reserved", "queue_position": 2, "requested_model": "seedance-2.0-fast", "credits_quoted": 34, "credits_charged": null } - 03
Lee el resultado
Haz GET de la tarea hasta que su estado sea succeeded. outputs[].url está firmado y caduca a las 24 horas, así que descarga lo que quieras conservar.
curl https://api.pershot.app/v1/jobs/job_01J9ZK4T8W \ -H "Authorization: Bearer $API_KEY"
Parámetrosy límites
Se leen del documento OpenAPI, que se genera a partir de los mismos esquemas con los que valida la API. Los campos desconocidos se rechazan.
| Campo | Tipo | Valores permitidos | Notas |
|---|---|---|---|
modelObligatorio | string | seedance-2.0-fast · seedance-2.0-mini · auto | El id del modelo. |
promptObligatorio | string | 2–2000 caracteres | Qué generar: el sujeto, la cámara y la luz. |
durationPredeterminado: 5 | integer | 4–15 | Duración de la salida en segundos enteros, hasta 15. |
resolutionPredeterminado: "720p" | string | 480p · 720p | Resolución de salida. 480p para borradores, 720p para la entrega; cada una es una generación aparte. |
aspect_ratioPredeterminado: "16:9" | string | 16:9 · 9:16 · 1:1 | Forma del encuadre. |
generate_audioPredeterminado: true | boolean | – | Audio nativo. El precio es el mismo, activado o desactivado. |
image_urlOpcional | string | URL https | Primer fotograma para video; la imagen de origen para los modelos de edición. Una URL https pública o una URL de subida. |
reference_image_urlsOpcional | string[] | Hasta 9 · URL https | Imágenes de referencia para el sujeto y el estilo. Refiérete a ellas en el prompt como @image1, @image2. |
seedOpcional | integer | 0–2.147.483.647 | Se acepta y se ignora: Seedance 2.0 no admite semilla. |
quote_idOpcional | string | qt_… | Ejecuta con una cotización de POST /v1/quotes, válida durante 10 minutos. |
max_creditsOpcional | number | > 0 | Lo máximo que puede costar esta tarea. Si se supera, la tarea se rechaza y nunca se cobra. |
webhook_urlOpcional | string | URL https | Una URL https que recibe los eventos de la tarea. |
end_user_idOpcional | string | 1–128 caracteres | Para cuentas de desarrollador aprobadas (el acceso requiere aprobación previa): tu propio id de usuario para esta solicitud, visible en el uso. |
project_idOpcional | string | prj_… | |
shot_idOpcional | string | sht_… | |
routing_preferenceOpcional | string | stability · speed | |
enhanceOpcional | object | – |
Envía exactamente uno de quote_id o max_credits. Este endpoint rechaza model "auto": para video, llama primero a POST /v1/auto/plan y luego envía el modelo que elija con max_credits.
- Frecuencia y concurrencia
- 60 solicitudes por minuto por clave y 3 tareas a la vez por cuenta de forma predeterminada. Más claves no agregan concurrencia.
Límites
Se leen de la misma tabla que usa la API para sus comprobaciones. Cada fila indica quién verifica el límite y qué pasa si se supera.
- AplicadoLo verificamos nosotros y respondemos 400 antes de cotizar o retener nada.
- ProveedorLo verifica el proveedor. Una tarea que rechaza falla y no se cobra nada.
- RecomendadoNadie lo verifica. Mantenerse dentro de él da mejores resultados.
| Límite | Valor | Unidad | Quién lo verifica | Si se supera |
|---|---|---|---|---|
| Solicitud | ||||
Longitud del promptprompt | De 2 a 2000 | caracteres | Aplicado | 400 invalid_request en el campo prompt, antes de cualquier cotización o retención. |
Prompt en inglésprompt | hasta 1000 | palabras | Recomendado | Se acepta. El modelo puede seguir con menos precisión un prompt más largo. |
Prompt en chinoprompt | hasta 500 | caracteres chinos | Recomendado | Se acepta. El modelo puede seguir con menos precisión un prompt más largo. |
Duraciónduration | De 4 a 15Predeterminado: 5 | segundos | Aplicado | 400 invalid_request en el campo duration. Solo segundos enteros. |
Resoluciónresolution | 480p, 720pPredeterminado: 720p | – | Aplicado | 400 invalid_request en el campo resolution. |
Relación de aspectoaspect_ratio | 16:9, 9:16, 1:1Predeterminado: 16:9 | – | Aplicado | 400 invalid_request en el campo aspect_ratio. |
Semillaseed | Se ignora | – | Proveedor | Se acepta y no se envía: Seedance 2.0 no admite semilla, así que una semilla no repite un resultado. |
Duración del video de entradainput_video_seconds | De 2 a 15 | segundos | Aplicado | 400 invalid_request en POST /v1/quotes. Las generaciones por API no admiten video de entrada. |
| Imágenes que envías | ||||
Imágenes de referenciareference_image_urls | hasta 9 | imágenes | Aplicado | 400 invalid_request en el campo reference_image_urls. |
Primer fotograma o referenciasreference_image_urls | image_url o reference_image_urls, no ambos | – | Aplicado | 400 invalid_request en el campo reference_image_urls. Seedance 2.0 ejecuta uno de los dos modos por tarea. |
Lado de la imagenimage_urlreference_image_urls | De 300 a 6000 | px por lado | Aplicado en archivos subidos | Archivos subidos: 400 invalid_request en image_url o reference_image_urls.N, antes de cualquier cotización o retención. Otros enlaces: el proveedor rechaza la tarea y no se cobra nada. |
Forma de la imagenimage_urlreference_image_urls | De 0,4 a 2,5 | ancho ÷ alto | Aplicado en archivos subidos | Archivos subidos: 400 invalid_request en image_url o reference_image_urls.N, antes de cualquier cotización o retención. Otros enlaces: el proveedor rechaza la tarea y no se cobra nada. |
Tamaño de archivo subidofile | hasta 10 | MB | Aplicado | POST /v1/uploads responde 400 invalid_request en el campo file. |
Formatos de archivo subidofile | JPEG, PNG, WebP | – | Aplicado | Se lee del propio archivo, no de su nombre. Cualquier otro formato: 400 invalid_request en el campo file. |
Tamaño de imagen enlazadaimage_urlreference_image_urls | hasta 30 | MB | Proveedor | Para imágenes enlazadas desde otros servidores. El proveedor rechaza la tarea y no se cobra nada. |
Formatos de imagen enlazadaimage_urlreference_image_urls | JPEG, PNG, WebP, BMP, TIFF, GIF, HEIC, HEIF | – | Proveedor | Para imágenes enlazadas desde otros servidores. El proveedor rechaza la tarea y no se cobra nada. |
| Salida | ||||
| Píxeles de salida | 480p16:9864×4969:16496×8641:1640×640720p16:91280×7209:16720×12801:1960×960 | px | Proveedor | Los define el modelo para cada resolución y relación de aspecto. |
| Velocidad de fotogramas | 24 | fps | Proveedor | La misma para todos los videos. |
| Formato de salida | MP4 | – | Proveedor | Cada video es un MP4, con sonido cuando generate_audio está activado. |
| Enlaces | ||||
| Enlace de subida | 7 | días | Aplicado | Después de eso, el enlace responde 403. Sube el archivo de nuevo. |
| Enlace de salida | 24 | horas | Aplicado | Después de eso, el enlace responde 403. Vuelve a hacer GET de la tarea para obtener un enlace nuevo. El archivo en sí se conserva 12 meses (outputs_expire_at de la tarea indica la fecha), y más tiempo si el resultado está guardado en Recursos o se usa en un proyecto. |
Nunca descargamos imágenes de otros servidores, así que para esos enlaces el proveedor verifica el tamaño, y una tarea que rechaza no se cobra. Los mismos límites se devuelven como JSON: GET /v1/models devuelve un objeto limits para cada modelo.
Precioscalculados a la vista
Cada tarea se cotiza en créditos antes de ejecutarse (1 US$ = 100 créditos). La tarifa por segundo sirve para presupuestar; POST /v1/quotes devuelve la cifra exacta.
créditos = ceil(precio de lista de BytePlus × 0,55 × 100), donde precio de lista = (s de entrada + s de salida) × ancho × alto × 24 ÷ 1024 × tarifa de lista| Especificación | Por segundo (API) | 5 s | 10 s | 15 s |
|---|---|---|---|---|
| 480pSin entrada de video | 0,031 US$Con un video de entrada: 0,019 US$/s≈ 322 s por 10 US$ | 16 cr≈ 0,16 US$ | 31 cr≈ 0,31 US$ | 47 cr≈ 0,47 US$ |
| 720pSin entrada de video | 0,067 US$Con un video de entrada: 0,040 US$/s≈ 149 s por 10 US$ | 34 cr≈ 0,34 US$ | 67 cr≈ 0,67 US$ | 100 cr≈ 1,00 US$ |
Las tareas rechazadas o fallidas no se cobran.
Webhookse idempotencia
Los reintentos nunca cobran dos veces y no tienes que consultar el estado periódicamente.
- Idempotencia
- Cada POST de generación necesita un Idempotency-Key (de 1 a 255 caracteres ASCII visibles). La misma clave dentro de 24 horas devuelve la misma tarea con HTTP 200, así que un reintento después de un tiempo de espera agotado nunca crea ni cobra una segunda tarea.
- Prompts rechazados
- Un prompt rechazado por la verificación previa (422 content_rejected) no crea nada, así que la misma clave puede volver a usarse con un prompt nuevo.
- Eventos
job.queuedjob.processingjob.succeededjob.failedjob.cancelled- Firma
- X-Signature lleva t, la hora unix, y v1, un HMAC-SHA256 de t, un punto y el cuerpo sin procesar, con tu secreto whsec_ como clave. Rechaza las marcas de tiempo de más de cinco minutos y elimina duplicados con X-Event-Id.
- Entrega
- Una respuesta 2xx en 10 segundos cuenta como entregada. Las entregas fallidas se reintentan después de 1 min, 5 min, 30 min, 2 h y 6 h. No se siguen las redirecciones.
{
"id": "evt_01J9ZKB1QX",
"type": "job.succeeded",
"created_at": "2026-09-29T14:02:31Z",
"data": {
"job": {
"id": "job_01J9ZK4T8W",
"object": "job",
"kind": "video",
"status": "succeeded",
"money_status": "settled",
"requested_model": "seedance-2.0-fast",
"credits_charged": 34,
"outputs": [
{
"kind": "video",
"url": "https://…/job_01J9ZK4T8W.mp4?sig=…"
}
]
}
}
}import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received, before any JSON parsing.
export function verifyWebhook(header, rawBody, secret, toleranceSec = 300) {
let t = null;
const signatures = [];
for (const item of (header ?? "").split(",")) {
const [key, value] = item.split("=", 2);
if (key === "t") t = Number(value);
if (key === "v1") signatures.push(Buffer.from(value, "hex"));
}
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return signatures.some((s) => s.length === expected.length && timingSafeEqual(s, expected));
}
// verifyWebhook(req.headers["x-signature"], rawBody, process.env.WEBHOOK_SECRET)
// Answer 2xx quickly, and skip an X-Event-Id you have already handled.Erroresy qué hacer
Todos los errores tienen la misma forma: un objeto error con code, message, param y request_id. Los que probablemente encuentres:
| Código | HTTP | Qué hacer |
|---|---|---|
invalid_request | 400 | Corrige el campo indicado en param. |
unauthorized | 401 | Revisa la clave y el encabezado Bearer. |
insufficient_credits | 402 | Recarga y vuelve a intentarlo con el mismo Idempotency-Key. |
forbidden_model | 403 | Agrega el modelo o la herramienta a la lista de permitidos de la clave en el estudio, o usa otra clave. Herramientas como Mejorar necesitan su propia entrada. |
quote_expired | 409 | Obtén una cotización nueva; las cotizaciones duran 10 minutos. |
price_changed | 409 | El precio subió por encima de tu límite. Vuelve a cotizar o aumenta max_credits. |
content_rejected | 422 | No se cobró nada. Cambia el prompt o las imágenes. |
rate_limited | 429 | Espera el tiempo indicado en Retry-After y vuelve a intentarlo. |
upstream_unavailable | 503 | El modelo no está disponible. Vuelve a intentarlo más tarde; una tarea que nunca empieza no se cobra. |