HiAPI
Блог

Руководство

Как использовать 851-labs/background-remover через hiapi API: curl, Python и рабочий запрос

Sep 5, 2026
Как использовать 851-labs/background-remover через hiapi API: curl, Python и рабочий запрос

851-labs/background-remover превращает фотографию товара, портрет или снимок питомца в прозрачный PNG всего за один вызов API — без промпта, без маски и без настроек соотношения сторон. В этой статье описаны точная структура запроса, рабочие команды curl, Python-скрипт, который можно сразу вставить в бэкенд, и одна ошибка схемы, на которой спотыкаются чаще всего.

Подготовка

  • Аккаунт hiapi и API key, полученный в консоли.
  • Изображение, размещённое по публичному HTTPS URL. Task API принимает URL, а не загрузку файла — если исходник есть только локально, сначала разместите его на любом CDN или в объектном хранилище.

Все запросы отправляются на единый эндпоинт задач:

POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json

Структура запроса (и единственное правило, которое нужно запомнить)

Идентификатор модели — 851-labs/background-remover, передавайте его как есть. У её схемы input есть только одно поле:

Поле Тип Обязательное Описание
image_url string да Должно соответствовать ^https?://[^\s]+$ — прямой URL http(s).

Вот и вся схема. Прежде чем писать код, стоит знать две вещи:

  1. Нет полей prompt, mask, background-color или aspect-ratio. Этот эндпоинт делает одно — разделяет передний и задний план — и ничего больше. Если позже понадобится перекрасить или изменить размер, потребуется вызвать другую модель.
  2. Лишние поля отклоняются, а не игнорируются. Если вы принесёте поле format или size из payload другой модели, задача вернёт 400 INVALID_REQUEST: <root>: additional properties 'format' not allowed ещё до того, как начнётся.

Минимальный рабочий пример: curl

Создание задачи:

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"
    }
  }'

После успешной отправки возвращается id задачи в поле data:

{"code": 200, "data": {"taskId": "tk-hiapi-..."}}

Опрос результата:

curl https://api.hiapi.ai/v1/tasks/tk-hiapi-... \
  -H "Authorization: Bearer sk-<your-key>"

Во время выполнения data.status последовательно проходит queued → handling → archiving. По завершении оно становится "success", а прозрачный PNG появляется в data.output:

{
  "code": 200,
  "data": {
    "status": "success",
    "output": [{"url": "https://.../result.png", "expireAt": "..."}]
  }
}

URL вывода действует недолго (обратите внимание на expireAt). Сразу после успеха задачи скачайте байты файла — не делайте hotlink и не сохраняйте исходный URL надолго.

Python для продакшена: создание, опрос, скачивание

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. 创建任务
    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. 轮询直到进入终态
    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. 立即下载 —— URL 会过期
            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)")

Удаление фона — лёгкая задача обработки изображений и обычно завершается задолго до 300-секундного дедлайна — этот таймаут служит страховкой, а не ожидаемым временем выполнения.

Callback вместо опроса

Для веб-бэкенда рекомендуется регистрировать callback при создании задачи, а не опрашивать в обработчике запроса. Объект callback находится на верхнем уровне, рядом с 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 поддерживает только "final" — вы получите ровно один POST, когда задача перейдёт в success или fail, без событий о ходе выполнения. Обработчик должен использовать taskId в качестве ключа, чтобы повторные доставки webhook не обрабатывались дважды, и периодически проходить по GET /v1/tasks/<id>, проверяя id, которые ваш эндпоинт так и не подтвердил.

Обработка ошибок: те, что действительно важны

400 INVALID_REQUEST при создании — сообщение об ошибке укажет точное поле:

Сообщение Причина
invalid input: image_url: missing required field "image_url" input пуст или имя ключа написано с ошибкой
image_url: 'not-a-url' does not match pattern '^https?://[^\s]+$' Значение не является корректным URL http(s)
<root>: additional properties 'format' not allowed Вы отправили поле, которое эта модель не принимает

Эти ошибки постоянные — повтор одной и той же payload будет вечно завершаться неудачей. Исправьте поле и отправьте заново.

401 permission_denied при создании — проблема в самом ключе, а не в теле запроса:

{"error": {"code": "permission_denied", "message": "...", "request_id": "...", "type": "hiapi_error"}}

Проверьте права ключа на модель в консоли.

Задача вернула status: "fail" — создание прошло успешно, но само выполнение не удалось (обычно бэкенд не смог получить image_url). Прочитайте data.error.code / message; такие сбои безопасно повторить один раз с задержкой.

GET по неизвестному или истёкшему id задачи вернёт 404 с содержимым {"code": 404, "data": null, "message": "task not found"} — при любой сверке считайте это терминальным состоянием, а не «всё ещё в ожидании».

Что дальше

Частые вопросы

Нужен ли промпт? Нет. Достаточно указать image_url, и модель сама отделит передний план от фона.

Вывод действительно прозрачный? Да — результат представляет собой PNG с альфа-каналом, который можно сразу наложить на любой фон.

Можно ли в том же вызове изменить соотношение сторон, цвет или фон? Нет. Этот эндпоинт только удаляет фон. Для перекраски, изменения размера или замены фона используйте прозрачный PNG как вход и вызовите следом модель редактирования изображений.

Почему я получаю «additional properties '...' not allowed»? Схема принимает только одно поле — image_url. Любое поле, принесённое из payload другой модели — format, size, background_color, любое, — будет отклонено сразу, а не молча проигнорировано.

Как сохранять результат? Скачивайте сразу после того, как задача достигла status: "success". URL вывода — подписанный и содержит expireAt; для долговременного hotlink он не подходит.

Сколько это стоит? Оплата за каждое изображение. Актуальный тариф смотрите на странице цен.

Похожие статьи

Все статьи →

Начните работать с постоянными артефактами ИИ

Получите API-ключ и вызывайте модели изображений, видео и аудио через один API на основе tasks.

Читать документацию API