튜토리얼
hiapi API로 ideogram-v4를 사용하는 방법: curl, Python 및 실제 작동하는 요청
Ideogram 모델의 명성은 대부분의 이미지 모델이 아직 해결하지 못한 한 가지, 즉 타이포그래피에 기반합니다. 포스터의 헤드라인이 올바르게 철자되고, 로고의 글자가 깔끔하며, 간판 텍스트가 뒤죽박죽으로 뭉개지지 않습니다. ideogram-v4는 다른 모든 이미지 및 비디오 모델과 마찬가지로 동일한 통합 작업 API를 통해 hiapi에서 사용할 수 있으며, 이 가이드는 이 요청을 처음부터 끝까지 안내합니다: 바로 복사해 붙여넣을 수 있는 curl 버전, 완전한 Python 스크립트, 스키마가 실제로 검증하는 파라미터(이는 Ideogram 네이티브 API가 노출하는 것과 동일하지 않음), 그리고 실무에서 마주치게 될 오류들입니다.
무엇을 만들고 무엇을 준비해야 하는가
목표: POST /v1/tasks에 텍스트 프롬프트를 보내고, 작업이 완료될 때까지 기다린 후, 요청한 대로 텍스트가 렌더링된 이미지를 다운로드합니다.
필요한 것은 단 하나입니다: hiapi API 키 — 콘솔에서 생성하세요. 이는 모든 요청에서 Bearer 토큰으로 사용됩니다. 무료 비인증 계층은 없으며, 아래의 모든 호출은 Authorization: Bearer sk-...를 사용한다고 가정합니다.
hiapi의 모든 모델과 마찬가지로 ideogram-v4는 비동기 방식입니다: 작업을 생성하면 즉시 taskId를 받고, 그다음 결과를 폴링하거나 콜백을 받습니다. 동기적인 "하나의 HTTP 연결에서 40초 대기" 모드는 존재하지 않으며, 이미지 생성에서는 어차피 그런 방식을 원하지도 않을 것입니다.
최소 요청: curl
작업 생성:
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ideogram-v4",
"input": {
"prompt": "빈티지 아르데코 스타일의 재즈 페스티벌 포스터. 메인 헤드라인 텍스트 \"MIDNIGHT & BRASS\"는 짙은 남색 배경 위에 굵은 금색 서체로, 서브헤드라인 \"Live at the Riverside, Fridays\"는 그 아래에 얇은 산세리프 서체로.",
"rendering_speed": "BALANCED",
"aspect_ratio": "3:4"
}
}'
응답은 즉시 반환되며 작업 id는 data.taskId에 있습니다(tk-hiapi-... 형식). 폴링:
curl https://api.hiapi.ai/v1/tasks/tk-hiapi-XXXXXXXX \
-H "Authorization: Bearer $HIAPI_KEY"
이미지 생성 중에 data.status는 queued와 handling을 차례로 거칩니다. 종료 상태에 도달하면 success 또는 fail이 됩니다. 성공 시 이미지 URL은 data.output[0].url에 있습니다:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-XXXXXXXX",
"status": "success",
"output": [
{ "url": "https://.../result.png?...expireAt=..." }
]
}
}
이 URL에 대해 주의할 점이 하나 있습니다: 서명되어 있으며 만료됩니다(expireAt). 작업이 성공하면 즉시 바이트를 다운로드하여 자체 스토리지에 저장하세요. 핫링크를 데이터베이스에 저장해서는 안 됩니다.
ideogram-v4가 실제로 허용하는 파라미터
이 부분은 정확하게 다룰 가치가 있습니다. Ideogram 자체 문서를 읽어 보면 네이티브 API가 스타일 프리셋, 매직 프롬프트 토글, 네거티브 프롬프트, 배치 수량을 노출한다는 것을 알 수 있습니다. hiapi의 ideogram-v4 작업 스키마는 의도적으로 더 작게 만들어졌으며, 검증기는 스키마에 없는 모든 것을 거부합니다. 다음은 라이브 API로 확인한 전체 범위입니다:
| 필드 | 필수 | 타입 / 값 |
|---|---|---|
prompt |
예 | string |
rendering_speed |
예 | "TURBO", "BALANCED", "QUALITY" |
aspect_ratio |
아니오 | "1:1", "16:9", "4:3", "9:16", "3:4" |
seed |
아니오 | 정수 |
두 개의 필수 필드는 강제 검증됩니다. 빈 input을 보내면 다음과 같은 결과가 나옵니다:
invalid input: prompt: missing required field "prompt";
rendering_speed: missing required field "rendering_speed"
열거형 값을 잘못 입력하면 오류가 유효한 값을 알려줍니다:
invalid input: rendering_speed: value must be one of 'TURBO', 'BALANCED', 'QUALITY'
그리고 Ideogram 네이티브 인터페이스에서 위 표에 없는 모든 것은 알 수 없는 속성으로 거부됩니다 — style_type, magic_prompt, negative_prompt, num_images, size 및 이미지 입력은 모두 400을 반환합니다. 예:
invalid input: <root>: additional properties 'style_type' not allowed
실질적인 영향:
- 타이포그래피 제어는 전적으로 프롬프트에 달려 있습니다. 렌더링하려는 정확한 텍스트를 큰따옴표로 프롬프트에 넣고, 서체를 묘사하세요("굵은 아르데코 서체", "얇은 기하학적 산세리프", "손으로 그린 간판 서체"). 이것이 Ideogram이 명성을 얻은 포스터/로고/간판 효과를 얻는 방법입니다 — 기댈 별도의 스타일 파라미터는 없습니다.
- 작업당 이미지 한 장.
n또는num_images는 없습니다. 후보 네 개를 원한다면 네 개의 작업을 제출하고 각각의taskId를 개별적으로 폴링하세요. seed는 재현성을 위한 조절 장치입니다. 동일한 프롬프트 + 동일한 seed는 문구를 반복 개선할 때 안정적인 출발점을 제공합니다.- 텍스트-투-이미지만 지원합니다. 이 모델 스키마는 참조 이미지를 허용하지 않습니다. 워크플로에 이미지-투-이미지가 필요하다면 해당 기능을 지원하는 모델을 선택하세요 — 통합 코드를 변경하지 않고 모델을 전환하는 방법은 하나의 API 키로 여러 이미지 모델 호출하기를 참조하세요.
rendering_speed에 관하여: TURBO는 빠른 계층으로 프롬프트 문구를 반복 개선할 때 초안용으로 적합하고, QUALITY는 느리고 정교한 계층으로 최종 렌더링에 적합하며, BALANCED는 합리적인 기본값입니다. 요금은 이미지당 사용량 기준으로 청구됩니다 — 현재 가격은 가격 페이지에서 확인하세요.
완전한 Python 스크립트
동일한 흐름 — 생성, 폴링, 다운로드 — 에 타임아웃과 종료 상태 처리를 포함합니다. 유일한 의존성은 requests입니다(pip install requests).
import os
import time
import requests
API_BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {
"Authorization": f"Bearer {os.environ['HIAPI_KEY']}",
"Content-Type": "application/json",
}
def create_task(prompt: str, rendering_speed: str = "BALANCED",
aspect_ratio: str = "1:1", seed: int | None = None) -> str:
input_obj = {
"prompt": prompt,
"rendering_speed": rendering_speed,
"aspect_ratio": aspect_ratio,
}
if seed is not None:
input_obj["seed"] = seed
resp = requests.post(API_BASE, headers=HEADERS,
json={"model": "ideogram-v4", "input": input_obj},
timeout=60)
data = resp.json()
task_id = (data.get("data") or {}).get("taskId")
if not task_id:
raise RuntimeError(f"create failed: HTTP {resp.status_code} {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:
resp = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
task = resp.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} not done after {timeout_s}s")
if __name__ == "__main__":
task_id = create_task(
prompt=('"Driftwood"라는 커피 브랜드를 위한 미니멀 로고 디자인, '
'Driftwood라는 단어를 따뜻한 세리프 서체의 워드마크로, 단색, '
'크림색 배경'),
rendering_speed="QUALITY",
aspect_ratio="1:1",
seed=42,
)
print("task:", task_id)
task = wait_task(task_id)
url = task["output"][0]["url"]
png = requests.get(url, timeout=120).content # 서명된 URL은 만료됨 - 즉시 다운로드
with open("driftwood-logo.png", "wb") as f:
f.write(png)
print("saved driftwood-logo.png,", len(png), "bytes")
프로덕션 고려사항: 콜백, 멱등성 및 오류
폴링 vs. 콜백. 한 번에 이미지 하나를 생성하는 대화형 도구의 경우 몇 초마다 폴링하는 것이 더 간단하고 충분합니다. 배치 또는 서버 측 워크로드의 경우 생성 요청에 콜백을 추가하여 hiapi가 종료 상태 결과를 POST로 보내도록 하세요:
{
"model": "ideogram-v4",
"input": { "prompt": "...", "rendering_speed": "BALANCED" },
"callback": { "url": "https://your.domain.example/hiapi/hook", "when": "final" }
}
생성 시 강제되는 두 가지 제약이 있습니다: URL은 https://여야 하고 공개적으로 접근 가능해야 하며, when은 "final"만 허용됩니다 — 다른 값을 시도하면 API가 바로 invalid callback.when: only 'final' is supported를 반환합니다. 처리기가 taskId에 대해 멱등성을 갖도록 하고, 신속하게 2xx를 반환하며, 콜백이 도착하지 않는 작업을 위해 폴링 폴백을 유지하세요. 콜백이 도착하지 않으면 큐를 탓하기 전에 먼저 hiapi 작업 콜백이 발생하지 않는 이유를 참고하여 문제를 해결하세요.
멱등성. 작업 생성은 멱등적이지 않습니다 — 성공한 모든 POST /v1/tasks는 새로운 작업이자 새로운 청구입니다. taskId를 받는 즉시 자체 작업 id와 연결하여 저장하고, 이후의 모든 재시도는 재제출하지 말고 저장된 taskId를 폴링하세요.
실제로 보게 될 오류.
401과 함께"code": "permission_denied"— 키가 유효하지 않거나 해당 모델을 사용할 수 없습니다. 메시지가 명확히 알려줍니다: “This API key cannot use the selected model. Please check permissions or use another key.” 콘솔에서 해결하고, 재시도하지 마세요.400과 함께"error_code": "INVALID_REQUEST"— 검증 실패입니다.message가 구체적인 필드와 유효한 값을 지적합니다; 읽고 요청 본문을 수정하세요. 동일한 요청 본문으로 재시도하면 영원히 실패합니다.GET /v1/tasks/{id}에서404"task not found"— 작업 id가 잘못되었거나 작업이 다른 키로 생성되었습니다.- 수락된 작업의
fail상태 — 폴링 응답의data.error.code/data.error.message를 확인하세요. 이는 새 작업으로 안전하게 재시도할 수 있습니다.
관련 읽기
- ideogram-v4 모델 페이지 — 기능 및 현재 가격 계층
- hiapi 작업 콜백이 발생하지 않는 이유 — 콜백 디버깅 체크리스트
- 하나의 API 키로 여러 이미지 모델 호출하기 — 동일한 작업 API, 다른
model문자열 - 가장 저렴한 이미지 생성 API — 모델별 실제 이미지당 비용을 비교하는 방법
- API 문서 — 전체
POST /v1/tasks/GET /v1/tasks/{id}레퍼런스
자주 묻는 질문
hiapi의 ideogram-v4는 이미지-투-이미지 또는 참조 이미지를 지원하나요?
아니요. 이 모델의 작업 스키마는 prompt, rendering_speed, aspect_ratio, seed만 허용하며 — 모든 이미지 입력 필드는 400으로 거부됩니다. 기존 이미지를 편집하거나 재작성해야 한다면 이미지-투-이미지를 지원하는 모델(예: gpt-image-2 시리즈)을 사용하세요.
어떤 rendering_speed를 사용해야 하나요?
프롬프트와 텍스트의 정확한 문구를 최적화하는 동안에는 TURBO로 반복하고, 그다음 최종 승자 버전을 동일한 seed와 QUALITY로 다시 렌더링하세요. 한 번만 렌더링한다면 BALANCED가 좋은 기본값입니다.
ideogram-v4가 정확한 텍스트를 렌더링하게 하려면 어떻게 하나요?
리터럴 텍스트를 큰따옴표로 프롬프트에 넣고 주변의 타이포그래피를 묘사하세요: 메인 헤드라인 텍스트 "SUMMER SALE", 굵고 압축된 산세리프 서체. 짧은 문자열이 전체 문장보다 더 안정적으로 렌더링됩니다; 긴 줄이 깨져서 나오면 메인 헤드라인과 서브헤드라인으로 나누세요.
하나의 요청으로 여러 이미지를 생성할 수 있나요?
아니요 — 작업 하나당 이미지 한 장입니다. 대신 여러 작업을 병렬로 제출하세요; 각 작업은 자체 taskId를 가지며 독립적으로 대기열에 들어갑니다.
왜 제 키는 다른 모델에서는 작동하는데 401 permission_denied가 나나요?
모델 접근 권한은 키별로 구성됩니다. 콘솔에서 해당 키의 모델 권한을 확인하거나 ideogram-v4에 접근할 수 있는 새 키를 생성하세요.
출력 URL의 유효 기간은 얼마나 되나요?
expireAt 타임스탬프가 있는 서명된 URL입니다. 일 단위가 아닌 분 단위로 취급하세요: 작업이 success에 도달하는 즉시 이미지를 다운로드하고 파일을 직접 저장하세요.
사용 가능한 종횡비는 무엇인가요?
정확히 다섯 가지입니다: 1:1, 16:9, 4:3, 9:16, 3:4. 자유 형식의 size 파라미터는 없습니다 — size가 포함된 요청은 알 수 없는 속성으로 거부됩니다.
관련 글
모든 아티클 보기 →-
튜토리얼
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 튜토리얼
요청 우선 실전 데모: 프롬프트에서 비디오 클립까지의 호출 구성, 요청 제출, 완료 상태 폴링 및 결과 다운로드