HiAPI
블로그

튜토리얼

hiapi API로 grok-imagine-quality/image-to-image 사용하는 방법: curl, Python 및 사용 가능한 요청

Jul 11, 2026
hiapi API로 grok-imagine-quality/image-to-image 사용하는 방법: curl, Python 및 사용 가능한 요청

이 가이드에서는 hiapi 통합 작업 API를 통해 grok-imagine-quality/image-to-image(Grok Imagine 시리즈 중 더 높은 충실도의 티어)를 사용하여 기존 이미지를 변환하는 방법을 보여줍니다. 원본 이미지와 텍스트 프롬프트를 제출하고, 결과를 폴링하여 가져온 뒤, 생성된 이미지를 다운로드합니다. 아래의 모든 요청 및 응답 구조는 실시간 API와 대조하여 검증되었습니다.

필요한 준비물

  • hiapi API 키 — 대시보드에서 생성하세요.
  • 원본으로 사용할 공개적으로 접근 가능한 이미지 URL 1~3개. 플랫폼이 서버 측에서 입력 미디어를 가져와 정규화하므로 로컬 파일 경로와 base64 페이로드는 사용할 수 없습니다 — 먼저 이미지를 API가 접근할 수 있는 위치에 호스팅하세요.

이게 전부입니다. SDK는 필요 없습니다. 작업 API는 일반 HTTPS + JSON입니다.

요청 모드

grok-imagine-quality/image-to-image는 비동기 작업 엔드포인트에서 실행됩니다: POST /v1/tasks로 작업을 생성한 뒤 완료될 때까지 GET /v1/tasks/<taskId>를 폴링하거나(또는 콜백을 등록하거나) 하면 됩니다.

입력 스키마는 엄격합니다 — 알 수 없는 필드는 400으로 거부됩니다:

필드 타입 필수 여부 설명
prompt string ✅ 원본 이미지에 무엇을 할지
image_urls string[] ✅ 원본/참조 이미지의 공개 URL 1~3개
aspect_ratio string – 다음 중 하나: auto, 2:1, 20:9, 19.5:9, 16:9, 4:3, 3:2, 1:1, 2:3, 3:4, 9:16, 9:19.5, 9:20, 1:2
resolution string – 1k 또는 2k — 소문자 (1K는 400을 반환함)
output_format string – jpeg, png 또는 webp

없는 것에 주목하세요: size도, n도, seed도, strength나 consistency 조절 키도 없습니다. 출력이 원본 이미지를 얼마나 따르는지는 프롬프트와 전달한 참조 이미지로 제어됩니다 — 아래 FAQ를 참고하세요.

최소 동작 예제(curl)

작업 생성:

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-quality/image-to-image",
    "input": {
      "prompt": "Turn this product photo into a clean studio shot on a light gray background with soft shadows",
      "image_urls": ["https://your-cdn.example.com/source.jpg"],
      "aspect_ratio": "1:1",
      "resolution": "2k",
      "output_format": "png"
    }
  }'

성공적으로 생성되면 작업 ID가 반환됩니다:

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx"
  }
}

작업이 최종 상태에 도달할 때까지 폴링합니다:

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

실행 중에는 data.status가 진행 중 상태이며, 완료되면 success로 바뀌고 이미지는 data.output에 위치합니다:

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx",
    "status": "success",
    "output": [
      {
        "url": "https://.../result.png?...&expireAt=...",
        "expireAt": 1760000000
      }
    ]
  }
}

⚠️ 출력 URL은 임시입니다(expireAt 참고). 작업이 성공하면 즉시 바이트를 다운로드하여 자체 스토리지에 저장하세요 — 결과 URL을 핫링크하지 마세요.

작업이 실패하면 data.status는 fail이 되고 data.error에 code와 message가 담깁니다.

Python: 생성, 폴링, 다운로드

requests만 사용하는 완전한 스크립트:

import time
import requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def create_task(prompt: str, image_urls: list[str]) -> str:
    payload = {
        "model": "grok-imagine-quality/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,   # 1-3 public URLs
            "aspect_ratio": "1:1",
            "resolution": "2k",         # lowercase: "1k" or "2k"
            "output_format": "png",
        },
    }
    r = requests.post(API_BASE, headers=HEADERS, json=payload, timeout=60)
    data = r.json()
    task_id = (data.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"create failed: {data}")
    return task_id

def wait_task(task_id: str, timeout_s: int = 600, poll_interval: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(poll_interval)
    raise TimeoutError(f"task {task_id} still running after {timeout_s}s")

if __name__ == "__main__":
    task_id = create_task(
        prompt="Turn this product photo into a clean studio shot on a light gray background",
        image_urls=["https://your-cdn.example.com/source.jpg"],
    )
    print("task:", task_id)

    task = wait_task(task_id)
    url = task["output"][0]["url"]

    # The output URL expires -- download immediately and persist yourself
    img = requests.get(url, timeout=120).content
    with open("result.png", "wb") as f:
        f.write(img)
    print(f"saved result.png ({len(img)} bytes)")

프로덕션 환경 고려 사항

폴링 대신 콜백 사용

일회성 스크립트를 넘어서는 모든 경우에는 콜백을 등록하고 폴링 루프를 건너뛰세요. 최상위 callback 객체를 추가합니다(model, input과 동일한 레벨):

{
  "model": "grok-imagine-quality/image-to-image",
  "input": { "...": "..." },
  "callback": {
    "url": "https://your-app.example.com/hooks/hiapi",
    "when": "final"
  }
}

when은 "final"만 지원합니다 — 작업이 최종 상태(success 또는 fail)에 도달하면 정확히 한 번의 POST를 받게 됩니다. 경험칙:

  • 폴링은 프로세스가 어차피 살아 있는 CLI, 노트북, 배치 작업에 적합합니다. 3~5초마다 폴링하세요. 1초 미만 간격으로 몰아치지 마세요.
  • 콜백은 웹 백엔드에 더 적합합니다: 대기 중인 연결도 없고, 생성 중에 작업 스레드가 묶여 있지도 않습니다. 웹훅 본문을 맹신하지 말고 서버 측에서 GET /v1/tasks/<taskId>를 다시 호출해 페이로드를 검증하세요.

멱등성

작업 생성 자체는 멱등하지 않습니다 — 프로세스가 POST /v1/tasks 이후, taskId를 영속화하기 전에 크래시하면 재시도 시 두 번째 작업이 생성(및 과금)됩니다. 기다리기를 시작하기 전에 taskId를 내부 작업 ID를 키로 하여 자체 스토리지에 영속화하고, 재시작 시 재생성하지 말고 저장된 taskId를 폴링하여 복구하세요.

오류 처리

실제로 마주치게 될 오류들:

  • 401 permission_denied — API 키가 유효하지 않거나 이 모델에 대한 접근 권한이 없습니다. 응답 본문에는 지원팀에 보낼 수 있는 request_id가 포함됩니다:

    {
      "error": {
        "code": "permission_denied",
        "message": "This API key cannot use the selected model. ...",
        "request_id": "2026...",
        "type": "hiapi_error"
      }
    }
    
  • 400 INVALID_REQUEST — 스키마 위반이며 정확한 메시지가 함께 제공됩니다. 이 모델의 실제 예시:

    • prompt: missing required field "prompt" — 필수 필드를 빠뜨렸습니다.
    • image_urls: maxItems: got 12, want 3 — 참조 이미지가 너무 많습니다(최대 3개).
    • resolution: value must be one of '1k', '2k' — 1K/4K를 보냈습니다.
    • additional properties 'seed' not allowed — 이 모델이 허용하지 않는 필드를 전달했습니다.
  • 최종 fail 상태 — 작업은 접수되었지만 생성이 실패했습니다(예: 원본 URL을 가져올 수 없음). data.error.message를 확인하고 입력을 수정한 뒤 새 작업을 생성하세요.

5xx 및 네트워크 오류에는 백오프 재시도를 사용하고, 400은 재시도하지 마세요 — 페이로드를 수정하기 전에는 동일하게 실패합니다.

품질 티어 선택(그리고 '일관성'은 어떻게 되나요?)

hiapi의 Grok Imagine 시리즈는 티어와 모달리티에 따라 별도의 모델 ID로 나뉩니다. 이미지 대 이미지의 경우 다음을 선택할 수 있습니다:

티어가 곧 모델 ID입니다 — input 내부에 quality 파라미터는 없습니다(보내면 400 additional properties 'quality' not allowed가 반환됨). 두 티어의 이미지당 가격은 가격 페이지에서 확인하세요.

관련 문서

자주 묻는 질문

일관성이나 강도 파라미터가 있나요? 없습니다. 입력 스키마는 prompt, image_urls, aspect_ratio, resolution, output_format만 허용하며, 그 외의 것은 400으로 거부됩니다. 출력이 원본 이미지를 얼마나 따를지 제어하려면 프롬프트에 반드시 유지해야 할 내용을 명확히 명시하고("제품과 라벨은 동일하게 유지하고 배경만 변경"), image_urls로 최대 3개의 참조 이미지를 전달하세요.

로컬 파일을 업로드하거나 base64를 보낼 수 있나요? 직접은 안 됩니다 — image_urls는 URL을 받고 플랫폼이 서버 측에서 가져옵니다. 파일을 공개적으로 접근 가능한 스토리지(S3, R2, CDN)에 업로드하고 해당 URL을 전달하세요.

원본 이미지를 몇 개까지 전달할 수 있나요? 1~3개입니다. 빈 배열은 minItems: got 0, want 1로 실패하고, 3개를 초과하면 maxItems로 실패합니다.

어떤 해상도와 종횡비가 지원되나요? resolution은 1k 또는 2k입니다(소문자만). aspect_ratio는 2:1부터 1:2까지 14개 값을 지원하며, auto, 16:9, 1:1, 9:16 및 모바일에 적합한 9:19.5/9:20이 포함됩니다.

출력 URL은 얼마나 유효한가요? 각 출력에는 expireAt 타임스탬프가 있습니다. 결과를 일시적인 것으로 간주하세요: 작업이 성공하면 즉시 바이트를 다운로드하여 직접 저장하세요.

여러 변형을 생성하려면 어떻게 하나요? n 파라미터는 없습니다 — 변형마다 작업을 하나씩 생성하세요. 작업은 독립적으로 실행되므로 여러 개를 병렬로 제출할 수 있습니다.

키가 올바른데 401 permission_denied는 무슨 뜻인가요? 키는 존재하지만 이 모델을 사용할 수 없습니다(요금제 또는 권한 범위). 대시보드에서 키의 모델 권한을 확인하거나, 오류 응답 본문의 request_id를 사용해 지원팀에 문의하세요.

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

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

API 문서 보기