HiAPI
Blog

Tutoriale

Come usare l'API wan2.7-image-standard su hiapi: generazione di immagini da testo e modifica con immagini di riferimento

Oct 21, 2026
Come usare l'API wan2.7-image-standard su hiapi: generazione di immagini da testo e modifica con immagini di riferimento

wan2.7-image-standard è la fascia standard del modello Tongyi Wanxiang Wan 2.7 Image. Il motivo per cui merita una pagina dedicata è questo: un unico ID modello supporta sia la generazione di immagini da testo sia la modifica di immagini basata su immagini di riferimento, con supporto fino a 2K, a un prezzo fisso di $0.0345 per immagine — più economico della fascia Pro che supporta il 4K. Questa guida fornisce una richiesta eseguibile subito, lo schema di input preciso (verificato contro l'API online), il percorso di modifica con immagini di riferimento e i comportamenti limite che devi gestire in produzione.

Tutto ciò che riguarda lo schema e la sezione sugli errori qui sotto è stato confermato interrogando l'endpoint /v1/tasks online durante la stesura — gli elenchi di valori ammessi, l'insieme dei campi accettati e la forma delle risposte di errore sono citati da risposte reali dell'API, non a memoria.

Cosa costruirai e cosa ti serve

Invierai un prompt (facoltativamente con immagini di riferimento), eseguirai il polling fino al completamento dell'attività, poi scaricherai l'immagine. Prima di tutto ti serve una cosa: una API key ottenuta dalla guida rapida di hiapi, esportata come HIAPI_API_KEY. Non esiste un percorso senza key — ogni richiesta si autentica tramite Authorization: Bearer sk-<your-key>.

wan2.7-image-standard funziona sull'API di attività asincrone di hiapi: prima fai POST /v1/tasks per creare l'attività, poi esegui il polling dell'endpoint di dettaglio finché non riporta lo stato terminale.

Generazione di immagini da testo: richiesta minima

Crea l'attività:

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.7-image-standard",
    "input": {
      "prompt": "Alle ore blu dopo la pioggia, in un vicolo silenzioso e deserto c'è un piccolo laboratorio di ceramica, con lanterne di carta calde appese, una teiera smaltata in vetrina, luci riflesse sulla pavimentazione bagnata, una bicicletta appoggiata al muro, fotografia cinematografica 35mm, alto livello di dettaglio",
      "aspect_ratio": "16:9",
      "resolution": "2K"
    }
  }'

L'ID attività nella risposta si trova in data.taskId:

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

Poi esegui il polling di GET /v1/tasks/<taskId> finché data.status non è success, e leggi l'URL dell'immagine da data.output[0].url:

import os, time, requests

API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}

def generate(prompt, aspect_ratio="16:9", resolution="2K", image_urls=None, timeout=600):
    payload = {"model": "wan2.7-image-standard",
               "input": {"prompt": prompt,
                         "aspect_ratio": aspect_ratio,
                         "resolution": resolution}}
    if image_urls:                      # modifica con immagini di riferimento (vedi sezione successiva)
        payload["input"]["image_urls"] = image_urls

    create = requests.post(API, headers=HEADERS, json=payload).json()
    if create.get("code") != 200:       # errore di validazione sincrono (es. valore enum non valido)
        raise RuntimeError(create)
    task_id = create["data"]["taskId"]

    deadline = time.time() + timeout
    while time.time() < deadline:
        data = requests.get(f"{API}/{task_id}", headers=HEADERS).json()["data"]
        if data["status"] == "success":
            return requests.get(data["output"][0]["url"]).content
        if data["status"] == "fail":    # errore terminale — non continuare il polling
            raise RuntimeError(data.get("error"))
        time.sleep(5)
    raise TimeoutError(task_id)

png = generate("...")   # salva subito i byte — vedi la nota sulla scadenza più sotto

aspect_ratio e resolution sono entrambi facoltativi (il modello ha valori predefiniti), ma impostali esplicitamente — resolution accetta solo 1K o 2K, e entrambi hanno lo stesso prezzo, quindi non c'è motivo economico per lasciarlo al valore predefinito.

Modifica basata su immagini di riferimento: stesso ID modello, più image_urls

Qui sta la differenza tra la fascia standard e quella Pro. Passa le immagini di riferimento in image_urls (un array, fino a 9 immagini di riferimento secondo le specifiche del modello), e il modello le modificherà o le ricomporrà seguendo comunque il tuo prompt testuale:

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.7-image-standard",
    "input": {
      "prompt": "Posiziona questo prodotto su un piano cucina in marmo illuminato dal sole, con erbe fresche accanto, luce morbida del mattino, fotografia di prodotto lifestyle",
      "image_urls": ["https://your-storage.example.com/product.jpg"],
      "resolution": "2K"
    }
  }'

In Python, è il parametro image_urls=[...] passato alla funzione helper sopra — il resto non cambia. Anche quando passi immagini di riferimento, prompt resta obbligatorio (l'API rifiuta le richieste senza prompt: missing required field "prompt").

Il nome del campo è importante: è image_urls. I nomi alternativi apparentemente plausibili — reference_image_urls, image_input, input_urls — vengono tutti rifiutati dallo schema con additional properties '<name>' not allowed. Se stai portando codice da endpoint di modifica di altri modelli, questo è il primo punto da correggere.

Lo schema di input preciso

Lo schema è rigido: qualsiasi campo non presente nell'elenco seguente restituisce 400 INVALID_REQUEST con additional properties '<name>' not allowed. Ecco tutti i campi che accetta:

Campo Tipo Obbligatorio Descrizione
prompt string Sì Obbligatorio sia per la generazione da testo sia per la modifica. Può essere in inglese o cinese.
aspect_ratio string enum No Uno dei valori: 1:1, 16:9, 4:3, 21:9, 3:4, 9:16, 8:1, 1:8. Qualsiasi altro valore (es. 3:2) → 400.
resolution string enum No Solo 1K o 2K. Questa fascia non supporta il 4K.
image_urls string[] No Immagini di riferimento per la modifica (fino a 9). Passandole si passa alla modalità riferimento.
seed integer No Per output riproducibili.

Campi che potresti aspettarti ma che questo modello non accetta: negative_prompt, n, size e prompt_optimizer vengono tutti rifiutati come proprietà sconosciute. Non esiste un parametro batch (n) — invia un'attività per ogni immagine.

Note per la produzione e comportamenti verificati

Un 200 in fase di invio non significa che l'immagine verrà generata. wan2.7-image-standard valida i valori enum in modo sincrono (un resolution o aspect_ratio errato fa fallire immediatamente la POST con 400 INVALID_REQUEST), ma non valida gli URL di riferimento al momento dell'invio. Voci image_urls malformate o irraggiungibili vengono accettate, restituendo 200 e un taskId, poi l'attività fallisce dopo circa un secondo. L'ho verificato direttamente: un'attività creata con URL di riferimento non validi restituisce questo stato terminale

{ "status": "fail", "error": { "code": "INVALID_REQUEST", "message": "invalid request parameters for this model" } }

La conseguenza pratica: esegui sempre il polling fino allo stato terminale e gestisci il ramo data.status == "fail" (leggendo data.error). Le attività fallite sono riportate come HTTP 200 con data.status: "fail" — le informazioni di errore sono in data.error, non in un errore HTTP di livello superiore. Prima di inviare, assicurati che i tuoi URL di riferimento siano accessibili pubblicamente.

Scarica subito l'output. data.output[0].url è un link temporaneo con un timestamp expireAt, non una risorsa CDN permanente. Recupera i byte e trasferiscili nel tuo storage nel momento stesso in cui l'attività va a buon fine; gli URL scaduti restituiscono 404. Se hai già riscontrato questo problema, vedi perché i tuoi URL di output di hiapi restituiscono 404 e come gestirlo.

Polling vs. callback. L'esempio sopra esegue il polling ogni cinque secondi, il che va bene per script e piccoli lotti. Per il throughput di produzione, aggiungi callback nella richiesta di creazione, così hiapi ti notifica all'evento di stato terminale invece di mantenere tu la connessione — i dettagli del meccanismo sono nella documentazione sulla creazione delle attività.

Standard vs. Pro: quale fascia chiamare

hiapi ospita due fasce di Wan 2.7 Image, che sono ID modello distinti, non parametri:

  • wan2.7-image-standard (questa guida) — generazione da testo e modifica con immagini di riferimento, 1K/2K, con prezzo fisso di $0.0345 per immagine indipendentemente dalla risoluzione.
  • wan2.7-image/text-to-image — fascia Pro: solo generazione da testo, fino a 4K, prezzo fisso di $0.08 per immagine. Vedi la pagina di Wan 2.7 Image Pro e la guida dettagliata sulla generazione di immagini di prodotto e-commerce in 4K.

Scegli la fascia standard quando ti serve la modifica basata su immagini di riferimento, oppure quando il 2K è sufficiente e vuoi pagare meno della metà del prezzo per immagine della Pro. Usa la Pro solo quando ti serve specificamente l'output nativo in 4K — è l'unica cosa che la fascia standard non può fare. I prezzi attuali di entrambe sono nella pagina dei prezzi.

Domande frequenti

wan2.7-image-standard supporta la modifica delle immagini o solo la generazione da testo? Entrambe, dallo stesso ID modello. Aggiungi l'array image_urls per passare alla modifica basata su immagini di riferimento; omettilo per la pura generazione da testo.

Qual è la risoluzione massima? 2K. Il campo resolution accetta solo 1K e 2K; l'API online rifiuta qualsiasi altro valore. Se ti serve il 4K, usa la fascia Pro (wan2.7-image/text-to-image).

Perché la mia attività ha restituito 200 e poi è fallita? Gli URL di riferimento non vengono controllati al momento dell'invio — solo in fase di esecuzione. Voci image_urls irraggiungibili o malformate creano l'attività (HTTP 200), poi falliscono con stato terminale INVALID_REQUEST. Esegui il polling di data.status e verifica che i tuoi URL siano pubblici.

Posso impostare un prompt negativo? No. negative_prompt non è un campo accettato da questo modello (nemmeno n, size o prompt_optimizer). Guida tramite il prompt positivo e seed.

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