Tutoriale
Come usare veo-3.1-lite/text-to-video tramite l'API hiapi: curl, Python e una richiesta eseguibile
veo-3.1-lite/text-to-video genera una breve clip video a partire da un semplice prompt testuale — senza bisogno di un'immagine iniziale. Questa guida fornisce esempi curl e Python pronti da copiare e incollare per la vera API dei task hiapi, lo schema di input preciso (verificato sull'endpoint online) e le forme di errore che incontrerai effettivamente in produzione.
1. Prerequisiti
- Un account hiapi e una API key (
sk-...) ottenuta dalla dashboard API Keys. - curl, oppure Python 3 con
requestsinstallato (pip install requests). - Nient'altro —
text-to-videorichiede solo una stringa di prompt.
Ogni modello di generazione su hiapi funziona tramite la stessa API asincrona unificata dei task: POST /v1/tasks crea il task, poi si esegue il polling o si attende un callback per ottenere il risultato. veo-3.1-lite/text-to-video si invoca esattamente come qualsiasi altro modello video — stessi header di autenticazione, stesso ciclo di vita del task — cambiano solo model e input. L'id del modello è veo-3.1-lite/text-to-video, con il suffisso /text-to-video; la stessa famiglia offre anche veo-3.1-lite/image-to-video, un id di modello separato per animare invece un'immagine di origine.
2. Esempio minimo eseguibile
2.1 Creare il task (curl)
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "veo-3.1-lite/text-to-video",
"input": {
"prompt": "una barchetta di carta che galleggia lungo una strada cittadina lucida di pioggia di notte, insegne al neon riflesse sull'asfalto bagnato",
"duration": 6,
"resolution": "720p",
"aspect_ratio": "16:9",
"generate_audio": true
}
}'
Una chiamata riuscita restituisce immediatamente un id di task — la generazione è asincrona:
{"code":200,"data":{"taskId":"tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX"},"message":"success"}
2.2 Eseguire il polling del risultato
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX \
-H "Authorization: Bearer sk-<your-api-key>"
Mentre la clip viene renderizzata, status è "handling". A completamento:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-01XXXXXXXXXXXXXXXXXXXXXXXX",
"model": "veo-3.1-lite/text-to-video",
"status": "success",
"storage": "temp",
"output": [
{"artifactId": "...", "type": "video", "url": "https://temp.hiapi.ai/.../result.mp4", "expireAt": 1786932195}
]
},
"message": "success"
}
output[0].url è un link temporaneo e a scadenza — scarica il file prima che expireAt scada (oppure sposta l'output in uno storage permanente).
2.3 Esempio Python completo
import time
import requests
API_KEY = "sk-<your-api-key>"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_task(prompt: str) -> str:
resp = requests.post(BASE, headers=HEADERS, json={
"model": "veo-3.1-lite/text-to-video",
"input": {
"prompt": prompt,
"duration": 6,
"resolution": "720p",
"aspect_ratio": "16:9",
},
}, timeout=30)
resp.raise_for_status()
return resp.json()["data"]["taskId"]
def wait_for_result(task_id: str, poll_seconds: int = 5, timeout_seconds: int = 600) -> str:
deadline = time.time() + timeout_seconds
while time.time() < deadline:
resp = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30)
resp.raise_for_status()
data = resp.json()["data"]
if data["status"] == "success":
return data["output"][0]["url"]
if data["status"] == "failed":
raise RuntimeError(f"task {task_id} failed: {data}")
time.sleep(poll_seconds)
raise TimeoutError(f"task {task_id} did not finish in {timeout_seconds}s")
if __name__ == "__main__":
tid = create_task("una barchetta di carta che galleggia lungo una strada cittadina lucida di pioggia di notte")
video_url = wait_for_result(tid)
print(video_url)
3. Schema di input
Tutti i campi seguenti si trovano sotto input. Lo schema è rigoroso — inviare un campo inesistente restituisce 400 (additional properties '<field>' not allowed), un ottimo modo per validare rapidamente la richiesta prima del rendering.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
prompt |
string | Sì | Descrizione della scena; specifica in modo concreto soggetto, movimento e comportamento della camera. |
duration |
integer | No | Uno tra 4, 6, 8 (secondi). |
resolution |
string | No | "720p" oppure "1080p". |
aspect_ratio |
string | No | "16:9" oppure "9:16". |
generate_audio |
boolean | No | Include nel rendering audio ambientale/di effetti sincronizzato. |
negative_prompt |
string | No | Elementi di contenuto che il rendering deve evitare. |
seed |
integer | No | Valore fisso per riprodurre la stessa composizione/movimento tra un tentativo e l'altro. |
Durate più lunghe e risoluzioni più alte aumentano i costi di rendering — prima di scalare i task in batch, consulta i prezzi correnti per modello sulla pagina dei prezzi.
4. Pattern per la produzione
Preferisci i callback al polling su larga scala
Per qualsiasi scenario che vada oltre uno script occasionale, registra un callback invece di eseguire il polling in un ciclo:
{
"model": "veo-3.1-lite/text-to-video",
"input": {"prompt": "..."},
"callback": {"url": "https://your-app.example.com/webhooks/hiapi", "when": "final"}
}
callback.url deve essere un URL http(s) raggiungibile, e when accetta solo "final" — hiapi invierà una POST una volta sola quando il task raggiunge lo stato terminale (success o failed). Questo evita di sprecare quota di richieste in cicli di polling e ti consegna il risultato nell'istante in cui è pronto, cosa ancora più importante per i video (tempi di rendering più lunghi della generazione di immagini).
Idempotenza e retry
Se il tuo task runner può ritentare l'invio (crash, timeout, ridistribuzione), registra la tua chiave di idempotenza insieme al taskId restituito prima di effettuare la richiesta, così al retry puoi verificare "l'ho già inviato?" invece di creare un rendering duplicato e pagarlo due volte.
Gestione degli errori
In pratica si incontrano due forme di errore distinte:
- Input errato (
400) — errore di validazione del corpo della richiesta:{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: prompt: missing required field \"prompt\""} - Errore di autenticazione/autorizzazione (
401) — chiave mancante, non valida o con permessi insufficienti:{"error":{"code":"permission_denied","message":"This API key cannot use the selected model...","request_id":"...","type":"hiapi_error"}}
Ramifica prima sul codice di stato HTTP, poi controlla il corpo della risposta — 400 significa quasi sempre un nome di campo o un valore errato (correggi la richiesta), mentre 401 significa che è la chiave stessa a dover essere gestita (permessi nella dashboard o una nuova chiave).
5. Pagine correlate
- Pagina del modello veo-3.1-lite/text-to-video — prezzi in tempo reale e un playground nel browser per testare i prompt prima di integrare il codice.
- Pagina del modello veo-3.1-lite/image-to-video — il modello gemello condizionato da un'immagine, per animare una scena esistente invece di partire dal testo.
- Introduzione all'API asincrona unificata — il ciclo di vita del task condiviso da ogni modello su hiapi (immagini, video, audio).
- Documentazione sull'autenticazione — formato della API key e dettagli sugli header.
- Guida all'API seedance-2.5/text-to-video — un secondo modello text-to-video sulla stessa API dei task, utile per confrontare schema e prezzi.
Domande frequenti
veo-3.1-lite/text-to-video richiede un'immagine iniziale?
No. Genera interamente a partire dalla stringa prompt. Se hai un'immagine di origine da animare, usa invece l'id di modello separato veo-3.1-lite/image-to-video.
Quali risoluzioni e durate sono supportate?
resolution è "720p" o "1080p"; duration è 4, 6 o 8 secondi. Inviare qualsiasi altro valore restituisce 400 con l'elenco dei valori ammessi.
La clip generata può avere l'audio?
Sì — imposta "generate_audio": true in input per includere audio ambientale/di effetti sincronizzato.
Come evitare il polling in un ciclo?
Passa un oggetto callback con l'url del tuo webhook e "when": "final". Al termine del task hiapi invierà una POST a quell'URL, senza che tu debba ricontrollare periodicamente con GET /v1/tasks/<id>.
Perché la mia richiesta restituisce 401 invece di 400?
Un 401 con error_code/code pari a "permission_denied" indica che la API key stessa non è valida o non ha accesso al modello — controlla la dashboard API Keys. Un 400 indica che il corpo della richiesta è malformato per una chiave di per sé valida.
L'URL del video restituito è permanente?
No — output[0].url è un link temporaneo con timestamp expireAt. Scaricalo prima della scadenza o spostalo in uno storage permanente.
Articoli correlati
Vedi tutti gli articoli →-
Tutoriale
Come chiamare hailuo-2.3-fast/image-to-video tramite l'API HiAPI: pratica con curl e Python
La prima richiesta funzionante per il livello image-to-video veloce ed economico — dall'ID del modello al download di un MP4
-
Tutoriale
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
-
Tutoriale
Utilizzare Kandinsky 6.0 Pro su HiAPI per la generazione di video da testo: tutorial con curl e Python
Dimostrazione pratica guidata dalla richiesta: costruire la chiamata da prompt a clip video, inviare la richiesta, monitorare lo stato di completamento e scaricare il risultato