개발자 api.md llms.txt
🌐 한국어
API 키 발급

HedaAI 상품 이미지 API

상품 사진에서 전문 이커머스 이미지 12장(메인 이미지 8장 + A+ 배너 4장)과 완성된 리스팅 카피를 생성합니다 — 프로그래밍 방식으로, 또는 MCP를 통해 AI 에이전트에서 바로.

$1.00 / 상품성공했을 때만 과금
약 10분비동기: 생성 → 폴링 → 조회
영구 보관결과물은 계정에 남고 URL은 만료되지 않음
MCP 기본 제공AI 에이전트용 호스팅 서버
기본 URL: https://hedaai.com/api/v1  ·  에이전트용 문서 미러: /developers/api.md · /developers/llms.txt

인증

hedaai.com/settings/api-keys에서 API 키를 생성하세요(모든 계정에서 가능하며, 신규 계정에는 $2.00 가입 보너스 ≈ 무료 태스크 2건이 지급됩니다). 전체 키(hda_live_…)와 해당 웹훅 시크릿(whsec_…)은 생성 시 한 번만 표시되므로 안전하게 보관하세요. 키에는 이름과 지출 한도를 지정할 수 있고 언제든 폐기할 수 있습니다.

Authorization: Bearer hda_live_...

키는 해시로 저장되며 본인 계정에만 연결됩니다 — API 키로 다른 계정의 데이터를 읽는 것은 불가능합니다.

샌드박스 모드(무료 테스트): 계정에서 실제 결제가 발생하기 전까지 생성된 이미지에는 워터마크가 들어가고 2K 업스케일이 적용되지 않습니다 — 그 외 동작은 완전히 동일합니다(GET /v1/account"mode": "sandbox_watermarked"를 반환). 첫 결제가 이루어지면 이전에 생성한 모든 상품의 워터마크가 자동으로 제거됩니다.

지출 한도: 각 키에는 선택 항목인 spend_cap_cents가 있습니다(기본값: 무제한). 한도에 도달하면 태스크 생성이 spend_cap_exceeded(403)로 실패합니다.

응답 구조

{ "status": 200, "code": 200, "message": "", "data": { … } }

오류 응답에는 프로그래밍 방식 매칭을 위한 error_code가 추가됩니다. 전송 오류와 태스크 실패의 구분: HTTP 4xx/5xx는 요청이 실패했다는 뜻입니다. 생성 도중 실패한 태스크는 HTTP 오류가 아니며, 폴링은 200과 함께 status: "failed"error 필드를 반환하고 과금되지 않습니다.

빠른 시작

# 1. 태스크 생성
curl -X POST https://hedaai.com/api/v1/tasks \
  -H "Authorization: Bearer $HEDAAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-12345-attempt-1" \
  -d '{
    "product_name": "stainless steel insulated water bottle",
    "images": ["https://your-cdn.example.com/bottle-front.jpg"],
    "aspect_ratio": "1:1",
    "category": "insulated water bottle 750ml",
    "target_market": "amazon_us"
  }'
# → data.task_id = "3f8a…", data.status = "queued"

# 2. 종료 상태가 될 때까지 15–30초마다 폴링
curl -H "Authorization: Bearer $HEDAAI_API_KEY" https://hedaai.com/api/v1/tasks/3f8a…
# → data.status = "succeeded", data.product_id = "9c1b…"

# 3. 완성된 상품 조회 (이미지 URL 12개 + 리스팅 카피)
curl -H "Authorization: Bearer $HEDAAI_API_KEY" https://hedaai.com/api/v1/products/9c1b…

POST/v1/tasks

이미지 생성 태스크를 생성합니다. 선택 헤더: Idempotency-Key(≤64자, 아래 참고).

필드타입필수비고
product_namestring짧은 상품명. 강력한 그라운딩 신호이므로 구체적으로 작성하세요.
imagesstring[1–8]사진 URL(공개 http/https, 각 ≤15MB) 및/또는 base64 / data-URI. 다각도 사진일수록 재현도가 높아집니다.
aspect_ratiostring1:1, 2:3, 3:2, 3:4, 4:3, 9:16, 16:9. Amazon 메인 이미지는 1:1을 사용합니다.
categorystring아니요구체적인 카테고리, 예: "vacuum cleaner replacement filter". 권장.
brand_namestring아니요브랜드 스토리 이미지와 리스팅 카피에 반영됩니다.
key_featuresstring[≤10]아니요반드시 보여줘야 할 셀링 포인트.
specsobject아니요{material, colorway, key_components[], usage_context, use_scenarios[], dimensions[], scale}. 권장 — API에는 대화형 검토 단계가 없으므로 그라운딩은 전적으로 보낸 정보에서 나옵니다.
target_marketstring아니요amazon_us(기본값) · shopify · ebay
copy_languagestring아니요리스팅 카피 로케일(en-US, de-DE, ja-JP, …). 타깃 마켓에 따라 기본값이 정해집니다.
aplus_formatstring아니요banner(16:9, 기본값) · aplus_3_4 · aplus_9_16 · standard_aplus/premium(Amazon 전용)
no_human_modelsbool아니요true = 모든 이미지에 인물 없음.
supplementary_textstring ≤5000아니요AI가 읽을 자유 형식 사양 / 매뉴얼 발췌.
callback_urlstring아니요종료 상태를 받을 웹훅(웹훅).

태스크 객체를 반환합니다:

{
  "task_id": "3f8a…", "status": "queued", "progress": 0,
  "queue_position": 2, "eta_seconds": 840, "cost_cents": 0,
  "created_at": "2026-07-17T08:00:00Z",
  "urls": { "get": "/api/v1/tasks/3f8a…", "cancel": "/api/v1/tasks/3f8a…/cancel" }
}

GET/v1/tasks/{task_id}

상태 라이프사이클: queuedprocessingsucceeded | partial_failed | failed | canceled.

15–30초마다 폴링하세요. 대기 중에는 queue_position / eta_seconds가 채워집니다.

POST/v1/tasks/{task_id}/cancel

태스크를 취소합니다. 대기 중에는 무료이며, 이미 완료된 태스크에는 영향이 없습니다(멱등).

GET/v1/products/{product_id}

{
  "product_id": "9c1b…", "name": "stainless steel insulated water bottle",
  "target_market": "amazon_us", "aspect_ratio": "1:1", "watermarked": false,
  "listing_copy": {
    "title": "…", "bullet_points": ["…","…","…","…","…"], "description": "…",
    "search_terms": "…", "meta_title": "…", "meta_description": "…", "language": "en"
  },
  "images": [
    { "slice_id": "M1", "section": "main", "url": "https://images.hedaai.com/…",
      "url_2k": "https://images.hedaai.com/…", "width": 2048, "height": 2048, "sort_order": 1 }
  ],
  "created_at": "2026-07-17T08:11:32Z"
}

GET/v1/account

{
  "balance_cents": 1250, "paid_balance_cents": 1000, "bonus_balance_cents": 250,
  "has_paid": true, "mode": "live", "price_per_task_cents": 100,
  "key": { "name": "prod-integration", "key_prefix": "hda_live_ab12…cd34",
           "spend_cap_cents": null, "spent_cents": 700 }
}

멱등성

POST /v1/tasksIdempotency-Key 헤더(≤64자)를 전달하세요. 같은 키와 같은 본문으로 재시도하면 중복 태스크를 생성(그리고 결국 과금)하는 대신 원래 태스크를 반환합니다. 같은 키에 다른 본문을 보내면 409 idempotency_conflict가 반환됩니다. 에이전트와 자동화에 적극 권장합니다 — 네트워크 재시도가 이중 과금으로부터 안전해집니다.

웹훅

태스크 생성 시 callback_url을 지정하면 종료 상태에서 POST를 받습니다. 이벤트: task.succeeded, task.partial_failed, task.failed, task.canceled.

{ "id": "evt_…", "type": "task.succeeded", "created_at": "2026-07-17T08:11:35Z",
  "data": { /* 태스크 객체 — GET /v1/tasks/{id}와 동일한 형태 */ } }

서명은 Standard Webhooks 사양을 따릅니다 — 헤더는 webhook-id, webhook-timestamp, webhook-signature: v1,<base64>입니다. 키의 webhook_secret으로 검증하세요:

import hmac, hashlib, base64

def verify(secret, msg_id, timestamp, body: bytes, signature_header):
    key = base64.b64decode(secret.removeprefix("whsec_"))
    expected = base64.b64encode(hmac.new(key, f"{msg_id}.{timestamp}.".encode() + body,
                                         hashlib.sha256).digest()).decode()
    return any(hmac.compare_digest(expected, s.split(",", 1)[1])
               for s in signature_header.split() if s.startswith("v1,"))

2xx로 빠르게 응답하세요(무거운 작업은 비동기로 처리). 전송 방식: 즉시 1회 시도 후 3s / 6s / 12s 간격으로 재시도하고, 그다음에는 실패로 표시됩니다(폴링은 계속 사용할 수 있습니다). 오래된 타임스탬프(>5 min)는 거부하고 id로 중복을 제거하세요. callback_url은 공개 http(s) 엔드포인트여야 하며, 사설/내부 주소는 거부됩니다.

요청 제한 & 동시성

제한초과 시
키당 요청 수120 / min (전체 엔드포인트)429 rate_limitedRateLimit-Limit / -Remaining / -Reset 헤더를 확인하세요
키당 진행 중 태스크2 (queued + processing)429 concurrency_limit — 태스크가 끝날 때까지 기다리세요
플랫폼 API 용량동적429 api_capacity — 몇 분 뒤 재시도하세요

생성 작업은 무겁기 때문에(태스크당 13–20회의 AI 이미지 호출) 처리량은 요청 빈도가 아니라 진행 중 태스크 슬롯 수로 결정됩니다. 더 높은 동시성이 필요하신가요? 문의하기.

오류

error_codeHTTP의미
bad_request400잘못된 파라미터 — 메시지에 해당 필드가 정확히 표시됩니다(예: images[2]: image download failed with HTTP 403).
unauthorized401API 키 누락/무효, 또는 폐기된 키.
insufficient_credits402잔액 부족; data.balance_cents가 포함됩니다.
spend_cap_exceeded403이 키의 지출 한도를 모두 소진했습니다.
account_disabled / email_not_verified / email_bounced403계정 수준 제한.
not_found404태스크/상품이 존재하지 않거나 다른 계정 소유입니다.
idempotency_conflict409동일한 Idempotency-Key, 다른 본문.
concurrency_limit / api_capacity / rate_limited429요청 제한을 참고하세요.
generation_failed / internal_error500서버 측 오류; 멱등성 키와 함께 안전하게 재시도할 수 있습니다.

코드 예제

태스크 생성, 종료 상태까지 폴링, 완성된 상품 조회로 이어지는 전체 흐름을 원하는 프로그래밍 언어로 확인하세요.

API=https://hedaai.com/api/v1

# 1. 태스크 생성
TASK_ID=$(curl -sS -X POST "$API/tasks" \
  -H "Authorization: Bearer $HEDAAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: sku-8842-v1" \
  -d '{"product_name":"stainless steel insulated water bottle",
       "images":["https://your-cdn.example.com/bottle.jpg"],
       "aspect_ratio":"1:1"}' | jq -r .data.task_id)

# 2. 종료 상태까지 폴링
while :; do
  TASK=$(curl -sS -H "Authorization: Bearer $HEDAAI_API_KEY" "$API/tasks/$TASK_ID")
  STATUS=$(echo "$TASK" | jq -r .data.status)
  [ "$STATUS" = "queued" ] || [ "$STATUS" = "processing" ] || break
  sleep 20
done

# 3. 이미지 + 리스팅 카피 조회
if [ "$STATUS" = "succeeded" ]; then
  PRODUCT_ID=$(echo "$TASK" | jq -r .data.product_id)
  curl -sS -H "Authorization: Bearer $HEDAAI_API_KEY" "$API/products/$PRODUCT_ID" \
    | jq -r '.data.images[].url, .data.listing_copy.title'
fi

MCP 서버 (AI 에이전트용)

HedaAI는 호스팅형 Model Context Protocol 서버를 제공하므로 에이전트가 상품 이미지를 직접 생성할 수 있습니다:

claude mcp add --transport http hedaai https://hedaai.com/api/v1/mcp \
  --header "Authorization: Bearer $HEDAAI_API_KEY"

생성은 비동기입니다: 에이전트가 create_product_shoot를 호출하고(선택적으로 idempotency_key 포함), 종료 상태가 될 때까지 30–60초마다 get_task를 폴링한 뒤, get_product로 이미지 URL과 리스팅 카피를 가져옵니다. OAuth가 필요한 클라이언트(예: claude.ai 커스텀 커넥터)는 아직 지원하지 않습니다 — Claude Code, Cursor 또는 에이전트 SDK처럼 API 키를 사용할 수 있는 클라이언트를 이용하세요.

요금

항목가격
상품 촬영 — 이미지 12장 + 리스팅 카피$1.00, 성공했을 때만 과금
가입 보너스$2.00 (≈ 무료 태스크 2건, 첫 결제 전까지 워터마크 적용)
잔액 충전hedaai.com에서 $10–$1000; ≥$50 +5% 보너스, ≥$100 +10%

잔액은 만료되지 않습니다. 구독도 없습니다. 최신 가격은 언제나 GET /v1/account(price_per_task_cents)에서 확인할 수 있습니다.