HiAPI
블로그

튜토리얼

hiapi API로 bria-product-shot을 사용하는 방법: curl, Python, 그리고 실제로 동작하는 한 번의 요청

Oct 23, 2026
hiapi API로 bria-product-shot을 사용하는 방법: curl, Python, 그리고 실제로 동작하는 한 번의 요청

bria-product-shot은 제품 사진 한 장을 받아 제품을 다양한 장면에 배치한 새 이미지를 반환합니다. 장면을 영어로 설명하거나, 참조 이미지를 제공하여 그 이미지의 배경 스타일을 따르게 할 수 있습니다. 이 가이드는 hiapi에서 처음부터 끝까지 실행된 요청 하나와, 요청 수락 여부를 결정하는 매개변수 규칙을 보여줍니다.

대시보드의 API Keys 페이지에서 hiapi API 키를 발급받고, 공개적으로 접근 가능한 제품 사진 URL(JPEG, PNG 또는 WEBP, 최대 12 MB)을 준비해야 합니다.

최소 동작 예제(curl)

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bria-product-shot",
    "input": {
      "image_url": "https://your-cdn.example.com/serum-bottle.png",
      "prompt": "On a white marble countertop beside a window, soft morning light, a few green leaves in the background",
      "placement_type": "manual_placement",
      "manual_placement_selection": "bottom_center"
    }
  }'

생성 호출은 즉시 태스크 ID를 반환합니다:

{"code":200,"data":{"taskId":"tk-hiapi-01M5K7TWWMM68ZDTERJN4QV8MW"},"message":"success"}

data.status가 success 또는 fail이 될 때까지 GET /v1/tasks/<taskId>를 폴링합니다. 완료 후 응답은 다음과 같습니다(출력 호스트 이름은 축약됨):

{
  "code": 200,
  "data": {
    "model": "bria-product-shot",
    "status": "success",
    "storage": "temp",
    "taskId": "tk-hiapi-01M5K7TWWMM68ZDTERJN4QV8MW",
    "output": [{"artifactId": "287064", "type": "image", "expireAt": 1793325686,
                "url": "https://temp.hiapi.ai/.../...-0.png"}]
  },
  "message": "success"
}

Python 버전

import os, time, requests

API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}

def product_shot(image_url: str, scene: str, position: str = "bottom_center") -> bytes:
    r = requests.post(API, headers=HEADERS, json={
        "model": "bria-product-shot",
        "input": {
            "image_url": image_url,
            "prompt": scene,
            "placement_type": "manual_placement",
            "manual_placement_selection": position,
        },
    }, timeout=30)
    r.raise_for_status()
    task_id = r.json()["data"]["taskId"]

    for _ in range(60):
        d = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
        if d["status"] == "success":
            # 출력 URL은 만료됩니다(약 7일): 즉시 다운로드하세요
            return requests.get(d["output"][0]["url"], timeout=60).content
        if d["status"] == "fail":
            raise RuntimeError(d)
        time.sleep(4)
    raise TimeoutError(task_id)

open("shot.png", "wb").write(product_shot(
    "https://your-cdn.example.com/serum-bottle.png",
    "On a white marble countertop beside a window, soft morning light, a few green leaves in the background",
))

주요 매개변수

필드 설명
image_url 필수. 제품 사진의 공개 http(s) URL입니다.
prompt 영어 장면 설명, 1–1000자입니다.
reference_image_url 장면 참조 이미지입니다. 이 매개변수 또는 prompt 중 하나만 사용해야 하며, 절대 동시에 사용할 수 없습니다.
placement_type manual_placement(기본값)는 제품을 사전 설정된 위치에 배치합니다. original은 사진 속 원래 위치를 유지합니다.
manual_placement_selection bottom_center(기본값), upper_left, upper_right, bottom_left, bottom_right, right_center, left_center, upper_center, center_vertical, center_horizontal입니다. manual_placement를 사용할 때만 유효합니다.
original_quality original을 사용할 때만 유효합니다. 약 1 MP로 축소하지 않고 입력 크기를 유지합니다.
fast 기본값 true. 끄면 표준 모델을 사용하며, 가격은 동일합니다.
optimize_description 기본값 true. 장면 텍스트를 확장합니다. prompt를 사용할 때만 유효하며, 참조 이미지와 함께 사용할 수 없습니다.

이 스키마는 닫혀 있으며(additionalProperties: false) 교차 필드 규칙이 있으므로, prompt와 reference_image_url을 함께 사용하거나 original과 사전 설정 위치를 함께 사용하는 등의 조합은 모두 유효하지 않은 요청입니다.

테스트 기록 및 참고 사항

실시간 API에 대해 실행한 내용:

  • 위 요청으로 실제 생성을 한 번 수행했으며, fast는 기본값으로 두었습니다. 태스크는 handling과 archiving을 거쳤고, 생성부터 완료까지 약 26초 후 success에 도달했습니다.
  • 정사각형 입력의 경우 출력은 1024×1024 PNG(약 1 MB)였으며, 이는 모델 페이지의 설명(정사각형 입력의 경우 사전 설정 위치는 1024×1024 기준으로 측정됨)과 일치합니다.
  • 일부러 잘못된 값 "manual_placement_selection": "middle"을 넣었을 때 생성 시점에 거부되었고, HTTP 400과 error_code: INVALID_REQUEST가 반환되었습니다. 오류 메시지에 허용되는 열 가지 위치가 모두 나열되므로, 태스크 실패를 기다리지 않고 바로 사용자에게 보여줄 수 있습니다.

실용적인 팁:

  • 출력을 즉시 다운로드하세요. 각 출력에는 expireAt 타임스탬프(완료 시점 기준 Unix 시간, 약 7일)가 포함됩니다. 이미지를 자체 스토리지에 저장하세요.
  • 이미지당 고정 가격입니다. 모델 페이지에 따르면 장면 텍스트와 참조 이미지, 배치 위치, 빠른 모드는 가격에 영향을 주지 않습니다. 숫자를 하드코딩하지 말고 가격 페이지의 현재 수치를 확인하세요.
  • 이 가이드는 생성을 한 번만 실행했으므로, 이 페이지는 서로 다른 제품 카테고리의 품질에 대해 어떠한 주장도 하지 않습니다. 일괄 사용 전에 자체 상품 카탈로그 이미지로 먼저 테스트하세요.

프로덕션 환경 권장 사항

  • 태스크를 생성하고 taskId를 저장한 뒤, 일시적인 네트워크 오류가 발생하면 몇 번 재시도하며 폴링하세요. 새 태스크를 만들지 말고 저장된 id를 다시 폴링하세요. 새 태스크는 다시 과금되기 때문입니다.
  • 큐를 사용하는 경우, 클라이언트 측에서 위의 열 가지 값으로 manual_placement_selection을 검증하여 잘못된 입력이 API에 도달하지 않도록 하세요.

관련 페이지

자주 묻는 질문

텍스트 프롬프트 대신 참조 이미지를 사용할 수 있나요? 네. reference_image_url을 보내고 prompt는 생략하세요. 둘을 동시에 보내지 말고, optimize_description도 참조 이미지와 함께 보내지 마세요.

한 번의 호출로 몇 장의 이미지가 반환되나요? 한 장입니다. 모델 페이지는 실행당 한 장의 이미지가 출력된다고 설명합니다.

제품이 사진 속 원래 위치에 유지되나요? placement_type: "original"일 때만 그렇습니다. 기본값인 manual_placement는 제품을 선택한 사전 설정 위치로 재배치합니다.

영구 AI 아티팩트로 빌드 시작하기

API 키를 받아 태스크 기반의 하나의 API로 이미지, 비디오, 오디오 모델을 호출하세요.

API 문서 보기