HiAPI
Blog

Tutoriale

API flux-2-klein-9b: guida a curl e Python

Aug 25, 2026
API flux-2-klein-9b: guida a curl e Python
Modello
flux-2-klein-9b

Su hiapi basta una singola chiamata POST /v1/tasks più il polling per generare un'immagine con flux-2-klein-9b: esattamente lo stesso pattern di attività asincrona usato da ogni modello della piattaforma. Questa guida documenta una richiesta e una risposta reali (creazione dell'attività, polling e URL finale dell'immagine), quindi il codice riportato sotto è eseguibile così com'è, non è codice illustrativo.

Cosa ti serve

  1. Una chiave API hiapi: creala nella console. Viene inviata in ogni richiesta come Bearer token.
  2. L'ID completo del modello, incluso il suffisso dell'endpoint. flux-2-klein-9b è accessibile solo tramite flux-2-klein-9b/text-to-image: scrivere solo flux-2-klein-9b restituisce un 400 (vedi sotto).

Richiesta minima funzionante (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": "flux-2-klein-9b/text-to-image",
    "input": {
      "prompt": "un faro consumato dalle intemperie su una costa rocciosa al tramonto, illuminazione cinematografica",
      "aspect_ratio": "16:9"
    }
  }'

Risposta:

{"code":200,"data":{"taskId":"tk-hiapi-01M0T23CG2GNPENYQV4WEKZJTM"},"message":"success"}

Esegui il polling dell'attività finché non è completata:

curl https://api.hiapi.ai/v1/tasks/tk-hiapi-01M0T23CG2GNPENYQV4WEKZJTM \
  -H "Authorization: Bearer sk-<your-key>"

Risposta al completamento:

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-01M0T23CG2GNPENYQV4WEKZJTM",
    "status": "success",
    "model": "flux-2-klein-9b/text-to-image",
    "created": 1787581018,
    "completed": 1787581030,
    "storage": "temp",
    "output": [
      {
        "type": "image",
        "url": "https://temp.hiapi.ai/7c6ttvrbpt/01M0T23CG2GNPENYQV4WEKZJTM-0.png",
        "artifactId": "96193",
        "expireAt": 1788185830
      }
    ]
  },
  "message": "success"
}

output[0].url è il PNG. Nei test, l'attività è passata da inviata a success in circa 12 secondi. Fai attenzione a expireAt: prima di costruire qualsiasi funzionalità che dipenda dalla disponibilità continuativa di questo URL, leggi le note sullo storage qui sotto.

Lo stesso flusso in Python

import time
import requests

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


def create_image(prompt: str, aspect_ratio: str = "1:1") -> str:
    resp = requests.post(
        f"{BASE_URL}/tasks",
        headers=HEADERS,
        json={
            "model": "flux-2-klein-9b/text-to-image",
            "input": {"prompt": prompt, "aspect_ratio": aspect_ratio},
        },
        timeout=30,
    )
    body = resp.json()
    if resp.status_code != 200 or "error" in body:
        raise RuntimeError(f"create failed: {body}")
    return body["data"]["taskId"]


def wait_for_image(task_id: str, timeout_s: int = 120, interval_s: int = 3) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        resp = requests.get(f"{BASE_URL}/tasks/{task_id}", headers=HEADERS, timeout=30)
        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(interval_s)
    raise TimeoutError(f"task {task_id} still running after {timeout_s}s")


if __name__ == "__main__":
    task_id = create_image("a weathered lighthouse on a rocky coast at sunset, cinematic lighting", "16:9")
    image_url = wait_for_image(task_id)
    image_bytes = requests.get(image_url, timeout=60).content
    with open("output.png", "wb") as f:
        f.write(image_bytes)
    print(f"saved output.png from task {task_id}")

I parametri che flux-2-klein-9b valida davvero

Lo schema di input è molto rigido: se invii qualsiasi campo non elencato, l'API rifiuta l'intera richiesta prima ancora di metterla in coda:

  • prompt (stringa, obbligatorio): l'unico campo obbligatorio.
  • aspect_ratio (stringa, facoltativo): uno tra 1:1, 4:3, 3:4, 16:9, 9:16. Qualsiasi altro valore restituisce un 400 con value must be one of ....
  • seed (intero, facoltativo): passando lo stesso seed con lo stesso prompt si ottengono risultati riproducibili.
  • output_format (stringa, facoltativo): uno tra jpeg, png, webp.

Questo è l'intero schema. Non esistono i campi size, quality, strength o n: inviarne uno qualsiasi provoca un errore:

{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: <root>: additional properties 'size' not allowed"}

flux-2-klein-9b supporta solo la generazione testo-immagine. Non accetta nemmeno image_urls: per la generazione immagine-immagine usa l'ID modello separato flux-2-klein-9b/image-to-image, che accetta una struttura di input diversa.

L'ID del modello deve includere il suffisso dell'endpoint

Su hiapi alcuni modelli si risolvono con l'ID nudo (ad esempio gpt-image-2), ma flux-2-klein-9b non è tra questi. Senza il suffisso l'attività non viene mai creata:

{"code":400,"data":null,"error_code":"MODEL_UNAVAILABLE","message":"model not available via /v1/tasks"}

Invia sempre la stringa completa flux-2-klein-9b/text-to-image come model.

Note per la produzione

  • Due strutture di errore diverse. Gli errori di validazione (campi mancanti, valori di enumerazione errati, chiavi sconosciute) vengono restituiti come {"code":400,"error_code":"INVALID_REQUEST","message":"..."} al livello superiore. Gli errori di autenticazione/autorizzazione invece vengono restituiti come {"error":{"code":"permission_denied","message":"...","request_id":"..."}}, cioè un oggetto error annidato, con HTTP 401. La gestione degli errori deve controllare entrambe le strutture; il codice che controlla solo resp["code"] non intercetta i casi 401.
  • permission_denied riguarda la chiave, non la richiesta. Se prompt è presente e del tipo corretto ma ricevi comunque un 401 permission_denied, significa che quella chiave API non ha questo modello abilitato: controlla nella console invece di ricontrollare il tuo JSON.
  • Lo storage degli output è temporaneo. storage: "temp" e ogni output ha un timestamp unix expireAt: nell'esempio catturato, circa una settimana dopo la creazione. Dopo il successo dell'attività scarica subito il file o caricalo sul tuo storage; non salvare l'URL di temp.hiapi.ai come indirizzo permanente.
  • Per i lotti usa i callback. Il polling di un'immagine va bene; il polling di cinquanta immagini significa cinquanta andate e ritorni ripetuti. Imposta callback: {"url": "...", "when": "final"} al livello superiore della richiesta di creazione, così hiapi ti invia il risultato una volta sola quando l'attività è realmente completata. Attualmente when supporta solo il valore "final".
  • Riprova prima di ottenere il taskId, non dopo. Un errore di rete o un 5xx sulla POST /v1/tasks iniziale può essere ritentato in sicurezza: a quel punto non è stato creato nulla. Una volta ottenuto il taskId, inviare di nuovo lo stesso prompt crea una seconda immagine non correlata; in quel caso fai polling o attendi il callback.

Contenuti correlati

Domande frequenti

Perché chiamando flux-2-klein-9b ottengo MODEL_UNAVAILABLE? L'ID del modello richiede il suffisso dell'endpoint. Usa flux-2-klein-9b/text-to-image, non il semplice flux-2-klein-9b.

Quali rapporti d'aspetto supporta flux-2-klein-9b? Cinque: 1:1, 4:3, 3:4, 16:9, 9:16. Qualsiasi altro valore restituisce un 400 con un messaggio value must be one of che elenca questi cinque valori.

Posso controllare la qualità o la risoluzione dell'output? No: lo schema accetta solo prompt, aspect_ratio, seed e output_format. Non esistono i parametri size o quality; inviarne uno restituisce un 400 con errore additional properties.

Posso fare editing immagine-immagine con flux-2-klein-9b? Non con questo ID modello. Usa flux-2-klein-9b/image-to-image, che ha un proprio schema di input separato.

Quanto dura l'URL di output? storage è "temp" e ogni output ha un timestamp unix expireAt, in pratica circa una settimana dopo. Dopo il successo dell'attività scarica o ricarica subito il file: non trattare l'URL come un indirizzo permanente.

Perché una chiave che funziona con altri modelli restituisce 401 con questo modello? L'accesso ai modelli è concesso per singola chiave. Un 401 con error_code: "permission_denied" significa che quella specifica chiave non è ancora autorizzata per flux-2-klein-9b: abilitala nella console, non è un bug nel tuo corpo della richiesta.

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