HiAPI
Blog

Tutoriale

Come usare veo-3.1-lite/image-to-video tramite l'API hiapi

Aug 27, 2026
Come usare veo-3.1-lite/image-to-video tramite l'API hiapi
Modello
veo-3.1-lite

Veo 3.1 Lite trasforma una singola immagine di riferimento più un prompt testuale in un breve video, e su hiapi è esposto tramite la stessa API asincrona a task condivisa da tutti i modelli della piattaforma. Questa guida percorre un flusso di richiesta realmente funzionante: ottenere la chiave, chiamare POST /v1/tasks, recuperare il risultato e i dettagli da considerare quando si passa da uno script usa-e-getta alla produzione (callback, idempotenza, gestione degli errori).

Cosa costruirai e cosa preparare prima

Invierai un URL di immagine e un prompt al modello veo-3.1-lite/image-to-video, ottenendo in risposta un URL .mp4 ospitato esternamente. Tutto passa attraverso l'endpoint unificato a task di hiapi, quindi la stessa struttura di richiesta vale per ogni modello video e immagine della piattaforma — cambiano solo l'id model e i campi input.

Prima di iniziare:

  1. Crea un account hiapi e ottieni una chiave API dalla dashboard. La chiave ha la forma sk-....
  2. Prepara un URL di immagine accessibile pubblicamente — l'API la recupera lato server, quindi percorsi localhost o bucket privati non funzionano.
  3. Prima di eseguire richieste reali (non di test), controlla il prezzo attuale di veo-3.1-lite/image-to-video nella pagina dei prezzi, perché il costo dipende da durata e risoluzione.

Non esiste un piano gratuito né una modalità senza chiave — ogni chiamata richiede Authorization: Bearer sk-<your-key>.

Esempio minimo funzionante

L'API a task di hiapi consiste in due chiamate: creare il task, poi o interrogarlo periodicamente oppure lasciare che una callback ti avvisi quando è completato. Di seguito la versione con polling in Python, che usa solo requests e time:

import time
import requests

API_KEY = "sk-your-key-here"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

payload = {
    "model": "veo-3.1-lite/image-to-video",
    "input": {
        "prompt": "the camera slowly pushes in as steam rises from the cup",
        "image_url": "https://example.com/your-reference-image.jpg",
        "duration": 6,
        "aspect_ratio": "16:9",
    },
}

# 1. Create the task
resp = requests.post(BASE, headers=HEADERS, json=payload, timeout=60)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print("task created:", task_id)

# 2. Poll until it's done
while True:
    task = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
    status = task["status"]
    if status == "success":
        video_url = task["output"][0]["url"]
        print("done:", video_url)
        break
    if status == "fail":
        raise RuntimeError(task.get("error"))
    time.sleep(5)

Se vuoi solo vedere il formato di trasferimento sulla rete, ecco la stessa cosa in curl grezzo:

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-your-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1-lite/image-to-video",
    "input": {
      "prompt": "the camera slowly pushes in as steam rises from the cup",
      "image_url": "https://example.com/your-reference-image.jpg",
      "duration": 6,
      "aspect_ratio": "16:9"
    }
  }'

# then poll:
curl -s https://api.hiapi.ai/v1/tasks/<taskId> \
  -H "Authorization: Bearer sk-your-key-here"

Ci sono alcuni aspetti dello schema di input che vale la pena conoscere, perché è più rigoroso di un endpoint generico che accetta qualunque cosa — i campi in eccesso vengono rifiutati direttamente, non ignorati silenziosamente:

  • prompt e image_url sono gli unici due campi obbligatori. image_url è singolare — questo modello accetta esattamente una immagine di riferimento, non un array.
  • duration accetta solo 4, 6 o 8 (secondi) — nessun altro intero.
  • aspect_ratio accetta auto, 16:9 o 9:16.
  • resolution accetta 720p o 1080p.
  • Extra opzionali: seed (intero, per la riproducibilità), generate_audio (booleano), negative_prompt (stringa).

Nota che l'id del modello è un id nudo, cioè veo-3.1-lite/image-to-video — non aggiungergli prefissi o namespace.

Quando status diventa "success", il video di output si trova in data.output[0].url. Quell'URL è temporaneo (con expireAt), quindi scaricalo o ri-ospitalo subito, invece di salvare il hotlink.

Considerazioni per la produzione: callback, idempotenza ed errori

Interrogare ogni 5 secondi va bene per uno script, ma è uno spreco in un server che gestisce molti task contemporaneamente. Per il traffico di produzione è preferibile usare le callback: passa un oggetto callback nella stessa richiesta di creazione del task e hiapi farà un POST del risultato finale al tuo endpoint, invece di essere tu a interrogarlo.

payload = {
    "model": "veo-3.1-lite/image-to-video",
    "input": {
        "prompt": "the camera slowly pushes in as steam rises from the cup",
        "image_url": "https://example.com/your-reference-image.jpg",
    },
    "callback": {
        "url": "https://yourapp.example.com/hooks/hiapi",
        "when": "final",
    },
}

L'impostazione chiave qui è when: "final" — significa che riceverai una notifica una sola volta, quando il task raggiunge uno stato terminale (success o fail), e non a ogni cambio di stato intermedio. Il tuo handler webhook dovrebbe verificare l'id del task e poi recuperare il record locale del task creato quando hai chiamato POST /v1/tasks la prima volta.

Idempotenza. Se il tuo servizio può ritentare la chiamata di creazione del task (timeout, consegna at-least-once, ecc.), aggiungi un header Idempotency-Key, lungo al massimo 255 byte:

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-your-key-here" \
  -H "Idempotency-Key: order-42-veo-submit" \
  -H "Content-Type: application/json" \
  -d '{...}'

Ritentare con la stessa chiave nello stesso account restituisce il taskId originale, invece di crearne un secondo (fatturabile) — puoi quindi lanciarlo in sicurezza da un ciclo di retry senza addebitare due volte il cliente.

Polling vs. callback, in breve: per script, notebook o strumenti interni a basso volume, usa il polling se stai comunque aspettando il risultato in modo bloccante. Per qualsiasi scenario server-side e concorrente, usa le callback — evitano di tenere aperte le connessioni e scalano su molti task in corso senza dover eseguire un ciclo di polling per ciascuno.

Gestione degli errori. Una chiave errata o revocata restituisce HTTP 401 con error.code: "permission_denied" — controlla specificamente questo caso, invece di presumere che qualsiasi risposta non-2xx significhi che la generazione del video è fallita. Un input malformato (prompt mancante, duration fuori dall'enum, campi non riconosciuti) restituisce HTTP 400 con error_code: "INVALID_REQUEST" e un messaggio che indica il campo problematico specifico — vale la pena mostrarlo direttamente nei tuoi log, invece di ignorarlo, perché il messaggio ti dice esattamente cosa correggere. Una volta accettato il task, i fallimenti lato generazione si manifestano nel payload di polling/callback con status: "fail" e un oggetto error — trattalo come riprovabile solo se il messaggio indica un problema transitorio a monte, non un problema di schema.

Risorse correlate

Domande frequenti

Devo passare image_url come data URI o base64? No — image_url deve essere un URL HTTP(S) pubblico che i server hiapi possono recuperare. Questo modello non accetta immagini codificate in base64.

Posso generare un video senza immagine di riferimento? Con veo-3.1-lite/image-to-video no — è un modello image-to-video, image_url è obbligatorio. Se vuoi la generazione da solo testo, usa un modello text-to-video; la pagina del modello Veo 3.1 non-lite elenca le modalità disponibili.

Perché ricevo ancora 400 anche se ho passato tutti i campi obbligatori? Controlla se ci sono campi extra — lo schema di input di questo modello rifiuta tutto ciò che non è nella lista consentita (prompt, image_url, duration, aspect_ratio, resolution, seed, generate_audio, negative_prompt). Il messaggio di errore indica il campo esatto che non riconosce.

Quanto tempo richiede effettivamente la generazione? Varia in base alla durata e alla profondità corrente della coda: è proprio per questo che è corretto fare polling a intervalli brevi o usare le callback, invece di presumere un tempo di attesa fisso.

L'output può includere audio? Sì, tramite il booleano generate_audio — consulta la documentazione del modello per i valori predefiniti attuali e come influisce sul costo.

Cosa succede se il mio endpoint di callback è inattivo quando il task si completa? Non affidarti solo all'arrivo della callback — conserva il taskId restituito dalla chiamata di creazione e, se non ricevi la callback entro una finestra di tempo ragionevole, passa al polling con GET /v1/tasks/<id>.

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