🎁 Novità Registrati gratis, 10 chiamate le offriamo noi. Fino a $1, senza carta.

Generazione di video

POST /v1/videos · GET /v1/videos/{id} · DELETE /v1/videos/{id}

Genera brevi video da un prompt testuale, opzionalmente guidati da frame di riferimento (primo/ultimo). È una job API asincrona nella forma standard create + poll: POST /v1/videos crea un task che risponde in ~2 secondi, lo interroghi finché non termina, e l'header Prefer: wait trasforma le generazioni veloci in una singola chiamata sincrona. Modelli Seedance, una sola chiave API, stessa fatturazione degli altri endpoint.

L'API video è in preview limitata (test su invito). I modelli compaiono nel catalogo e nei prezzi, ma creare task richiede che il tuo workspace sia in allowlist — contattaci per abilitarlo.

Endpoint e ciclo di vita del task

Una risorsa task, quattro operazioni. Un task passa da queuedin_progress → uno stato terminale: completed, failed o cancelled. La risposta di creazione include link status_url / cancel_url già pronti — non assembli mai URL a mano.

EndpointDescrizione
POST /v1/videosCrea un task di generazione. Risponde in ~2 s con l'oggetto task (status queued) e i link di polling.
GET /v1/videos/{id}Interroga il task. Su completed ottieni data[0].url, usage.completion_tokens e i parametri effettivamente applicati; su failed un errore strutturato con codice e messaggio del provider.
DELETE /v1/videos/{id}Annulla il task. Solo i task queued possono essere annullati; i task annullati non vengono mai fatturati.
GET /v1/videos/modelsElenca i modelli video disponibili per la tua chiave, con vincoli di risoluzione/durata e prezzi per modello.

Zucchero sincrono — Prefer: wait

Aggiungi un header Prefer: wait o Prefer: wait=N (N limitato a 1..60 secondi) alla chiamata di creazione e il gateway tiene aperta la richiesta. Se il task termina nella finestra ricevi direttamente l'oggetto terminale — URL del video e usage inclusi, senza polling. Se non fa in tempo, la chiamata degrada con grazia: ricevi l'oggetto di stato corrente (nessun errore, il task continua) e prosegui col polling normale.

Corpo della richiesta

ParametroTipoDescrizione
model*stringIl modello video da usare (es. seedance-1-5-pro-251215). Elenca tutti i modelli disponibili via GET /v1/videos/models.
prompt*stringDescrizione testuale del video desiderato.
imagestring | string[]Input image-to-video: un'immagine = primo frame, due immagini = primo + ultimo frame. Ogni voce è un data URI o un URL https.
resolutionstringRisoluzione di output: 480p, 720p, 1080p o 4k. L'insieme supportato varia per modello — vedi la tabella dei modelli.
ratiostringRapporto d'aspetto: 16:9, 4:3, 1:1, 3:4, 9:16, 21:9 o adaptive.
durationintegerDurata della clip in secondi (intervallo per modello entro 2..15). Alcuni modelli accettano anche -1 per lasciar scegliere il modello.
seedintegerSeed opzionale per output riproducibile (dove supportato).
watermarkbooleanSe renderizzare il watermark del provider.
generate_audiobooleanGenera la traccia audio (default true). Sui modelli a doppia tariffa cambia il prezzo — vedi la tabella dei modelli.

Modelli disponibili

La disponibilità dei modelli dipende dal tuo deployment. Recupera l'elenco live e compliance-aware — con vincoli di risoluzione/durata e prezzi di ciascun modello — via GET /v1/videos/models. La lineup attuale:

ModelloRisoluzioniDurataPrezzoNote
dreamina-seedance-2-0-260128 480p · 720p · 1080p · 4k 4–15 s 480p/720p $7.0 · 1080p $7.7 · 4k $4.0 Ammiraglia 2.0; fino a 4K
dreamina-seedance-2-0-fast-260128 480p · 720p 4–15 s $5.6 Variante 2.0 più veloce
dreamina-seedance-2-0-mini-260615 480p · 720p 4–15 s $3.5 Variante 2.0 più piccola
seedance-1-5-pro-251215 480p · 720p · 1080p 4–12 s $2.4 audio · $1.2 muted Tariffa in base a generate_audio
seedance-1-0-pro-fast-251015 480p · 720p · 1080p 2–12 s $1.0 Il più economico

Prezzo: USD per 1M di video token. seedance-1-5-pro-251215 fattura $2.4 con la traccia audio attiva (generate_audio: true, il default) e $1.2 senza; gli altri modelli hanno una tariffa unica per fascia di risoluzione.

Video token e prezzi

Il video è fatturato in video token, derivati dall'output reale: tokens ≈ larghezza × altezza × 24 fps × secondi / 1024. Le tariffe sono per 1M di video token e seguono i parametri effettivamente applicati (riportati nel task completed) — quindi ratio: "adaptive" e duration: -1 sono fatturati in base a ciò che il modello ha realmente prodotto.

Riferimenti intuitivi su seedance-1-5-pro-251215 con audio: una clip 480p / 16:9 / 4 s ≈ 40,6K video token ≈ $0.10; una 720p / 5 s ≈ 108,9K token ≈ $0.26.

Fatturazione

Fatturato solo in caso di successo: l'addebito avviene una sola volta, quando il task raggiunge completed per la prima volta, in base allo usage di video token restituito. I task falliti (compresi i rifiuti della moderazione dei contenuti) e quelli annullati non vengono mai fatturati — l'errore del provider è inoltrato testualmente.

!

Il data[0].url restituito è un URL pre-firmato del provider che scade in ~24 ore — scaricalo subito e ricarica il file su uno storage tuo se ti serve a lungo termine.

Esempio — curl, in un colpo solo (Prefer: wait)

curl https://synthorai.io/v1/videos \
  -H "Authorization: Bearer $SYNTHORAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=60" \
  -d '{
    "model": "seedance-1-0-pro-fast-251015",
    "prompt": "A corgi puppy chasing a butterfly across a meadow, cinematic",
    "resolution": "480p",
    "ratio": "16:9",
    "duration": 4
  }'

# Finished inside the wait window → the terminal object comes straight back:
{
  "id": "vid_6091d8d1af805818b1470488",
  "object": "video",
  "model": "seedance-1-0-pro-fast-251015",
  "status": "completed",
  "data": [{ "url": "https://…tos….mp4?…" }],
  "usage": { "completion_tokens": 40594, "total_tokens": 40594 },
  "resolution": "480p", "ratio": "16:9", "duration": 4, "fps": 24,
  "seed": 34142
}
# Not done in time → the current status object is returned instead (no error,
# the task keeps running) — continue polling status_url as usual.

Esempio — curl, create + poll

# 1) Create — returns in ~2 s with a queued task object
curl https://synthorai.io/v1/videos \
  -H "Authorization: Bearer $SYNTHORAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-1-5-pro-251215",
    "prompt": "A corgi puppy chasing a butterfly across a meadow, cinematic",
    "resolution": "720p",
    "duration": 5,
    "generate_audio": true
  }'

{
  "id": "vid_6091d8d1af805818b1470488",
  "object": "video",
  "model": "seedance-1-5-pro-251215",
  "status": "queued",
  "created_at": 1784619862,
  "status_url": "https://synthorai.io/v1/videos/vid_6091d8d1af805818b1470488",
  "cancel_url": "https://synthorai.io/v1/videos/vid_6091d8d1af805818b1470488"
}

# 2) Poll until status is terminal (completed | failed | cancelled)
curl https://synthorai.io/v1/videos/vid_6091d8d1af805818b1470488 \
  -H "Authorization: Bearer $SYNTHORAI_API_KEY"

{
  "id": "vid_6091d8d1af805818b1470488",
  "object": "video",
  "model": "seedance-1-5-pro-251215",
  "status": "completed",
  "data": [{ "url": "https://…tos….mp4?…" }],
  "usage": { "completion_tokens": 108900, "total_tokens": 108900 },
  "resolution": "720p", "ratio": "16:9", "duration": 5, "fps": 24,
  "seed": 34142, "generate_audio": true
}

# 3) Download the video — the URL is pre-signed (no auth header) and expires
#    in ~24 h: fetch promptly and re-host if you need it long-term.
curl -o out.mp4 "https://…tos….mp4?…"

Esempio — Python (requests)

import time
import requests

BASE = "https://synthorai.io/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}

task = requests.post(f"{BASE}/videos", headers=HEADERS, json={
    "model": "seedance-1-5-pro-251215",
    "prompt": "A corgi puppy chasing a butterfly across a meadow, cinematic",
    "resolution": "720p",
    "duration": 5,
}).json()

while task["status"] not in ("completed", "failed", "cancelled"):
    time.sleep(5)
    task = requests.get(task["status_url"], headers=HEADERS).json()

if task["status"] == "completed":
    url = task["data"][0]["url"]  # pre-signed, valid ~24 h — re-host promptly
    with open("out.mp4", "wb") as f:
        f.write(requests.get(url).content)
else:
    print(task["error"])  # provider code + message, passed through verbatim

Esempio — Node (fetch)

import fs from "node:fs";

const BASE = "https://synthorai.io/v1";
const HEADERS = { Authorization: `Bearer ${process.env.SYNTHORAI_API_KEY}` };

let task = await (await fetch(`${BASE}/videos`, {
  method: "POST",
  headers: { ...HEADERS, "Content-Type": "application/json" },
  body: JSON.stringify({
    model: "seedance-1-5-pro-251215",
    prompt: "A corgi puppy chasing a butterfly across a meadow, cinematic",
    resolution: "720p",
    duration: 5,
  }),
})).json();

while (!["completed", "failed", "cancelled"].includes(task.status)) {
  await new Promise((r) => setTimeout(r, 5000));
  task = await (await fetch(task.status_url, { headers: HEADERS })).json();
}

if (task.status === "completed") {
  const url = task.data[0].url; // pre-signed, valid ~24 h — re-host promptly
  fs.writeFileSync("out.mp4", Buffer.from(await (await fetch(url)).arrayBuffer()));
} else {
  console.error(task.error); // provider code + message, passed through verbatim
}

Idempotenza

Passa un header X-Idempotency-Key sulla chiamata di creazione per rendere sicuri i retry: una richiesta ripetuta con la stessa chiave restituisce 409 invece di creare (e fatturare) un secondo task. La generazione video è lenta e soggetta a retry — questo evita addebiti doppi.