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.
FAQ
- Yes, references can be plain URLs — any reachable http/https address, JPEG, PNG, or WebP, up to 10 MB.
- No, there's no size parameter. The output aspect follows the reference: portrait references give 864×1152, landscape references 1328×752.
- Yes, both endpoints share one calling convention — only
modeland theinputfields change. - No, failures don't cost anything. Credits held at creation are refunded in full at the terminal failure state.
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.





