HiAPI
Blog

Tutoriale

Come usare imagen4-ultra tramite l'API HiAPI: esempi con curl e Python

Esercitazione pratica completa sulla generazione di immagini di alta qualità da testo su HiAPI

Oct 31, 2026
博客封面图:淡蓝底上多层半透明玻璃平面叠错排列,折射出克制的冷蓝色带。

Cosa offre imagen4-ultra su HiAPI

imagen4-ultra è il modello di generazione di immagini di alta qualità da testo di HiAPI: invii un prompt e ricevi un'immagine generata. Ciò che lo rende davvero utile per gli sviluppatori è che, come tutti gli altri modelli della piattaforma, funziona dietro l'interfaccia unificata di HiAPI, quindi il metodo di autenticazione, la struttura delle richieste e il modello di gestione delle attività che impari qui sono direttamente riutilizzabili su altri endpoint.

Questo tutorial è un'esercitazione pratica eseguibile, non un elenco di parametri. Al termine avrai:

  • una richiesta curl pronta da copiare e incollare per inviare un'attività di generazione di immagini da testo,
  • un piccolo client Python ricavato dallo stesso identico request,
  • una chiara comprensione di come il rapporto d'aspetto e le altre opzioni influenzano l'output,
  • e un ciclo di polling per attendere il completamento dell'attività e salvare l'immagine su disco.

Una precisazione sulle aspettative: la generazione di immagini non è istantanea. imagen4-ultra funziona in modo asincrono: si invia un'attività, si ottiene un identificatore dell'attività e si esegue il polling finché il rendering non è completato. Se hai usato altri endpoint asincroni di HiAPI, questo flusso ti sarà familiare; in caso contrario, la sezione sul polling copre l'intero ciclo di vita.

Rimarrà sempre nell'ambito dell'API HiAPI stessa: nessun SDK specifico di un fornitore, nessuna console di terze parti. Un URL di base, una chiave, un formato di richiesta.

Prima di inviare la prima richiesta

Prima che la prima chiamata abbia successo, servono tre cose.

1. Una chiave API

Genera una chiave dalla console del tuo account HiAPI. Trattala come una password: salvala in una variabile d'ambiente, non incollarla direttamente nel file sorgente.

export HIAPI_API_KEY="your-key-here"

2. L'URL di base

Tutte le richieste HiAPI vanno allo stesso host API documentato nella documentazione della piattaforma. Centralizzalo nel codice in un unico punto, così non lo codifichi in più posizioni:

export HIAPI_BASE_URL="https://api.hiapi.ai"

Se il tuo account o la tua regione usano un host diverso, utilizza il valore mostrato nella console: il percorso delle richieste sottostanti rimane invariato.

3. Come si trasmettono le informazioni di autenticazione

HiAPI usa un token bearer nell'intestazione Authorization. Ogni richiesta, sia di invio sia di polling, porta le stesse due intestazioni:

Authorization: Bearer $HIAPI_API_KEY
Content-Type: application/json

L'autenticazione è tutta qui. Nessun passaggio di firma della richiesta, nessuno scambio di token per singola chiamata. Se sai impostare le intestazioni, sai chiamare questa API.

Prima di proseguire, un controllo di base: verifica che la chiave sia stata esportata nella stessa sessione shell in cui eseguirai curl. Una quota considerevole delle segnalazioni di “401 Unauthorized” si riduce, in definitiva, a una chiave esportata in una scheda del terminale e usata in un'altra.

Nel seguito assumeremo sempre che l'identificatore del modello sia imagen4-ultra. Se vuoi verificare la stringa esatta esposta dal tuo account, consulta l'elenco dei modelli nella documentazione.

La richiesta curl eseguibile

Di seguito una richiesta di invio completa. Invia il prompt, imposta il rapporto d'aspetto dell'output e richiede la generazione di una singola immagine.

curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "imagen4-ultra",
    "prompt": "A lone lighthouse on a rocky coast at dusk, long exposure, dramatic clouds, cinematic lighting",
    "aspect_ratio": "16:9",
    "n": 1
  }'

Analisi del corpo della richiesta campo per campo:

  • model —— l'identificatore del modello che stai chiamando. Determina l'instradamento della richiesta; senza di esso, l'API non sa quale modello eseguire.
  • prompt —— la descrizione in linguaggio naturale dell'immagine. È la leva principale che influenza la qualità dell'output. Sii specifico su soggetto, illuminazione, stile e composizione; un prompt vago produrrà solo immagini vaghe.
  • aspect_ratio —— la forma della tela di output, espressa come larghezza:altezza. Ne parleremo in dettaglio più avanti.
  • n —— quante immagini generare con questo invio. Mantienilo a 1 durante i test, così il costo di ogni esecuzione è facile da calcolare.

A seconda della configurazione dell'endpoint, la risposta conterrà l'immagine completata oppure, cosa più comune per questo tipo di modelli, un oggetto attività con un identificatore e un campo di stato. Conserva quell'identificatore: la sezione sul polling dipende da esso.

# Struttura tipica della risposta di invio
{
  "id": "job_abc123",
  "status": "queued"
}

Passa la risposta attraverso uno strumento di formattazione JSON (se disponibile, | jq .), così potrai leggere i nomi dei campi confrontandoti con la risposta del tuo account, senza strizzare gli occhi su un'unica riga.

Scrivere la stessa richiesta in Python

La versione Python è una traduzione riga per riga: stesso URL, stesse intestazioni, stesso corpo della richiesta. Usare requests rende la corrispondenza evidente:

import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ.get("HIAPI_BASE_URL", "https://api.hiapi.ai")

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

payload = {
    "model": "imagen4-ultra",
    "prompt": "A lone lighthouse on a rocky coast at dusk, long exposure, dramatic clouds, cinematic lighting",
    "aspect_ratio": "16:9",
    "n": 1,
}

response = requests.post(
    f"{BASE_URL}/v1/images/generations",
    headers=headers,
    json=payload,
    timeout=30,
)
response.raise_for_status()
job = response.json()
print(job["id"], job["status"])

Quando sposti questo codice in un servizio reale, ci sono alcuni punti che vale la pena mantenere:

  • Leggi la chiave dalle variabili d'ambiente, mai da un valore letterale nel file. La forma os.environ[...] genera un errore esplicito se la variabile manca, ed è proprio ciò che vuoi.
  • Imposta un timeout esplicito per la chiamata di invio. L'attività stessa viene eseguita in modo asincrono, quindi la richiesta HTTP dovrebbe tornare rapidamente; un limite di 30 secondi intercetta i problemi di rete invece di lasciare il programma bloccato.
  • Chiama raise_for_status() prima di toccare il JSON. Il corpo di una risposta 4xx non ha la struttura che ti aspetti; fallire subito fornisce un traceback più chiaro rispetto a un KeyError tre righe dopo.
  • Riusa requests.Session se devi inviare molte attività: il connection pooling conta più di quanto sembri.

Se preferisci httpx o aiohttp, la conversione è meccanica: stesso dizionario headers, stesso corpo JSON, stesso percorso. La richiesta stessa è indipendente dalla libreria HTTP.

Rapporto d'aspetto e opzioni della richiesta

Il rapporto d'aspetto è l'opzione che regoli più spesso, perché cambia sia la composizione sia le dimensioni di output disponibili per il layout a valle.

Il rapporto d'aspetto si passa nel corpo della richiesta come stringa "larghezza:altezza" —— "1:1", "16:9", "9:16", "4:3", "3:2" e così via. Scegli il rapporto che corrisponde all'uso finale dell'immagine:

  • 1:1 —— avatar, riquadri di prodotto, post social che vengono ritagliati in quadrato.
  • 16:9 / 9:16 —— banner hero, miniature video, posizionamenti in formato storia verticale.
  • 4:3 / 3:2 —— composizioni fotografiche classiche, layout a galleria.

Imposta il rapporto in modo consapevole, invece di generare un quadrato e ritagliarlo dopo. Il ritaglio scarta pixel che hai già pagato per generare e può tagliare fuori il soggetto. Se conosci il posizionamento finale, codificalo nella richiesta.

Oltre al rapporto d'aspetto, le opzioni importanti nell'uso quotidiano sono:

  • prompt —— resta l'input con il maggiore impatto. Itera qui prima di iterare su qualsiasi altro aspetto.
  • n —— il numero di immagini generate per ogni invio. Utile quando vuoi più varianti tra cui scegliere; mantienilo basso nella fase di esplorazione del prompt.
  • model —— l'identificatore esatto della variante del modello. Se il tuo account espone più modelli di immagini, questo è l'interruttore tra loro.

Attenersi ai parametri documentati per quell'endpoint, senza indovinare i nomi. I campi sconosciuti sono una causa comune di risposte 400, e le opzioni scritte male sono facili da trascurare in corpi di richiesta di grandi dimensioni. In caso di dubbio, invia prima un corpo minimo —— model, prompt, aspect_ratio —— verifica che funzioni, poi aggiungi un'opzione alla volta.

Polling delle attività asincrone e download del risultato

La generazione di immagini richiede tempo, quindi la chiamata di invio restituisce un'attività, non un'immagine. Il ciclo di vita è: invio → polling dello stato → download dell'output.

Passo 1: invia e cattura l'ID dell'attività

Riusa la richiesta precedente ed estrai id dalla risposta:

job = response.json()
job_id = job["id"]

Passo 2: esegui il polling finché l'attività non raggiunge uno stato terminale

Esegui il polling dell'endpoint di stato con le stesse intestazioni di autenticazione, dormendo tra un tentativo e l'altro. Applica un backoff progressivo per non sovraccaricare l'API:

import time

def wait_for_job(job_id, headers, base_url, timeout=300):
    deadline = time.time() + timeout
    delay = 2
    while time.time() < deadline:
        r = requests.get(
            f"{base_url}/v1/images/generations/{job_id}",
            headers=headers,
            timeout=30,
        )
        r.raise_for_status()
        data = r.json()
        status = data["status"]
        if status == "succeeded":
            return data
        if status == "failed":
            raise RuntimeError(f"job failed: {data}")
        time.sleep(delay)
        delay = min(delay * 2, 15)
    raise TimeoutError(f"job {job_id} not finished within {timeout}s")

Dettagli importanti: una scadenza rigida, un limite massimo sull'intervallo di backoff e un ramo esplicito per lo stato di errore, così le attività problematiche emergono come eccezioni invece di restare appese.

Passo 3: scarica l'immagine

La risposta dell'attività completata contiene la posizione dell'output —— un URL o un riferimento equivalente all'artefatto. Recuperalo e scrivi i byte su disco:

result = wait_for_job(job_id, headers, BASE_URL)
image_url = result["output"][0]["url"]

img = requests.get(image_url, timeout=60)
img.raise_for_status()
with open("lighthouse.png", "wb") as f:
    f.write(img.content)

Due abitudini che evitano la maggior parte degli imprevisti in produzione: scrivi sempre in modalità binaria ("wb"), mai in modalità testo; e considera temporaneo l'URL di download —— salva subito il file nel tuo storage, invece di contare sul fatto che il link resti valido a tempo indefinito.

Errori comuni e come risolverli

La maggior parte dei fallimenti rientra in poche categorie. Ecco come si manifesta ciascuna e come risolverla.

401 Unauthorized

Chiave mancante, formattata male o non visibile al processo che effettua la richiesta.

  • Controlla che l'intestazione sia esattamente Authorization: Bearer <key> —— la parola Bearer, uno spazio, poi la chiave.
  • Verifica che la variabile d'ambiente sia impostata nella stessa shell o nello stesso processo. Nei container e in CI, le variabili esportate nella tua shell locale non passano insieme al codice.
  • Se hai ruotato di recente la chiave, assicurati che quella vecchia non sia ancora memorizzata da qualche parte.

400 Bad Request

Di solito è un problema del corpo della richiesta.

  • Nomi di campo sconosciuti o scritti male —— attieniti ai parametri documentati.
  • Valori di aspect_ratio non accettati dall'endpoint —— usa la forma larghezza:altezza indicata nella documentazione.
  • n fuori dall'intervallo consentito.
  • JSON malformato —— ad esempio una virgola in più, o virgolette non escapate all'interno della stringa del prompt. Se sospetti questo problema, formatta e controlla il corpo della richiesta prima di inviarlo.

Il passo di interrogazione dello stato o di download restituisce 404

L'ID dell'attività è errato, oppure il percorso che stai interrogando non corrisponde all'endpoint usato per l'invio. Alla prima integrazione, registra per intero la risposta di invio e confronta l'ID carattere per carattere.

Timeout del polling

Se wait_for_job raggiunge la scadenza:

  • Verifica di controllare il valore di stato corretto; uno stato terminale che non riconosci apparirà come un blocco.
  • Per rendering grandi e complessi, aumenta il timeout complessivo invece di ridurre l'intervallo di polling.
  • Durante l'integrazione, registra ogni risposta di stato, così puoi capire quanto tempo impiegano effettivamente le attività con la tua combinazione di prompt.

Lo stato dell'attività restituisce failed

Leggi il corpo dell'errore restituito dall'API —— esiste per un motivo. Le attività fallite di solito dipendono dal prompt o dai parametri: la correzione va fatta nella richiesta, non nel codice di polling.

Quando qualcosa non è chiaro, la documentazione HiAPI di quel modello è la fonte autorevole per i nomi dei campi e i valori accettabili. Verifica una modifica alla volta e conserva una richiesta funzionante come riferimento per la prossima integrazione.

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