HiAPI
Blog

Tutoriale

Come usare grok-imagine-1.5/image-to-video tramite l'API hiapi: curl, Python e una richiesta eseguibile subito

Jul 7, 2026
Come usare grok-imagine-1.5/image-to-video tramite l'API hiapi: curl, Python e una richiesta eseguibile subito

Riepilogo sintetico

  • Di cosa si tratta: una guida replicabile che spiega come usare grok-imagine-1.5/image-to-video tramite l'API unificata delle attività di hiapi per animare un'immagine statica in un breve video.
  • Flusso: crea un'attività con POST /v1/tasks, esegui il polling di GET /v1/tasks/<taskId> (oppure registra un callback), quindi scarica l'MP4 da data.output[0].url prima che scada.
  • Schema di input (verificato rispetto all'API live): accetta esattamente una voce image_urls, prompt opzionale, duration da 1 a 15 secondi, resolution pari a 480p/720p, aspect_ratio tra auto, 1:1, 16:9, 9:16, 3:2, 2:3. Non accetta altri campi.

Cosa costruirai e cosa ti serve

Obiettivo: inviare un'immagine sorgente più un prompt di movimento e ottenere una breve clip video MP4 generata da Grok Imagine 1.5.

Prerequisiti:

  • Una chiave API hiapi — creala nella dashboard. La chiave ha la forma sk-... e va inserita nell'intestazione Authorization: Bearer.
  • Un URL dell'immagine sorgente accessibile pubblicamente (JPEG/PNG). L'API recupera l'immagine lato server, quindi i link a localhost o i file che richiedono autenticazione non funzionano.
  • Qualsiasi client HTTP. Gli esempi seguenti usano curl e requests di Python.

L'id del modello è la stringa nuda grok-imagine-1.5/image-to-video, senza suffisso.

Esempio minimo eseguibile: curl

Crea l'attività:

curl -X POST "https://api.hiapi.ai/v1/tasks" \
  -H "Authorization: Bearer sk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-1.5/image-to-video",
    "input": {
      "image_urls": ["https://example.com/product-shot.jpg"],
      "prompt": "slow cinematic push-in, soft studio light drifting across the subject",
      "duration": 6,
      "resolution": "720p",
      "aspect_ratio": "16:9"
    }
  }'

Un invio riuscito restituisce 200 e un taskId:

{
  "code": 200,
  "data": { "taskId": "tk-hiapi-01KWVVSTX0TJ32AD45F6ZQ08W5", "status": "queued" },
  "message": "success"
}

Esegui il polling finché l'attività non raggiunge uno stato terminale (status passa progressivamente da queued → handling → success o fail):

curl "https://api.hiapi.ai/v1/tasks/tk-hiapi-01KWVVSTX0TJ32AD45F6ZQ08W5" \
  -H "Authorization: Bearer sk-YOUR_KEY"

Attività completata (risposta reale, troncata):

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-01KWVVSTX0TJ32AD45F6ZQ08W5",
    "model": "grok-imagine-1.5/image-to-video",
    "status": "success",
    "storage": "temp",
    "output": [
      {
        "type": "video",
        "url": "https://temp.hiapi.ai/.../01KWVVSTX0TJ32AD45F6ZQ08W5-0.mp4",
        "expireAt": 1783951451
      }
    ]
  },
  "message": "success"
}

⚠️ storage: "temp" e expireAt significano che l'URL di download è temporaneo. Scarica l'MP4 e salvalo sulla tua infrastruttura subito dopo il successo dell'attività — non fare hotlinking.

Esempio minimo eseguibile: Python

Script completo — crea, esegue polling, scarica:

import time
import requests

API_KEY = "sk-YOUR_KEY"
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1. Crea l'attività
resp = requests.post(BASE, headers=HEADERS, json={
    "model": "grok-imagine-1.5/image-to-video",
    "input": {
        "image_urls": ["https://example.com/product-shot.jpg"],
        "prompt": "slow cinematic push-in, soft studio light drifting across the subject",
        "duration": 6,
        "resolution": "720p",
        "aspect_ratio": "16:9",
    },
})
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print("task:", task_id)

# 2. Esegui il polling del risultato (image-to-video di solito termina ben entro pochi minuti)
deadline = time.time() + 600
while time.time() < deadline:
    task = requests.get(f"{BASE}/{task_id}", headers=HEADERS).json()["data"]
    status = task["status"]
    if status == "success":
        break
    if status == "fail":
        raise RuntimeError(f"generation failed: {task.get('error')}")
    time.sleep(5)
else:
    raise TimeoutError(f"task {task_id} still not finished after 10 min")

# 3. Scarica immediatamente — l'URL di output scade
video_url = task["output"][0]["url"]
mp4 = requests.get(video_url, timeout=120)
mp4.raise_for_status()
with open("clip.mp4", "wb") as f:
    f.write(mp4.content)
print("saved clip.mp4,", len(mp4.content), "bytes")

Riferimento input (cosa accetta realmente lo schema)

Questi vincoli provengono direttamente dal validatore live, non sono supposizioni — inviare altro restituisce 400 INVALID_REQUEST con un messaggio preciso:

Campo Tipo Regola
image_urls array di stringhe obbligatorio, esattamente 1 URL (maxItems: 1)
prompt stringa opzionale — descrive il movimento, il movimento di camera e l'atmosfera
duration intero da 1 a 15 secondi
resolution stringa 480p o 720p
aspect_ratio stringa auto, 1:1, 16:9, 9:16, 3:2, 2:3

Note:

  • Questo modello non ha i campi seed, negative_prompt, fps, motion_strength o camera_fixed. Lo schema rifiuta le proprietà sconosciute (additional properties ... not allowed), quindi controlla movimento e comportamento della camera esclusivamente tramite prompt.
  • Ogni attività può avere una sola immagine di riferimento. Passarne due restituisce image_urls: maxItems: got 2, want 1.
  • aspect_ratio: "auto" segue le proporzioni dell'immagine sorgente — di solito è ciò che si desidera per le foto di prodotto.
  • Il vecchio grok-imagine/image-to-video accetta fino a 30 secondi per clip; 1.5 si ferma a 15 secondi. Entrambi hanno lo stesso prezzo al secondo: $0.015 per 480p, $0.0282 per 720p.

Considerazioni per la produzione

Usa i callback invece del polling. Per qualsiasi scenario oltre agli script, registra un webhook al momento della creazione dell'attività e salta il ciclo di polling:

{
  "model": "grok-imagine-1.5/image-to-video",
  "input": { "image_urls": ["https://example.com/shot.jpg"], "duration": 6 },
  "callback": { "url": "https://yourapp.com/hooks/hiapi", "when": "final" }
}

callback.url deve essere un endpoint http(s) pubblico e when supporta solo "final" — ricevi un POST una volta quando l'attività raggiunge success o fail. Il polling va bene per CLI e attività batch; i callback sono migliori quando devi generare molti clip in blocco senza distribuire una flotta di poller. Mantieni un polling di fallback (ad esempio controllare ogni pochi minuti le attività che non hanno ricevuto callback) per evitare che un webhook perso lasci le attività in sospeso.

Idempotenza. La creazione delle attività non è deduplicata lato server, quindi un semplice retry dopo un timeout di rete può causare invii duplicati e addebiti duplicati. Persisti il taskId non appena la chiamata di creazione restituisce, e controlla il tuo storage prima di riprovare; se il processo si interrompe tra l'invio e la persistenza, elenca le attività recenti (GET /v1/tasks) e abbinale per modello + ora di creazione prima di reinviare.

Gestione degli errori. Le modalità di errore che incontrerai realmente:

  • 401 con {"error": {"code": "permission_denied", "type": "hiapi_error", ...}} — chiave errata, o chiave senza accesso a quel modello. La risposta include un request_id per l'assistenza.
  • 400 con error_code: "INVALID_REQUEST" — violazione dello schema; il message indica il campo e la regola specifici (ad esempio duration: maximum: got 99, want 15). Correggi il corpo della richiesta, non riprovare alla cieca.
  • 402 saldo insufficiente — i modelli video precontrollano la tua quota al momento dell'invio. Ricarica e reinvia.
  • L'attività stessa con status: "fail" — errore lato generazione; controlla data.error e riprova con backoff. Un'immagine sorgente non accessibile è una causa comune.

Salva subito l'output. Vale la pena ripeterlo: output[0].url risiede su storage temporaneo con un timestamp expireAt. Nel momento in cui vedi success, trasmetti immediatamente l'MP4 al tuo bucket di storage. Se la tua pipeline si interrompe dopo il successo ma prima del download, recupera di nuovo l'attività per id — l'URL rimane valido fino a expireAt, non per sempre.

Letture correlate

Domande frequenti

Quanto può essere lungo un video grok-imagine-1.5? Da 1 a 15 secondi, impostati dal campo intero duration. Richiedere di più restituisce 400 (duration: maximum: got X, want 15). Se ti servono fino a 30 secondi, usa il vecchio grok-imagine/image-to-video.

Quali risoluzioni e proporzioni supporta? resolution è 480p o 720p; aspect_ratio è auto, 1:1, 16:9, 9:16, 3:2 o 2:3. 9:16 a 720p è la combinazione preferita per clip verticali in stile Shorts/Reels.

Posso passare più immagini di riferimento? No — image_urls di questo modello accetta esattamente un URL. Per flussi di lavoro multi-riferimento, concatena le attività o prima componi le immagini di riferimento in un'unica immagine di input.

C'è un seed o un prompt negativo? No. Lo schema di input rifiuta direttamente seed, negative_prompt, fps e campi simili. Stile del movimento, movimento di camera e atmosfera sono tutti controllati tramite la stringa prompt.

Quanto costa? La fatturazione è basata sui secondi di video generato: $0.015/secondo per 480p, $0.0282/secondo per 720p. Una clip di 6 secondi costa $0.09 in 480p e $0.1692 in 720p. Se non passi duration, il valore predefinito è 8 secondi. Per altri esempi vedi il dettaglio dei prezzi di Grok Imagine 1.5.

Perché la mia richiesta restituisce 401 permission_denied? O la chiave API è errata/revocata, oppure non ha accesso a quel modello. Verifica la chiave nella dashboard e assicurati di inviare Authorization: Bearer sk-... — l'assenza del prefisso Bearer produce lo stesso errore.

Come faccio a sapere che il video è pronto senza polling? Allega "callback": {"url": "https://your-endpoint", "when": "final"} al momento della creazione dell'attività. Quando l'attività raggiunge uno stato terminale, hiapi invia un POST al tuo endpoint. Come fallback, esegui il polling di GET /v1/tasks/<taskId>.

Perché il mio URL del video smette di funzionare dopo qualche giorno? L'output risiede su storage temporaneo — ogni voce di output porta un timestamp expireAt. Scarica il file subito dopo success e servilo dal tuo storage.

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