HiAPI
Blog

Tutoriale

Come usare l'API kling-3.0-omni/transformation: restyling video con curl e Python

Oct 14, 2026
Come usare l'API kling-3.0-omni/transformation: restyling video con curl e Python

kling-3.0-omni/transformation è il modello video-to-video di Kling 3.0 Omni: fornisci un video sorgente e un prompt testuale, e il modello riscrive l'aspetto di quel video — scena, stile, soggetto — mantenendo intatti movimento e temporalità originali. Su hiapi lo chiami tramite lo stesso endpoint asincrono unificato di tutti gli altri modelli generativi: POST /v1/tasks. Questa guida fornisce una tabella dei parametri verificata sul campo, richieste curl pronte da copiare e incollare, un client Python completo (che esegue il polling e scarica il risultato) e i pattern di produzione (callback, idempotenza, gestione degli errori) che ti servono prima di collegarlo a un'applicazione reale.

Ogni nome di campo, valore di enum e struttura di risposta riportati di seguito è stato verificato rispetto all'API reale.

Cosa costruirai + prerequisiti

Un piccolo programma: invia un processo di restyling, attende che termini, quindi scarica il file .mp4 ristilizzato. Ti servono due cose:

  1. Una chiave API hiapi. Creala nella console hiapi — ha un formato simile a sk-.... Ogni richiesta usa Authorization: Bearer sk-<your-key>.
  2. Un URL di un video sorgente accessibile pubblicamente. Il modello scarica il tuo video lato server, quindi deve essere un URL http(s) pubblico (il tuo CDN, R2/S3 con oggetti pubblici, ecc.), non un percorso di file locale. È consentito un solo URL.

Il modello e i suoi parametri

La struttura esterna della richiesta è {"model": ..., "input": {...}}. Lo schema di input è rigido — accetta solo i tre campi seguenti, qualsiasi campo aggiuntivo viene rifiutato con 400.

Campo Tipo Obbligatorio Descrizione
prompt string Sì Descrive lo stile/scena/soggetto di destinazione. Anche l'intensità del restyling si regola qui — non esiste un parametro numerico strength/fidelity.
video_urls array Sì Esattamente un URL pubblico del video sorgente (minItems pari a 1, maxItems pari a 1).
resolution string enum Sì Uno tra 720p, 1080p, 4k.

Alcuni punti che traggono facilmente in inganno:

  • Non esiste un parametro duration. La durata e le proporzioni dell'output seguono il video sorgente (3–15,5 secondi) e la fatturazione avviene sulla durata dell'output finale.
  • L'id del modello contiene -omni: kling-3.0-omni/transformation (alcuni altri endpoint Omni usano kling-3.0/...). Usa direttamente questo id come valore di model.
  • L'intensità del restyling è guidata dal prompt. Per una modifica lieve scrivi "restyling leggero, conserva tratti del volto e illuminazione"; per una modifica radicale scrivi "reimmagina completamente come cartone animato 2D cel-shaded".

Esempio minimo funzionante (curl)

# 1) Crea il processo di restyling
curl -s https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-3.0-omni/transformation",
    "input": {
      "prompt": "Ristilizza questa scena in stile animazione ad acquerello disegnata a mano, con una morbida texture carta e una calda luce crepuscolare; conserva il movimento di camera e il soggetto originali.",
      "video_urls": ["https://your-cdn.example.com/source-clip.mp4"],
      "resolution": "720p"
    }
  }'
# -> {"code":200,"data":{"taskId":"tk-hiapi-01..."},"message":"success"}

# 2) Esegui il polling del processo fino allo stato terminale
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01... \
  -H "Authorization: Bearer sk-<your-key>"
# data.status segue l'ordine: queued -> handling -> archiving -> success
# In caso di successo, data.output[0].url è il file .mp4 ristilizzato

L'id del processo che usi per il polling proviene da data.taskId nella risposta di creazione — non dal campo id di primo livello. Le stringhe di stato sono queued / handling / archiving / success (stato terminale) oppure fail; non dare per scontato che siano succeeded/completed.

Client Python completo (creazione → polling → download)

import os
import time
import requests

API_KEY = os.environ["HIAPI_KEY"]            # la tua chiave sk-...
BASE = "https://api.hiapi.ai"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}


def create_restyle(source_video_url: str, prompt: str, resolution: str = "720p") -> str:
    body = {
        "model": "kling-3.0-omni/transformation",
        "input": {
            "prompt": prompt,
            "video_urls": [source_video_url],   # esattamente un URL pubblico
            "resolution": resolution,           # "720p" | "1080p" | "4k"
        },
    }
    r = requests.post(f"{BASE}/v1/tasks", json=body, headers=HEADERS, timeout=30)
    r.raise_for_status()
    data = r.json()
    if data.get("code") != 200:
        raise RuntimeError(f"Invio rifiutato: {data}")
    return data["data"]["taskId"]


def wait_for_video(task_id: str, poll_s: int = 10, timeout_s: int = 900) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{BASE}/v1/tasks/{task_id}", headers=HEADERS, timeout=30)
        r.raise_for_status()
        data = r.json()["data"]
        status = data["status"]
        if status == "success":
            return data["output"][0]["url"]
        if status == "fail":
            raise RuntimeError(f"Processo fallito: {data.get('error')}")
        time.sleep(poll_s)                      # queued / handling / archiving
    raise TimeoutError(f"{task_id} non completato entro {timeout_s} secondi")


if __name__ == "__main__":
    task_id = create_restyle(
        source_video_url="https://your-cdn.example.com/source-clip.mp4",
        prompt=(
            "Ristilizza questa scena in stile animazione ad acquerello disegnata a mano, "
            "morbida texture carta, calda luce crepuscolare; conserva il movimento di camera "
            "e il soggetto originali."
        ),
        resolution="720p",
    )
    print("Processo:", task_id)

    url = wait_for_video(task_id)
    print("URL del video:", url)

    # Il file di output risiede su temp.hiapi.ai e scade (circa 7 giorni). Scaricalo subito.
    clip = requests.get(url, timeout=120).content
    with open("restyled.mp4", "wb") as f:
        f.write(clip)
    print("Salvato restyled.mp4", len(clip), "byte")

Metti la chiave in una variabile d'ambiente e avvia:

export HIAPI_KEY=sk-<your-key>
python restyle.py

Pattern di produzione

Usa i callback invece del polling frequente

Per qualsiasi scenario che vada oltre uno script, registra un webhook per evitare di mantenere un ciclo di polling. callback è un campo di primo livello — allo stesso livello di model e input, mai dentro input:

{
  "model": "kling-3.0-omni/transformation",
  "input": {
    "prompt": "Ristilizza questa scena in stile cartone animato 2D cel-shaded, con contorni spessi; conserva il movimento originale.",
    "video_urls": ["https://your-cdn.example.com/source-clip.mp4"],
    "resolution": "1080p"
  },
  "callback": { "url": "https://your-app.example.com/hooks/hiapi", "when": "final" }
}
  • callback.when accetta solo final (valore predefinito). Quando il processo raggiunge lo stato terminale, viene accodato una volta e scatta sia in caso di successo che di fallimento. La semantica di consegna è at-least-once, quindi lo stesso callback può arrivare più volte (vedi sotto).
  • Il corpo della richiesta POST consegnata è identico all'oggetto data ottenuto tramite GET /v1/tasks/<id> — quindi il tuo handler può leggere status, output[].url ed error senza effettuare un nuovo recupero.
  • Inserire callback dentro input fa fallire l'invio con l'errore additional properties 'callback' not allowed (lo schema di input di ogni modello è rigido).

Idempotenza e semantica di consegna

I callback sono at-least-once e non exactly-once — lo stesso taskId può arrivare più volte. Usa taskId come chiave del tuo handler e rendi idempotente il passo "segna come completato + salva il video". hiapi ritenta i callback che restituiscono non-2xx/timeout con cadenza immediata → +1 minuto → +5 minuti → +20 minuti, fino a 4 tentativi; il tuo endpoint deve restituire HTTP 2xx per interrompere i ritentativi.

Scarica subito l'output

data.output[0].url punta a temp.hiapi.ai e include un expireAt (timestamp Unix, TTL di circa 7 giorni). Dopo la scadenza l'oggetto viene eliminato e l'URL restituisce 404 — un nuovo polling del processo restituisce lo stesso URL ma non rigenera il file. Non appena il processo ha successo, copia subito i byte nel tuo storage.

Gestione degli errori

Tre forme di fallimento da gestire con branch distinti:

  • Errore di richiesta (HTTP 400) — struttura piatta, nessun processo creato: {"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: resolution: value must be one of '720p', '1080p', '4k'"}
  • Errore di autenticazione (HTTP 401) — struttura annidata: {"error":{"code":"permission_denied","type":"hiapi_error", ...}}
  • Processo fallito — l'invio restituisce 200 e un taskId, ma un successivo polling mostra data.status == "fail" con data.error. I processi falliti non vengono addebitati (l'importo prenotato viene rimborsato quando il processo fallisce definitivamente). I casi in cui l'URL sorgente non è raggiungibile o non può essere scaricato emergono qui.

Costi

kling-3.0-omni/transformation viene fatturato in base ai secondi di output, con una tariffa che varia in base alla risoluzione richiesta (720p $0,143 al secondo, 1080p $0,193 al secondo, 4k $0,479 al secondo, verificato il 21 ottobre 2026). Prima di elaborare video in batch, consulta la pagina dei prezzi hiapi aggiornata per le tariffe al secondo correnti — i costi dei processi video si accumulano molto più rapidamente di quelli delle immagini.

Letture correlate

Domande frequenti

Come si controlla l'intensità del restyling? Tramite il prompt, non tramite parametri. Non esistono campi strength, fidelity o creativity. Per una modifica lieve scrivi "restyling leggero, conserva volto e illuminazione", per una modifica radicale scrivi "reimmagina completamente come

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