Tutoriale
Come usare 851-labs/background-remover tramite l'API hiapi: curl, Python e richieste funzionanti
851-labs/background-remover trasforma una singola chiamata API una foto di prodotto, un ritratto o un animale domestico in un PNG trasparente — senza prompt, senza maschere, senza impostazioni di proporzioni. Questo articolo descrive la struttura esatta della richiesta, un comando curl funzionante, uno script Python pronto da inserire nel backend e l'errore di schema che manda più spesso le persone fuori strada.
Preparazione
- Un account hiapi e una chiave API ottenuta dalla console.
- Un'immagine ospitata su un URL HTTPS pubblico. L'API dei task riceve URL, non caricamenti di file — se la tua immagine di origine esiste solo in locale, prima caricala su un qualsiasi CDN o storage a oggetti.
Tutte le richieste vengono inviate all'endpoint unificato dei task:
POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json
Struttura della richiesta (e l'unica regola da ricordare)
L'id del modello è 851-labs/background-remover, da passare così com'è. Il suo schema input ha un solo campo:
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
image_url |
string | Sì | Deve corrispondere a ^https?://[^\s]+$ — un URL http(s) direttamente accessibile. |
Questo è l'intero schema. Prima di scrivere qualsiasi codice, val la pena sapere due cose:
- Non esistono campi prompt, mask, background-color o aspect-ratio. Questo endpoint fa una sola cosa — separazione primo piano/sfondo — e nient'altro. Se in seguito hai bisogno di ricolorare o ridimensionare, dovrai chiamare un altro modello.
- I campi in eccesso vengono rifiutati, non ignorati. Se trascini un campo
formatosizedal payload di un altro modello, il task restituirà400 INVALID_REQUEST: <root>: additional properties 'format' not allowedancora prima di iniziare.
Esempio minimo funzionante: curl
Creazione del task:
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "851-labs/background-remover",
"input": {
"image_url": "https://your-cdn.example.com/product-shot.jpg"
}
}'
Dopo l'invio riuscito viene restituito un id del task, all'interno di data:
{"code": 200, "data": {"taskId": "tk-hiapi-..."}}
Polling del risultato:
curl https://api.hiapi.ai/v1/tasks/tk-hiapi-... \
-H "Authorization: Bearer sk-<your-key>"
Durante l'esecuzione, data.status attraversa in sequenza queued → handling → archiving. Al termine diventa "success" e il PNG trasparente appare in data.output:
{
"code": 200,
"data": {
"status": "success",
"output": [{"url": "https://.../result.png", "expireAt": "..."}]
}
}
L'URL di output è valido per breve tempo (nota expireAt). Dopo il successo del task, scarica subito i byte del file — non fare hotlink né conservare l'URL originale a lungo termine.
Python pronto per la produzione: invio, polling, download
import time
import requests
API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def remove_background(image_url: str) -> bytes:
# 1. Crea il task
resp = requests.post(API_BASE, headers=HEADERS, json={
"model": "851-labs/background-remover",
"input": {"image_url": image_url},
}, timeout=60)
body = resp.json()
if resp.status_code != 200 or not (body.get("data") or {}).get("taskId"):
raise RuntimeError(f"create failed [{resp.status_code}]: {body}")
task_id = body["data"]["taskId"]
# 2. Esegui il polling fino allo stato terminale
deadline = time.time() + 300
while time.time() < deadline:
task = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS,
timeout=30).json().get("data") or {}
if task.get("status") == "success":
outputs = task.get("output") or []
if not outputs or not outputs[0].get("url"):
raise RuntimeError(f"task {task_id} succeeded but returned no output URL")
# 3. Scarica subito — l'URL scade
png = requests.get(outputs[0]["url"], timeout=120)
png.raise_for_status()
return png.content
if task.get("status") == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
time.sleep(3)
raise TimeoutError(f"task {task_id} still running after 300s")
if __name__ == "__main__":
png = remove_background("https://your-cdn.example.com/product-shot.jpg")
with open("cutout.png", "wb") as f:
f.write(png)
print(f"saved cutout.png ({len(png)} bytes)")
La rimozione dello sfondo è un task immagini leggero e di solito si completa ben prima della scadenza di 300 secondi — quel timeout è solo una rete di sicurezza, non il tempo di esecuzione previsto.
Usare i callback invece del polling
Per i backend web, conviene registrare un callback al momento della creazione del task invece di fare polling nel gestore delle richieste. L'oggetto callback è al livello superiore, allo stesso livello di model:
{
"model": "851-labs/background-remover",
"input": { "image_url": "https://your-cdn.example.com/product-shot.jpg" },
"callback": {
"url": "https://your-app.example.com/hooks/hiapi",
"when": "final"
}
}
callback.when supporta solo "final" — riceverai esattamente un POST quando il task raggiunge success o fail, non eventi di avanzamento. Il gestore dovrebbe usare taskId come chiave per evitare di elaborare più volte webhook consegnati in modo duplicato, e scansionare periodicamente GET /v1/tasks/<id> per controllare gli id che il tuo endpoint non ha mai confermato.
Gestione degli errori: quelli che contano davvero
400 INVALID_REQUEST alla creazione — il messaggio di errore indica il campo esatto:
| Messaggio | Causa |
|---|---|
invalid input: image_url: missing required field "image_url" |
input è vuoto, oppure il nome della chiave è scritto male |
image_url: 'not-a-url' does not match pattern '^https?://[^\s]+$' |
Il valore non è un URL http(s) ben formato |
<root>: additional properties 'format' not allowed |
Hai inviato un campo che il modello non accetta |
Questi errori sono permanenti — riprovare lo stesso payload fallirà sempre. Correggi il campo e invia di nuovo.
401 permission_denied alla creazione — il problema è la chiave stessa, non il corpo della richiesta:
{"error": {"code": "permission_denied", "message": "...", "request_id": "...", "type": "hiapi_error"}}
Controlla nella console i permessi del modello per quella chiave.
Il task restituisce status: "fail" — la creazione è riuscita ma l'esecuzione stessa è fallita (di solito perché il backend non riesce a recuperare image_url). Leggi data.error.code / message; questi errori possono essere ritentati in sicurezza una volta con backoff.
Un GET su un id di task sconosciuto o scaduto restituisce 404 con {"code": 404, "data": null, "message": "task not found"} — in qualsiasi scansione di riconciliazione va trattato come stato terminale, non come "ancora in attesa".
Prossimi passi
- Pagina del modello 851-labs/background-remover — esempi live e prezzo attuale.
- Rimuovere lo sfondo di un'immagine con un editing basato su prompt — un'alternativa basata su Seedream, per i casi in cui non devi solo rimuovere lo sfondo ma cambiarlo.
- Documentazione dell'API asincrona dei task di hiapi — riferimento completo per creazione/polling/callback.
- Documentazione sull'autenticazione di hiapi — configurazione della chiave API e formato degli header.
- Prezzi — le tariffe attuali per immagine.
Domande frequenti
Mi serve un prompt?
No. Basta fornire un image_url e il modello separa da solo primo piano e sfondo.
L'output è davvero trasparente? Sì — il risultato è un PNG con canale alpha, compositabile direttamente su qualsiasi sfondo.
Posso cambiare proporzioni, colore o sfondo nella stessa chiamata? No. Questo endpoint rimuove solo lo sfondo. Se ti serve ricolorare, ridimensionare o sostituire lo sfondo, usa questo PNG trasparente come input e concatena uno o più modelli di editing di immagini.
Perché ricevo "additional properties '...' not allowed"?
Lo schema accetta un solo campo: image_url. Qualsiasi campo trascinato dal payload di un altro modello — format, size, background_color, qualsiasi cosa — viene rifiutato direttamente, non ignorato silenziosamente.
Come devo salvare il risultato?
Scaricalo subito dopo che il task raggiunge status: "success". L'URL di output è un URL firmato con expireAt; non è adatto all'hotlink a lungo termine.
Quanto costa? Il costo è a consumo per immagine. Consulta le tariffe attuali sulla 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