튜토리얼
hiapi API로 851-labs/background-remover 사용하는 방법: curl, Python 및 실행 가능한 요청
851-labs/background-remover는 단 한 번의 API 호출로 상품, 인물, 반려동물 사진을 투명 PNG로 변환합니다 — 프롬프트도, 마스크도, 가로세로 비율 설정도 필요 없습니다. 이 글에서는 정확한 요청 구조, 실행 가능한 curl 명령, 백엔드에 바로 넣을 수 있는 Python 스크립트, 그리고 가장 많은 사람이 실수하는 스키마 오류 하나를 소개합니다.
준비 작업
- hiapi 계정과 콘솔에서 발급받은 API key.
- 공개 HTTPS URL로 호스팅된 이미지. 작업 API는 파일 업로드가 아니라 URL을 받습니다 — 원본 이미지가 로컬에만 있다면 먼저 임의의 CDN이나 오브젝트 스토리지에 올리세요.
모든 요청은 통합 작업 엔드포인트로 전송됩니다:
POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json
요청 구조 (그리고 반드시 기억해야 할 단 하나의 규칙)
모델 id는 851-labs/background-remover이며, 그대로 전달하면 됩니다. 이 모델의 input 스키마에는 필드가 하나뿐입니다:
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
image_url |
string | 예 | ^https?://[^\s]+$와 일치해야 합니다 — 직접 접근 가능한 http(s) URL. |
이것이 스키마의 전부입니다. 코드를 작성하기 전에 알아둘 점이 두 가지 있습니다:
- prompt, mask, background-color, aspect-ratio 필드가 없습니다. 이 엔드포인트는 오직 한 가지 일 — 전경/배경 분리 — 만 하며, 그 외에는 아무것도 하지 않습니다. 이후에 다시 채색하거나 크기를 조정해야 한다면 다른 모델을 추가로 호출해야 합니다.
- 잉여 필드는 무시되지 않고 거부됩니다. 다른 모델의 payload에서 가져온
format이나size필드를 포함하면, 작업이 시작되기도 전에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"
}
}'
성공적으로 제출되면 data 안에 작업 id가 반환됩니다:
{"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에 주목하세요). 작업이 성공하면 즉시 파일 바이트를 다운로드하세요 — 원본 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 객체는 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"만 지원합니다 — 작업이 success 또는 fail 상태가 되면 정확히 한 번 POST를 받으며, 진행 이벤트는 받지 않습니다. 핸들러는 taskId를 키로 사용해 중복 전달된 webhook이 중복 처리되지 않도록 하고, 엔드포인트가 확인하지 못한 id는 주기적으로 GET /v1/tasks/<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]+$' |
값이 올바른 형식의 http(s) URL이 아님 |
<root>: additional properties 'format' not allowed |
이 모델이 허용하지 않는 필드를 전송함 |
이 오류들은 영구적입니다 — 동일한 payload로 재시도하면 영원히 실패합니다. 필드를 수정한 뒤 다시 전송하세요.
생성 시 401 permission_denied — 문제는 요청 본문이 아니라 key 자체에 있습니다:
{"error": {"code": "permission_denied", "message": "...", "request_id": "...", "type": "hiapi_error"}}
콘솔에서 해당 key의 모델 권한을 확인하세요.
작업이 status: "fail" 반환 — 생성은 성공했지만 실행 자체가 실패한 경우(보통 백엔드가 image_url을 가져오지 못함)입니다. data.error.code / message를 읽으세요. 이런 실패는 백오프를 두고 한 번 재시도해도 안전합니다.
알 수 없거나 만료된 작업 id를 GET하면 404와 함께 {"code": 404, "data": null, "message": "task not found"}가 반환됩니다 — 어떤 대조 스캔에서든 이를 "아직 대기 중"이 아니라 최종 상태로 취급해야 합니다.
다음 단계
- 851-labs/background-remover 모델 페이지 — 실시간 예제와 현재 가격.
- 프롬프트 기반 편집으로 이미지 배경 제거하기 — 배경을 제거할 뿐 아니라 변경해야 하는 경우에 적합한 Seedream 기반 대안.
- hiapi 비동기 작업 API 문서 — 생성/폴링/콜백 전체 레퍼런스.
- hiapi 인증 문서 — API key 설정과 요청 헤더 형식.
- 가격 — 현재 이미지당 요금.
자주 묻는 질문
프롬프트가 필요한가요?
아니요. image_url만 제공하면 모델이 전경과 배경을 스스로 분리합니다.
출력이 정말 투명한가요? 예 — 결과는 알파 채널이 있는 PNG이며, 어떤 배경에도 바로 합성할 수 있습니다.
같은 호출에서 가로세로 비율, 색상, 배경을 변경할 수 있나요? 아니요. 이 엔드포인트는 배경만 제거합니다. 다시 채색하거나, 크기를 조정하거나, 배경을 교체하려면 이 투명 PNG를 입력으로 사용해 이미지 편집 모델을 이어서 호출하세요.
왜 "additional properties '...' not allowed"가 발생하나요?
이 스키마는 image_url 필드 하나만 허용합니다. 다른 모델 payload에서 가져온 모든 필드 — format, size, background_color, 그 무엇이든 — 는 조용히 무시되지 않고 즉시 거부됩니다.
결과는 어떻게 저장해야 하나요?
작업이 status: "success"가 된 즉시 다운로드하세요. 출력 URL은 expireAt이 있는 서명 URL이며, 장기 핫링크용이 아닙니다.
비용은 얼마인가요? 이미지당 사용량 기준으로 청구됩니다. 현재 요금은 가격 페이지에서 확인하세요.
관련 글
모든 아티클 보기 →-
튜토리얼
HiAPI API로 hailuo-2.3-fast/image-to-video 호출하는 방법: curl과 Python 실전
빠르고 저렴한 이미지-투-비디오 등급의 첫 실행 요청 — 모델 ID부터 MP4 다운로드까지
-
튜토리얼
HiAPI API로 hailuo-2.3/text-to-video를 호출하는 방법: curl, Python 및 실행 가능한 요청 예시
-
튜토리얼
HiAPI에서 Kandinsky 6.0 Pro 텍스트-투-비디오 사용하기: curl 및 Python 튜토리얼
요청 우선 실전 데모: 프롬프트에서 비디오 클립까지의 호출 구성, 요청 제출, 완료 상태 폴링 및 결과 다운로드