HiAPI
Blog

Tutoriale

Come usare veo-3.1-lite/text-to-video tramite l'API hiapi: curl, Python e una richiesta eseguibile

Aug 27, 2026
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 requests installato (pip install requests).
  • Nient'altro — text-to-video richiede 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

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.

Inizia a creare con artefatti IA persistenti

Ottieni la tua chiave API e chiama modelli di immagini, video e audio tramite un'unica API basata sui task.

Leggi la documentazione API