HiAPI
블로그

튜토리얼

hiapi API를 통해 seedream-5.0-lite 이미지-투-이미지 사용하는 방법

Jul 7, 2026
hiapi API를 통해 seedream-5.0-lite 이미지-투-이미지 사용하는 방법

이 튜토리얼은 hiapi 통합 작업 API를 통해 seedream-5.0-lite의 이미지-투-이미지 모드를 호출하는 방법을 보여줍니다: 정확한 요청 구조, 바로 실행 가능한 curl 명령, 백엔드에 넣을 수 있는 Python 스크립트, 그리고 이 모델이 강제하지만 다른 모델은 하지 않는 검증 함정까지 다룹니다.

이 글을 다 읽으면 하나 이상의 참조 이미지 URL과 편집 프롬프트를 받아 즉시 다운로드 가능한 생성 이미지 URL을 반환하는 스크립트를 갖게 됩니다.

필요한 준비물

  • hiapi 계정과 API key. hiapi 콘솔에서 얻을 수 있습니다.
  • 공용 HTTPS URL에 호스팅된 하나 이상의 참조 이미지. 이 모델은 단일 요청에서 최대 14장의 참조 이미지를 허용하며, 이것이 다중 참조 이미지 워크플로에 유용한 이유입니다—한 이미지의 피사체를 다른 이미지의 스타일이나 장면과 융합할 수 있습니다.
  • 편집이나 변환을 설명하는 텍스트 프롬프트(최소 3자—맞습니다, API가 이를 검증합니다).

모든 요청은 통합 작업 엔드포인트로 전송되며, 키는 Authorization 헤더에 담습니다:

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

요청 구조(그리고 이 모델의 요구 사항)

모델 id는 seedream-5.0-lite/image-to-image—/v1/models에 나열된 것과 정확히 동일하게 그대로 전달하세요. 이 모델의 input 스키마는 엄격하며 네 개 필드 모두 필수입니다:

필드 타입 설명
prompt string 편집 지시문. 최소 길이 3.
image_urls string[] 1–14개의 참조 이미지 URL.
aspect_ratio string 1:1, 4:3, 3:4, 16:9, 9:16, 2:3, 3:2, 21:9 중 하나.
resolution string 2K 또는 4K만 가능.이 모델에는 1K 단계가 없습니다.

플랫폼의 다른 모델에서 마이그레이션한 사람들이 흔히 밟는 두 가지 함정:

  1. resolution은 2K 또는 4K만 허용합니다.공유 작업 제출 코드가 기본값으로 "1K"를 채운다면(많은 다른 이미지 모델에서 동작함), 이 모델은 400으로 거부합니다.
  2. 잉여 필드는 무시되는 것이 아니라 거부됩니다.size, n 또는 스키마 밖의 어떤 것이든 전송하면 400 INVALID_REQUEST와 함께 additional properties '<field>' not allowed가 반환됩니다. 작업 API는 모델별로 input을 검증합니다—다른 모델의 payload를 무턱대고 재사용하지 마세요.

최소 실행 예제: curl

작업 생성:

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-5.0-lite/image-to-image",
    "input": {
      "prompt": "Replace the background with a sunlit Tokyo street at golden hour, keep the subject unchanged",
      "image_urls": ["https://your-cdn.example.com/subject.png"],
      "aspect_ratio": "3:2",
      "resolution": "2K"
    }
  }'

성공적으로 제출되면 data에 작업 id가 반환됩니다:

{"code": 200, "data": {"taskId": "task_abc123..."}}

결과 폴링:

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

실행 중에는 data.status가 pending/processing입니다. 완료되면 "success"로 바뀌고 이미지가 data.output에 나타납니다:

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

출력 URL은 짧은 시간만 유효합니다(expireAt 참고). 즉시 바이트를 다운로드하여 직접 저장하세요—원본 URL을 핫링크하거나 영속화하지 마세요.

다중 참조 이미지: 여러 이미지 전달

여러 참조 이미지를 융합하려면—예를 들어 제품 이미지 하나와 스타일 참조 이미지 하나—image_urls에 URL을 더 추가하고 프롬프트에서 각 이미지가 무엇을 기여하는지 명시하세요:

{
  "model": "seedream-5.0-lite/image-to-image",
  "input": {
    "prompt": "Place the product from the first image into the scene from the second image, matching its lighting and color grade",
    "image_urls": [
      "https://your-cdn.example.com/product.png",
      "https://your-cdn.example.com/scene-reference.jpg"
    ],
    "aspect_ratio": "1:1",
    "resolution": "2K"
  }
}

하드 상한은 14개 URL이며, 15번째는 400 INVALID_REQUEST: image_urls: maxItems: got 15, want 14를 반환합니다. 실무에서는 각 이미지의 역할을 명확히 지정한 프롬프트(“이미지 1의 피사체를 유지하고 이미지 2의 색감을 적용”)와 함께 신중히 고른 2–4장의 참조 이미지가, 느슨하게 관련된 이미지 잔뜩보다 훨씬 통제 가능한 편집 결과를 줍니다.

단일 이미지에 정밀하고 표적화된 편집—배경 교체, 의상 변경, 객체 제거—에는 참조 URL 하나를 사용하고 무엇을 바꿀지와 무엇을 유지할지(“얼굴과 자세는 그대로 유지”)를 함께 명시하세요. Seedream 모델은 유지 지시를 잘 따르며, 명시적으로 밝히는 것이 정밀 편집과 완전한 재해석을 가르는 핵심입니다.

프로덕션용 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 edit_image(prompt: str, image_urls: list[str],
               aspect_ratio: str = "1:1", resolution: str = "2K") -> bytes:
    # 1. Create the task
    resp = requests.post(API_BASE, headers=HEADERS, json={
        "model": "seedream-5.0-lite/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,
            "aspect_ratio": aspect_ratio,
            "resolution": resolution,  # this model: "2K" or "4K" only
        },
    }, 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. Poll until terminal state
    deadline = time.time() + 600
    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. Download immediately — the URL expires
            img = requests.get(outputs[0]["url"], timeout=120)
            img.raise_for_status()
            return img.content
        if task.get("status") == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(5)
    raise TimeoutError(f"task {task_id} still running after 600s")


if __name__ == "__main__":
    png = edit_image(
        "Replace the background with a minimalist studio backdrop, keep the subject unchanged",
        ["https://your-cdn.example.com/subject.png"],
        aspect_ratio="3:2",
    )
    with open("edited.png", "wb") as f:
        f.write(png)
    print(f"saved edited.png ({len(png)} bytes)")

폴링 대신 콜백 사용

폴링은 스크립트와 워커 큐에서 문제없습니다. 웹 백엔드라면 작업 생성 시 콜백을 등록하여 hiapi가 최종 상태를 푸시하게 하세요—callback 객체는 요청 최상위, model 바로 옆에 위치합니다:

{
  "model": "seedream-5.0-lite/image-to-image",
  "input": { "...": "..." },
  "callback": {
    "url": "https://your-app.example.com/hooks/hiapi",
    "when": "final"
  }
}

"when": "final"을 사용하면 작업이 success 또는 fail에 도달할 때 한 번만 POST를 받습니다. 처리기에는 두 가지 규칙이 있습니다:

  • 멱등하게 만드세요.작업 id를 처리 키로 사용하여 중복 전달된 webhook이 중복 처리를 일으키지 않게 하세요. 제출 시 작업 id를 저장하고, 콜백을 “가서 가져와 완료하라”는 알림으로 취급하되 유일한 사실 출처로 삼지 마세요.
  • 대사(reconciliation) 경로를 남겨 두세요.콜백이 발동할 때 엔드포인트가 다운되어 있었다면, 미완료 id를 주기적으로 스캔하고 GET /v1/tasks/<id>로 누락을 잡아낼 수 있습니다.

콜백이 계속 도착하지 않는 것 같다면 왜 hiapi 작업 콜백이 발동하지 않는가의 일반적 장애 패턴을 가능성 순서대로 하나씩 점검하세요.

오류 처리: 정말 중요한 세 가지 실패

생성 시 401 permission_denied—키가 해당 모델을 사용할 수 없습니다. 응답 본문은 다음과 같습니다:

{"error": {"code": "permission_denied", "message": "This API key cannot use the selected model...", "type": "hiapi_error"}}

콘솔에서 키의 모델 권한을 확인하거나 이미지 모델이 활성화된 키를 사용하세요.

생성 시 400 INVALID_REQUEST—input이 해당 모델의 스키마와 맞지 않습니다. 메시지는 위반 필드를 한 번에 모두 나열하므로(예: resolution: value must be one of '2K', '4K'; <root>: additional properties 'size' not allowed) 전체를 읽고 모든 필드를 한 번에 고치세요. 이는 영구적 오류입니다—같은 payload를 재시도하면 영원히 실패합니다.

작업의 status: "fail"—생성은 성공했지만 생성이 실패했습니다(백엔드가 가져올 수 없는 참조 URL, 콘텐츠 정책, 업스트림 용량). 작업의 error.code와 error.message가 원인을 알려줍니다. 400과 달리 일부는 일시적이므로 백오프를 두고 한 번 재시도할 가치가 있습니다.

또한 알아 둘 점: 존재하지 않거나 만료된 작업 id를 GET하면 404 task not found가 반환됩니다—대사 스캔에서는 이를 “여전히 대기 중”이 아니라 최종 상태로 취급해야 합니다.

다음에 볼 곳

FAQ

seedream-5.0-lite 이미지-투-이미지에 참조 이미지를 몇 장까지 전달할 수 있나요? image_urls 배열은 최대 14장입니다. 최소 한 장—이 필드는 필수이므로 순수 텍스트-투-이미지 호출은 seedream-5.0-lite/text-to-image를 사용해야 합니다.

다른 모델은 1K를 쓰는데 왜 “value must be one of '2K', '4K'”가 나오나요? 작업 API의 input 스키마는 모델별로 정의됩니다. seedream-5.0-lite의 이미지-투-이미지 모드는 2K와 4K 출력만 제공하며, 다른 모델은 1K 단계를 제공합니다. 확인 없이 다른 모델의 payload를 재사용하지 마세요.

참조 이미지를 URL 대신 base64로 보낼 수 있나요? 이 모델의 스키마는 URL 배열인 image_urls를 받습니다. 이미지를 접근 가능한 HTTPS URL(어떤 CDN, 객체 스토리지 버킷 또는 사전 서명 URL이든 가능)에 호스팅하고 그 URL을 전달하세요.

한 번 생성에 얼마나 걸리며, 출력 URL은 얼마나 유효한가요? 보통 위 Python 예제의 600초 폴링 예산보다 훨씬 짧습니다. 출력 URL에는 expireAt 타임스탬프가 있습니다—작업 성공 후 즉시 바이트를 다운로드하여 자체 스토리지에 저장하세요.

같은 코드를 seedream-5.0-lite 텍스트-투-이미지에 쓸 수 있나요? 엔드포인트와 흐름은 같지만 텍스트-투-이미지는 자체 input 스키마를 가집니다(image_urls 없음). 모델 id를 seedream-5.0-lite/text-to-image로 바꾸고 참조 이미지를 제거하되, 모드별 필수 필드가 다르므로 테스트 호출 한 번으로 검증하세요.

이미지당 얼마인가요? 가격은 생성당 사용량으로 청구되며 해상도에 따라 다릅니다. 실시간 요율은 가격 페이지에서 확인하세요.

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

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

API 문서 보기