HiAPI
Blog

Tutoriale

Come usare 851-labs/background-remover tramite l'API hiapi: curl, Python e richieste funzionanti

Sep 5, 2026
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:

  1. 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.
  2. I campi in eccesso vengono rifiutati, non ignorati. Se trascini un campo format o size dal payload di un altro modello, il task restituirà 400 INVALID_REQUEST: <root>: additional properties 'format' not allowed ancora 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

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.

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