Search

Search HiAPI models, tools, and resources.

Back to blog
Tutorial6 min read

How to Use Ideogram 4.5 API: Generation and Precise Text Edits

ideogram-v4.5/text-to-image plus /image-to-image editing: curl/Python examples, parameters, and Precise Edit.

HiAPI EditorialIdeogram 4.5API IntegrationTypography

TL;DR

  • Ideogram 4.5 is a typography-first family: ideogram-v4.5/text-to-image generates posters, wordmarks, and bilingual packaging with in-image text, while ideogram-v4.5/image-to-image offers Precise Edit for surgical text changes, reference-image restyling, and masked local edits. Choose a task on the model page, or use the API examples below.
  • Pricing is per image and tiered: LOW $0.043, MEDIUM (default) $0.086, HIGH $0.3145; editing adds VERY_LOW at $0.0115; each request returns 1 image; num_images must be 1. See the pricing guide.
  • Everything runs on HiAPI /v1/tasks: submit and read data.taskId, query data.status, then download the type=image entry from data.output on success.

What it does

  • Organize text hierarchy: quote the required words and specify positions for the headline, subtitle, date, and lineup. Proofread the generated text.
  • Single-image composition tests: each request returns 1 image. Vary the prompt or seed and submit separate tasks for alternatives.
  • A matching editor: Precise Edit (edit_precision=high) supports focused changes such as names or dates; compare preserved areas with the source.
  • References and masks: up to 4 references (3 with a mask); mask black repaints, white keeps.

Here's a real LOW-tier output:

Minimal modern brand poster for a design conference. Huge bold headline text "DESIGN FORWARD" centered, smaller subtitle "Typography Summit 2026" below, clean Swiss grid layout, warm orange and deep navy palette, geometric shapes, crisp sharp lettering

DESIGN FORWARD brand poster

ideogram-v4.5/text-to-image, LOW, landscape_16_9, 1280×720, $0.043.

Try this prompt →

Two endpoints: which to use

ideogram-v4.5/text-to-imageideogram-v4.5/image-to-image
What it doesGenerates typeset frames from textEdits existing images
Required inputpromptimage_url + prompt
Quality tierslow / medium / highvery_low / low / medium / high
Special parametersnum_images: 1, enable_prompt_expansionedit_precision (Precise), reference_image_urls, mask_url
Size6 presets, default square_hdauto (default) or 6 presets; masks and Precise are auto-only
Best forPosters, logos, packaging, signage draftsText fixes, recolors, seasonal variants, local repaints

Typical pipeline: generate the brand poster, then use Edit to swap in each client's name and date. A LOW generation ($0.043) plus a Precise LOW edit ($0.043) is $0.086 a set.

Two ways to start

Browser, 3 steps: open the model page → paste the prompt, pick a tier → generate.

API, 3 steps: POST /v1/tasks to submit → read data.taskId → query until data.status is success, then download.

curl: your first image

Set HIAPI_IDEMPOTENCY_KEY in the terminal to a unique ID for this business operation and reuse it for retries. This example explicitly selects LOW, a landscape size, and expansion enabled.

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $HIAPI_IDEMPOTENCY_KEY" \
  -d '{
  "model": "ideogram-v4.5/text-to-image",
  "input": {
    "prompt": "Minimal modern brand poster for a design conference. Huge bold headline text \"DESIGN FORWARD\" centered, smaller subtitle \"Typography Summit 2026\" below, clean Swiss grid layout, warm orange and deep navy palette, geometric shapes, crisp sharp lettering",
    "quality": "low",
    "image_size": "landscape_16_9",
    "enable_prompt_expansion": true,
    "num_images": 1
  }
}'

For editing, switch model to ideogram-v4.5/image-to-image with a source image and instruction. This Precise Edit request asks for a text change while keeping the layout; compare the output with the source:

Set a separate HIAPI_EDIT_IDEMPOTENCY_KEY for this editing operation; do not reuse the generation task’s key.

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $HIAPI_EDIT_IDEMPOTENCY_KEY" \
  -d '{
  "model": "ideogram-v4.5/image-to-image",
  "input": {
    "prompt": "Change the logo text from \"Ember & Oak\" to \"Maple & Co\", keep the same serif lettering style, emblem, tagline, colors and layout exactly unchanged",
    "image_url": "https://static.hiapi.ai/gallery/2026/10/88567ad2baf46b32.png",
    "edit_precision": "high",
    "quality": "low",
    "image_size": "auto",
    "num_images": 1
  }
}'

Python: submit, poll, download

Install requests and set HIAPI_API_KEY. For a new submission, also set HIAPI_IDEMPOTENCY_KEY: use a unique value for each new business operation and keep it unchanged for retries. The program prints the task ID first. After an interruption, set HIAPI_TASK_ID to resume polling and downloading without submitting another generation task.

import os
import time
from pathlib import Path

import requests

BASE = "https://api.hiapi.ai/v1/tasks"
headers = {"Authorization": "Bearer " + os.environ["HIAPI_API_KEY"]}
payload = {
    "model": "ideogram-v4.5/text-to-image",
    "input": {
        "prompt": "Minimal modern brand poster for a design conference. Huge bold headline text \"DESIGN FORWARD\" centered, smaller subtitle \"Typography Summit 2026\" below, clean Swiss grid layout, warm orange and deep navy palette, geometric shapes, crisp sharp lettering",
        "quality": "low",
        "image_size": "landscape_16_9",
        "enable_prompt_expansion": True,
        "num_images": 1,
    },
}
# Set HIAPI_TASK_ID to resume polling without creating another task.
task_id = os.environ.get("HIAPI_TASK_ID")
if not task_id:
    # Use one unique key per business operation; keep it for retries.
    submission_key = os.environ["HIAPI_IDEMPOTENCY_KEY"]
    response = requests.post(
        BASE, headers={**headers, "Idempotency-Key": submission_key},
        json=payload, timeout=30,
    )
    response.raise_for_status()
    created = response.json()
    if created.get("code") != 200:
        raise RuntimeError(created)
    task_id = created["data"]["taskId"]
print("Keep this task ID:", task_id, flush=True)

deadline = time.monotonic() + 600
while time.monotonic() < deadline:
    response = requests.get(f"{BASE}/{task_id}", headers=headers, timeout=30)
    response.raise_for_status()
    result = response.json()
    if result.get("code") != 200:
        raise RuntimeError(result)
    task = result["data"]
    if task["status"] in ("fail", "failed"):
        raise RuntimeError(task.get("error", task))
    if task["status"] == "success":
        image_url = next(
            (item["url"] for item in task.get("output", [])
             if item.get("type") == "image" and item.get("url")), None,
        )
        if not image_url:
            raise RuntimeError("Successful task has no image URL")
        # Do not forward API authorization to the media download host.
        image = requests.get(image_url, timeout=60)
        image.raise_for_status()
        media_type = image.headers.get("Content-Type", "").split(";", 1)[0].lower()
        suffix = {"image/png": ".png", "image/jpeg": ".jpg",
                  "image/webp": ".webp"}.get(media_type)
        if not suffix:
            raise RuntimeError("Unexpected image content type: " + media_type)
        target = Path(task_id + suffix)
        partial = target.with_suffix(suffix + ".part")
        partial.write_bytes(image.content)
        partial.replace(target)
        print("Saved:", target)
        break
    time.sleep(3)
else:
    raise TimeoutError(f"Polling timed out; keep checking task {task_id}")

If a query or download has a network error, resume with the printed task ID; the script does not automatically repeat task creation. It polls for up to 600 seconds with 3-second waits, downloads to a .part file, and renames it only when complete.

Parameters

Generation: ideogram-v4.5/text-to-image

FieldRequiredValuesNotes
promptyes1–10,000 charsFour parts: the job → text and palette → layout → finish and limits
qualitynolow / medium / high, default mediumlow for exploration, medium daily, high for small-type finals
image_sizeno6 presets, default square_hdNo custom sizes
num_imagesnoMust be 1One output image per task
enable_prompt_expansionnodefault truePrompt expansion; false disables expansion, but output text still needs checking
seednointegerReproduce with identical inputs

Editing: ideogram-v4.5/image-to-image

FieldRequiredValuesNotes
image_urlyesimage URLSource image
promptyes1–10,000 charsThe change; state what stays
edit_precisionnoregular / high, default regularhigh = Precise Edit, for focused text changes
qualitynovery_low / low / medium / high, default mediumvery_low works with regular only
image_sizenoauto or 6 presets, default autoMasks and Precise are auto-only
reference_image_urlsnoup to 4At most 3 when a mask is supplied
mask_urlnoimage URLBlack repaints, white keeps
num_imagesnoMust be 1One output image per task
seednointeger

Unknown fields inside input return 400; top-level fields such as model and callback follow the task-endpoint format.

Errors you'll actually hit

StatusMeaningWhat to do
400 INVALID_REQUESTMalformed body (missing prompt or image_url, bad enum, unknown field)Fix the payload against the tables
402 INSUFFICIENT_QUOTAOut of credits (no charge)Top up and retry
429 RATE_LIMITEDRate limitedSlow your submissions
409 IDEMPOTENCY_KEY_PROCESSINGA task is being created for this keyWait and retry the same key and body
422 IDEMPOTENCY_KEY_MISMATCHThe key was reused with a different bodyRestore the original body; use a new key only for a new task

Terminal failures may include CONTENT_POLICY_VIOLATION, TASK_FAILED, and TASK_TIMEOUT. Keep the taskId and error, then reconcile the final task state with the account record. A query or download failure does not establish generation failure.

Before you ship

  • Callbacks: pass "callback": {"url": "https://..."} at the request top level.
  • Persist outputs: result URLs in data.output expire; download them after success.
  • Single-image tasks and idempotency: each task returns 1 image. Reuse the same key for retries of the same logical submission; assign a new key only to a new task.
  • Small Chinese text: compare tiers using your actual copy, and proofread before delivery. Medium or high is not a substitute for checking.

FAQ

How many images can one request generate?

Generation and editing currently return 1 image per task; num_images must be 1. Submit separate tasks for alternatives.

Is LOW the default quality tier?

No. MEDIUM is the default at $0.086 per image. Set quality: "low" explicitly for LOW at $0.043.

Which mode fits a brand-name or date change?

Use Precise Edit with explicit edit_precision: "high", quality: "low", and image_size: "auto", at $0.043 per image.

What do black and white mask regions mean?

Black regions are repainted and white regions are kept. Match the mask to the source dimensions and choose image_size: "auto" with a mask.

Should a timeout retry use a new idempotency key?

Not for the same logical submission. Reuse the same Idempotency-Key and body; use a new key only when you intend to create a new task.

Next: take the DESIGN FORWARD prompt, generate a poster, then swap in your own event name with one Precise instruction. Related: quality-tier prices and budgets · 4 editing prompt examples.

Generate it with HiAPI

Choose a model, enter your prompt, and see the result.

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

Start generating