Para hacer la primera llamada a Seedance 2 API, no copies solo un model ID. Primero completa una ficha de contrato con cuatro valores que pertenezcan al mismo proveedor: host, alcance de la API key, namespace del modelo y endpoint asíncrono. Mezclar uno de BytePlus con otro de Volcengine o de un gateway produce 401, 404 o incluso una página HTML que parece una respuesta válida.
Este es el contrato mínimo de la ruta internacional directa de BytePlus, verificado contra su documentación vigente el 18 de julio de 2026:
texthost = https://ark.ap-southeast.bytepluses.com key scope = proyecto de recursos de ModelArk + modelo/endpoint permitido (+ IP allowlist opcional) model = dreamina-seedance-2-0-260128 create = POST /api/v3/contents/generations/tasks retrieve = GET /api/v3/contents/generations/tasks/{task_id} delivery = callback_url + polling de reparación
Crea la clave en el proyecto de recursos de BytePlus ModelArk, guárdala en una variable de entorno del servidor y no la incluyas en JavaScript cliente, aplicaciones móviles ni repositorios públicos. La llamada de creación, según la referencia actual de BytePlus, puede empezar así:
bashcurl -X POST \ "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks" \ -H "Authorization: Bearer $ARK_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "dreamina-seedance-2-0-260128", "content": [{ "type": "text", "text": "A calm product shot, one slow camera move, clean studio light" }], "ratio": "16:9", "resolution": "720p", "duration": 5, "generate_audio": false, "callback_url": "https://example.com/webhooks/seedance" }'
La respuesta de creación contiene un id de tarea; no es el vídeo terminado. En esta revisión solo se comprobó, sin credenciales, que el endpoint correcto alcanza una frontera de autenticación con HTTP 401 y cuerpo JSON. No se ejecutó una generación autenticada ni se confirmó el acceso de una cuenta concreta al modelo, su cuota o su saldo.
Elige una ruta completa, no un model ID aislado
Las tres rutas cubren necesidades distintas. Conserva todos los valores de una sola fila durante la petición.
| Ruta | Host y alcance de la clave | Namespace de modelos | Endpoint asíncrono |
|---|---|---|---|
| BytePlus internacional directo | ark.ap-southeast.bytepluses.com; clave de un proyecto de recursos ModelArk, con restricción opcional por modelo/custom endpoint e IP | Standard dreamina-seedance-2-0-260128; Fast dreamina-seedance-2-0-fast-260128; Mini dreamina-seedance-2-0-mini-260615 | POST/GET /api/v3/contents/generations/tasks[/{id}] |
| Volcengine China directo | ark.cn-beijing.volces.com; cuenta, clave y activación del modelo en la región china correspondiente | Standard doubao-seedance-2-0-260128; Fast doubao-seedance-2-0-fast-260128; comprueba el sufijo Mini en la lista actual de tu cuenta | POST/GET /api/v3/contents/generations/tasks[/{id}] |
| LaoZhang gateway | base https://api.laozhang.ai/seedance/api/v3; token asignado al grupo SeeDance2 | doubao-seedance-2-0-260128 o doubao-seedance-2-0-fast-260128 | POST/GET /contents/generations/tasks[/{id}]; descarga compatible en https://api.laozhang.ai/v1/videos/{id}/content |
El tutorial oficial de Seedance 2.0 de BytePlus distingue Standard, Fast y Mini. Trátalos como contratos de modelo separados y confirma en la consola que el ID esté disponible y activado para tu proyecto. Un resultado de Google o el ejemplo de otro proveedor puede revelar la intención de búsqueda, pero no sustituye esta fuente ni demuestra disponibilidad para una cuenta o país.
Si tu integración necesita propiedad oficial internacional y controles de endpoint, empieza por BytePlus. Si opera dentro de la infraestructura china y usa contratos doubao-*, elige Volcengine. Si ya centralizas proveedores detrás de una sola puerta de enlace, la documentación actual de LaoZhang ofrece una ruta relay. Su contrato actual no admite flujos con rostros de personas reales; detén esos trabajos antes de subir material. Si el relay no expone un modelo, región o control necesario, detén la integración en esa ruta y cambia al proveedor oficial directo.
Prueba la frontera antes de depurar el prompt
Una petición sin credenciales no valida una generación, pero sí ayuda a detectar un host o prefijo equivocado. Envía un POST con {} y registra status, Content-Type y si el cuerpo realmente es JSON.
| Resultado observado | Qué demuestra | Acción siguiente |
|---|---|---|
BytePlus AP: 401 JSON | La petición llegó a la frontera de autenticación correcta | Revisar proyecto, clave, activación del modelo y cuota por separado |
Volcengine CN: 401 JSON | La ruta china llegó a su frontera de autenticación | Usar una clave regional y modelos doubao-* |
LaoZhang /seedance/api/v3/...: 401 JSON | El prefijo del relay es correcto y falta un token válido | Confirmar la asignación al grupo SeeDance2 |
LaoZhang /api/v3/...: 404 JSON | Falta el prefijo específico de Seedance | Corregir la base a /seedance/api/v3 |
Ruta antigua /seedance/v3/...: 200 HTML | Se alcanzó una página web, no el API JSON | Rechazar la respuesta y corregir la URL |
Por tanto, 401 no prueba que el modelo esté habilitado, y 200 no prueba éxito si el cuerpo es HTML. Esta separación evita perder horas cambiando el prompt cuando el error pertenece al contrato de transporte.
Priority ordena una cola concreta; no acelera el modelo
En la inferencia online basada en endpoint de Seedance 2.0 de BytePlus, priority acepta enteros de 0 a 9. Un valor mayor adelanta una solicitud en cola frente a solicitudes de prioridad menor dentro del mismo endpoint. No interrumpe una tarea que ya se ejecuta, no compara colas de endpoints diferentes y no garantiza una generación más rápida. Tampoco es un parámetro de inferencia flexible offline.
Si necesitas prioridad, valida primero que tu ruta sea exactamente esa y registra el endpoint junto al job. No copies el campo a Volcengine o a un gateway suponiendo que conservará la misma semántica.
El callback es un evento repetible, no el dueño único del estado
BytePlus permite enviar callback_url al crear la tarea. Publica cambios de estado como queued, running, succeeded, failed y expired. Para entregas terminales succeeded o failed, la documentación indica hasta tres reintentos si no recibe confirmación satisfactoria dentro de cinco segundos.
Ese límite no convierte al callback en entrega exactamente una vez. El mismo evento puede llegar más de una vez, desordenado o después de que tu polling ya haya actualizado el job. Tampoco hay una firma pública que esta guía pueda afirmar con seguridad; no inventes un header de firma. Usa HTTPS y valida por otros medios verificables: task ID existente, pertenencia del task al job y al usuario, tipo y tamaño del cuerpo, estados permitidos y transición monotónica.
tsasync function handleSeedanceCallback(payload: ProviderTask) { const job = await jobs.findByProviderTaskId(payload.id); if (!job) return { status: 404 }; await jobs.transaction(async (tx) => { const current = await tx.lock(job.id); if (current.processedEvents.includes(`${payload.id}:${payload.status}`)) return; if (!canAdvance(current.status, payload.status)) return; await tx.applyProviderState(current.id, payload); await tx.markEventProcessed(current.id, `${payload.id}:${payload.status}`); }); return { status: 200 }; }
Responde con rapidez y mueve la descarga o el procesamiento pesado a una cola interna. Mantén además polling con backoff para tareas no terminales: es la vía de reparación cuando el callback no llega, tu despliegue estaba reiniciando o la validación local falló.
Un timeout de creación entra en cuarentena
El fallo más costoso no es un polling adicional, sino crear dos tareas para la misma intención. Antes del POST, crea un job local con una clave idempotente derivada del usuario, ruta, modelo, prompt normalizado, referencias y parámetros de salida. Después guarda el task ID del proveedor en una actualización atómica.
| Situación | Decisión segura |
|---|---|
| El job ya tiene task ID | No volver a crear; continuar con retrieve o polling |
| El callback ya dejó el job terminal | No retroceder el estado ni recrear |
| Timeout tras enviar, sin task ID local | Marcar create_unknown y reconciliar antes de reintentar |
| No existe intento previo para la clave idempotente | Crear una vez y registrar la respuesta |
Tarea failed | Clasificar el error y exigir una decisión explícita antes de una nueva creación |
La regla de parada es sencilla: si existe cualquier evidencia de que el proveedor aceptó el trabajo, no repitas el create. Repara el vínculo task/job mediante registros y consultas disponibles. Solo un operador o una política explícita debe liberar una segunda creación cuando el resultado de la primera siga siendo indeterminado.
Cierra el flujo en tu almacenamiento
Cuando retrieve o callback indique succeeded, comprueba que exista la URL de salida, descárgala desde un worker y cópiala a almacenamiento controlado por tu aplicación. No conviertas una URL del proveedor en enlace permanente ni prometas un plazo de retención que no se haya verificado en la documentación actual.
Guarda junto al resultado el proveedor, host, modelo exacto, task ID, job ID local, estado terminal y parámetros necesarios para soporte. En los fallos, conserva el código y mensaje del proveedor sin registrar la API key ni URLs sensibles de entrada. Para separar selección de proveedor y diseño del input, consulta la comparación de proveedores de Seedance 2 API y la guía de prompts y referencias.
El contrato operativo completo queda así: elige una ruta, valida su frontera, crea una sola vez, persiste el task ID, acepta callbacks como eventos repetibles, repara con polling y conserva el resultado en tu propio sistema.
