Tutorial
How to Use Ideogram 3.0 Character API: First Image in 5 Minutes
curl/Python examples for both endpoints (generation + masked editing), parameter tables, and verbatim errors.
- TURBO / image
- $0.09
- Reference
- 1 image
- Output
- WebP
TL;DR
- Ideogram 3.0 Character is a reference-image character generator: upload one character reference, write one scene prompt, and the same face and outfit appear in a new scene. Try it on the model page — new accounts get 200 free credits.
- Pricing is per image: TURBO $0.09, BALANCED $0.13, QUALITY $0.18. References are free; failed tasks refund in full (details on the pricing page).
- Call it through the HiAPI
/v1/tasksendpoint: submit a task, get ataskId, poll for the result, then download fromoutput[0].url.
What it does
- Character consistency: one reference image locks the character — face and outfit stay the same while the scene changes.
- Illustration and photo styles:
styletakes AUTO / REALISTIC / FICTION, so photographed people and illustrated characters both work. - Aspect follows the reference: a portrait reference yields 3:4 (864×1152), a landscape reference 16:9 (1328×752) — no size parameter needed.
- A matching edit endpoint:
ideogram-v3-character/editpaints the character into a masked area of an existing image and leaves the rest untouched.
Here's a real output (the reference was a landscape illustrated character):
The explorer character walking through a lantern-lit night market, holding a paper cup of hot noodles, warm glowing stalls on both sides, storybook illustration, no text, no signs

ideogram-v3-character, TURBO, 16:9, 1328×752, $0.09.
Two endpoints: which to use
ideogram-v3-character |
ideogram-v3-character/edit |
|
|---|---|---|
| What it does | Generates the character in a new scene | Paints the character into a masked area of an existing image |
| Required input | prompt + 1 reference |
prompt + source image + mask + 1 reference |
| Price (TURBO / BALANCED / QUALITY) | $0.09 / $0.13 / $0.18 | $0.09 / $0.13 / $0.18 |
| Output | WebP, aspect follows the reference | WebP, size follows the source image |
| Best for | Posters, serialized stories, scene sets | Swapping or adding a character in a finished image |
Mask convention: black = repaint, white = keep; the mask and source image must share the same aspect ratio. The edit endpoint rejects negative_prompt with a 400.
Two ways to start
Browser, 3 steps: open the model page → upload the character reference and paste the prompt → hit generate. A TURBO image is $0.09.
API, 3 steps: POST /v1/tasks to submit → take the taskId → GET /v1/tasks/<taskId> until success, then download.
curl: your first image
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: your-unique-key-001" \
-d '{
"model": "ideogram-v3-character",
"input": {
"prompt": "The explorer character walking through a lantern-lit night market, holding a paper cup of hot noodles, warm glowing stalls on both sides, storybook illustration, no text, no signs",
"reference_image_urls": [
"https://static.hiapi.ai/gallery/2026/10/156346d531f0b319.jpg"
],
"rendering_speed": "TURBO"
}
}'
For the edit endpoint, switch model to ideogram-v3-character/edit and add image_url (source) and mask_url to input:
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ideogram-v3-character/edit",
"input": {
"prompt": "The explorer character curled up in the armchair asleep under a knitted blanket",
"image_url": "https://static.hiapi.ai/gallery/2026/10/8e1328c02f8edd33.jpg",
"mask_url": "https://static.hiapi.ai/gallery/2026/10/0121b5b1d8af8697.png",
"reference_image_urls": [
"https://static.hiapi.ai/gallery/2026/10/12ccfec91203bec9.jpg"
],
"rendering_speed": "TURBO"
}
}'
The response carries the taskId you'll poll with.
Python: submit, poll, download
import time, uuid, requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
}
payload = {
"model": "ideogram-v3-character",
"input": {
"prompt": "The explorer character walking through a lantern-lit night market, holding a paper cup of hot noodles, warm glowing stalls on both sides, storybook illustration, no text, no signs",
"reference_image_urls": ["https://static.hiapi.ai/gallery/2026/10/156346d531f0b319.jpg"],
"rendering_speed": "TURBO",
},
}
# Submit: the Idempotency-Key makes network retries safe
resp = requests.post(
BASE,
headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
json=payload,
timeout=30,
)
resp.raise_for_status()
task_id = resp.json()["taskId"]
# Poll: queued -> handling -> archiving -> success / fail
while True:
task = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30).json()
print(task["status"])
if task["status"] in ("success", "fail"):
break
time.sleep(3)
if task["status"] == "success":
image_url = task["output"][0]["url"] # temporary URL — download promptly
img = requests.get(image_url, timeout=60)
with open("output.webp", "wb") as f:
f.write(img.content)
print("saved output.webp")
Parameters (ideogram-v3-character)
| Field | Required | Values | Notes |
|---|---|---|---|
prompt |
yes | 1–5,000 chars | Describe the scene the character enters, not the character's looks (the reference carries those) |
reference_image_urls |
yes | exactly 1, JPEG / PNG / WebP, ≤10 MB | Character reference; its aspect sets the output aspect |
rendering_speed |
no | TURBO / BALANCED / QUALITY, default BALANCED | Sets tier and price |
style |
no | AUTO / REALISTIC / FICTION, default AUTO | REALISTIC leans photographic; FICTION keeps the illustrated look |
seed |
no | integer 0–2147483647 | Same inputs + same seed reproduce the image |
expand_prompt |
no | default true | Auto-expands the prompt; pass false to run it verbatim |
negative_prompt |
no | ≤5,000 chars | What to keep out of the image |
The edit endpoint adds two required fields, image_url and mask_url, and drops support for negative_prompt. Any field outside the table returns a 400 (additional properties ... not allowed).
Errors you'll actually hit (verbatim)
| What you did | Response |
|---|---|
Omitted prompt |
400 invalid input: prompt: missing required field "prompt" |
| Sent 2 references | 400 invalid input: reference_image_urls: maxItems: got 2, want 1 |
Misspelled rendering_speed |
400 invalid input: rendering_speed: value must be one of 'TURBO', 'BALANCED', 'QUALITY' |
| Sent an unknown field | 400 invalid input: <root>: additional properties 'foo' not allowed |
Sent negative_prompt to the edit endpoint |
400 invalid input: <root>: additional properties 'negative_prompt' not allowed |
| Out of credits | 402 insufficient account balance; top up and retry |
Re-submitting the same Idempotency-Key returns 409 (still processing) or 422 (payload mismatch); generate a fresh key and retry.
Before you ship
- Callbacks: pass
"callback": {"url": "https://..."}at the request top level and HiAPI notifies your service at the terminal state — no polling needed. - Persist outputs:
output[0].urlis temporary. Download it into your own storage right away; don't treat it as a permanent link. - Be explicit: always send
rendering_speed(omitting it bills at BALANCED), and pick the reference's aspect deliberately — it decides the output's aspect. - Use a unique idempotency key per batch task: give every submission its own
Idempotency-Key; retrying a network failure with the same key hits the same task instead of creating another one or double-charging credits.
FAQ
Can references be plain URLs?
Any reachable http/https address works — JPEG, PNG, or WebP, up to 10 MB.
How many reference images can I send?
Exactly one — a hard rule; two returns a 400. To change the character, change the reference image.
Is there a size parameter?
None — the output aspect follows the reference: portrait references give 864×1152, landscape references 1328×752.
Do both endpoints share one calling convention?
Only model and the input fields change between them.
Do failures cost anything?
Credits held at creation are refunded in full when a task ends in failure.
Next: take the night-market prompt above and generate a test image, browse the prompt guide for scene recipes, and see the pricing page for tiers and budgets.
Related articles
View all articles →-
Tutorial
How to Call hailuo-2.3-fast/image-to-video via the HiAPI API: curl and Python
A first working request for the fast, low-cost image-to-video tier — from model ID to downloaded MP4
9 min read -
Tutorial
How to Use hailuo-2.3/text-to-video via the HiAPI API: curl, Python, and a Working Request
11 min read -
Tutorial
Kandinsky 6.0 Pro Text-to-Video on HiAPI: curl and Python Tutorial
A request-first walkthrough: build the prompt-to-clip call, submit it, poll for completion, and download the result
11 min read