Tutoriale
Come usare gpt-image-2 image-to-image tramite l'API hiapi
Una ricetta di codice eseguibile che ti mostra come chiamare l'endpoint image-to-image di gpt-image-2 su hiapi: envelope della richiesta, immagine di riferimento e parametro aspect_ratio, scelta tra polling e callback, e esempi curl, Python e Node.js pronti da copiare e incollare.
Questa ricetta ti guiderà passo dopo passo su come chiamare la modalità image-to-image di gpt-image-2 tramite l'API unificata delle attività di hiapi. Otterrai un esempio curl eseguibile, uno script Python da integrare direttamente nel backend, una versione Node.js adatta agli scenari serverless, e i parametri che contano davvero più i dettagli che causano problemi in produzione.
Alla fine di questo articolo avrai uno script che riceve l'URL di un'immagine di riferimento e un prompt, e restituisce l'URL di un'immagine generata che puoi scaricare direttamente o affidare al tuo livello di archiviazione.
Preparazione
- Un account hiapi e una chiave API. Puoi ottenerli nella console hiapi.
- Un'immagine di riferimento ospitata su un URL HTTPS pubblico (oppure un data URL base64 — entrambi vanno bene).
- Un prompt testuale che descriva cosa vuoi che il modello faccia con quell'immagine di riferimento.
Tutto qui. Nessun SDK da installare — hiapi è solo HTTP + JSON, qualsiasi linguaggio in grado di inviare richieste POST può essere usato.
Vuoi prima capire la generazione di immagini da solo testo? Consulta Come generare immagini con l'API hiapi. Lo schema sottostante è lo stesso flusso di attività asincrono, con in più un campo
image.
Chiamata minima funzionante
hiapi espone tutti i modelli di immagini tramite la stessa interfaccia di attività asincrona:
POST /v1/tasks— invia l'attività, restituisce untaskId.- Esegui il polling di
GET /v1/tasks/{taskId}finchéstatus === "success", oppure forniscicallback.urlper ricevere il risultato finale via webhook. - Leggi l'URL dell'immagine da
data.output[0].urle scaricala o archiviala.
curl
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2/image-to-image",
"input": {
"prompt": "transform the subject into a watercolor painting, soft pastel palette",
"image": "https://example.com/reference.jpg",
"aspect_ratio": "1:1",
"resolution": "1K"
}
}'
La risposta immediata ti fornisce l'id dell'attività:
{ "data": { "taskId": "task_01HXXXX..." } }
Poi esegui il polling del risultato:
curl https://api.hiapi.ai/v1/tasks/task_01HXXXX... \
-H "Authorization: Bearer sk-YOUR_KEY"
Quando l'attività è pronta, la risposta è simile a questa:
{
"data": {
"status": "success",
"output": [{ "url": "https://cdn.hiapi.ai/...png", "expireAt": "..." }]
}
}
output[0].url ha una validità limitata nel tempo (nota il campo expireAt), quindi scaricala subito o ricaricala nel tuo archivio — non fornire mai un hotlink agli utenti finali.
I parametri che contano davvero
| Campo | Tipo | Descrizione |
|---|---|---|
model |
string | Usa l'id semplice gpt-image-2/image-to-image. Non aggiungere il prefisso models/. |
input.prompt |
string | La trasformazione che vuoi applicare all'immagine di riferimento. |
input.image |
string | URL HTTPS oppure URL data:image/...;base64,.... |
input.aspect_ratio |
string | Uno dei seguenti valori: 1:1, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 16:9, 9:16, 21:9 o auto. |
input.resolution |
string | 1K, 2K o 4K. Predefinito 1K. |
Due comportamenti importanti:
- Alcuni modelli hiapi accettano solo
aspect_ratio(senzaresolution); altri richiedono dimensioni in pixel. gpt-image-2/image-to-image accetta la combinazioneaspect_ratio+resolutionmostrata sopra — non passare quisize: "1024x1024". - Il campo
imageè l'immagine di riferimento. Se passi un data URL base64, assicurati che il payload sia sotto il limite del corpo della richiesta della tua piattaforma (qualche MB va bene, immagini di più megabyte dovrebbero essere prima caricate e poi passate come URL).
Script Python di livello produttivo
Questa versione gestisce il polling con una scadenza e termina in modo pulito in caso di fallimento:
import os
import time
import requests
API = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
def submit(prompt: str, image_url: str, aspect_ratio: str = "1:1") -> str:
payload = {
"model": "gpt-image-2/image-to-image",
"input": {
"prompt": prompt,
"image": image_url,
"aspect_ratio": aspect_ratio,
"resolution": "1K",
},
}
r = requests.post(API, headers=HEADERS, json=payload, timeout=30)
r.raise_for_status()
return r.json()["data"]["taskId"]
def wait(task_id: str, timeout_s: int = 300, interval_s: int = 5) -> str:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=20)
r.raise_for_status()
task = r.json()["data"]
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
time.sleep(interval_s)
raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")
if __name__ == "__main__":
task_id = submit(
prompt="transform the subject into a watercolor painting, soft pastel palette",
image_url="https://example.com/reference.jpg",
)
print("task:", task_id)
print("url:", wait(task_id))
Esegui con HIAPI_API_KEY=sk-... python recipe.py.
Node.js (fetch, senza dipendenze)
const API = "https://api.hiapi.ai/v1/tasks";
const TOKEN = process.env.HIAPI_API_KEY;
const headers = {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
};
async function submit(prompt, imageUrl, aspectRatio = "1:1") {
const r = await fetch(API, {
method: "POST",
headers,
body: JSON.stringify({
model: "gpt-image-2/image-to-image",
input: { prompt, image: imageUrl, aspect_ratio: aspectRatio, resolution: "1K" },
}),
});
const data = await r.json();
if (!r.ok) throw new Error(JSON.stringify(data));
return data.data.taskId;
}
async function wait(taskId, timeoutMs = 300000, intervalMs = 5000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const r = await fetch(`${API}/${taskId}`, { headers });
const task = (await r.json()).data;
if (task.status === "success") return task.output[0].url;
if (task.status === "fail") throw new Error(JSON.stringify(task.error));
await new Promise((res) => setTimeout(res, intervalMs));
}
throw new Error(`task ${taskId} timed out`);
}
(async () => {
const id = await submit(
"transform the subject into a watercolor painting, soft pastel palette",
"https://example.com/reference.jpg",
);
console.log("task:", id, "\nurl:", await wait(id));
})();
Polling vs. callback
Eseguire il polling ogni 5 secondi va bene per uno script una tantum, ma occupa un worker per tutta la durata dell'attività. In un backend reale di solito vuoi un webhook:
{
"model": "gpt-image-2/image-to-image",
"input": { "prompt": "...", "image": "https://example.com/reference.jpg" },
"callback": { "url": "https://your-app.example.com/api/hiapi-callback", "when": "final" }
}
Quando l'attività si conclude (con successo o fallimento), hiapi invia tramite POST a quell'URL lo stesso payload che ottieni da GET /v1/tasks/{id}. Considera quel gestore come idempotente — i retry sono possibili — e verifica prima di fidarti della richiesta (un token di firma tuo nell'URL, controllo dell'header Authorization, ecc.).
Un pattern pulito è: invia l'attività, persisti il taskId con la tua job id come chiave, restituisci 202 Accepted al chiamante, e lascia che il webhook si occupi di archiviazione e notifica.
Gestione degli errori
In pratica incontrerai tre modalità di fallimento:
401 permission_deniedcon"This API key cannot use the selected model."— la chiave non è autorizzata a usaregpt-image-2/image-to-image. Controlla nella console hiapi e verifica nella pagina dei prezzi che il modello sia incluso nel tuo piano.400conadditional properties not allowed— hai inviato un campo che quel modello specifico non accetta (ad esempiosizeinvece diaspect_ratio). Il messaggio di errore indica la chiave non valida; rimuovila e riprova.status: "fail"durante il polling con un oggettodata.error— il modello stesso ha rifiutato l'input (contenuto non sicuro, URL di riferimento non raggiungibile, ecc.). Registra nei logerror.codeeerror.message, non riprovare automaticamente alla cieca.
Imposta sempre un timeout per la chiamata a POST /v1/tasks (30 secondi sono sufficienti — restituisce rapidamente il taskId), e un timeout separato e più lungo per il ciclo di polling o per il percorso di ricezione del webhook.
Link correlati
- Pagina del modello gpt-image-2 — matrice delle capacità e livelli di prezzo.
- Tutti i modelli hiapi — se ti serve un altro modello di immagini o video, qui c'è il catalogo completo.
- Documentazione API — riferimento completo di
/v1/taskse dell'intera superficie dell'interfaccia. - Come generare immagini con l'API hiapi — il complemento text-to-image di questa ricetta.
Domande frequenti
D: gpt-image-2/image-to-image supporta più immagini di riferimento?
R: Il contratto minimo usa un singolo campo image. Se il tuo caso d'uso richiede più immagini di riferimento (ad esempio un'immagine del soggetto + un'immagine di stile), combinale prima in una sola, oppure consulta la pagina del modello per i campi supportati più recenti.
D: Posso passare un file locale invece di un URL?
R: Sì — codificalo come URL data:image/png;base64,... e passalo come input.image. Per file superiori a circa 3 MB, caricali prima nel tuo archivio e passa un URL pubblico; è più veloce ed evita i limiti del corpo della richiesta.
D: Quanto tempo richiede un'attività?
R: La maggior parte delle attività image-to-image di gpt-image-2 si completa in 10–30 secondi con risoluzione 1K. Risoluzioni più alte e prompt complessi possono richiedere più tempo — per sicurezza, imposta il timeout di polling a 5 minuti.
D: Come posso controllare quanto l'output differisce dall'immagine di riferimento? R: Esprimilo esplicitamente nel prompt. "Keep the subject's pose and composition, only restyle to watercolor" produce una coerenza più stretta rispetto a "make this a watercolor". La modalità image-to-image di gpt-image-2 è guidata dal prompt — nell'envelope della richiesta non c'è un cursore "strength" separato.
D: output[0].url è permanente?
R: No. Ha un timestamp expireAt (di solito qualche ora). Dopo il successo dell'attività, scarica i byte il prima possibile e caricali nel tuo archivio (R2, S3, ecc.).
D: Quanto costa ogni immagine? R: Dipende dal tuo piano e dalla risoluzione. Il costo attuale per chiamata è nella pagina dei prezzi.
Articoli correlati
Vedi tutti gli articoli →-
Tutoriale
Come chiamare hailuo-2.3-fast/image-to-video tramite l'API HiAPI: pratica con curl e Python
La prima richiesta funzionante per il livello image-to-video veloce ed economico — dall'ID del modello al download di un MP4
-
Tutoriale
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
-
Tutoriale
Utilizzare Kandinsky 6.0 Pro su HiAPI per la generazione di video da testo: tutorial con curl e Python
Dimostrazione pratica guidata dalla richiesta: costruire la chiamata da prompt a clip video, inviare la richiesta, monitorare lo stato di completamento e scaricare il risultato