HiAPI
  • Models
  • Pricing
Search

Search HiAPI models, tools, and resources.

LoginGet Started
  • Models
  • Pricing
HiAPI

One API, All AI Models

Generate images, video, and audio with leading models through one production-ready API.

Get a free API key

AI Image API

  • All image models
  • GPT Image 2
  • Nano Banana 2
  • Seedream 5.0 Pro
  • Qwen Image 2.0 Pro
  • FLUX 1.1 Pro

AI Video API

  • All video models
  • Seedance 2.5
  • FLUX.3 Video
  • Seedance 2.0
  • Veo 3.1
  • Kling 3.0

AI Audio API

  • All audio models
  • MiniMax Music 2.6
  • MiniMax Music 1.5
  • ElevenLabs v3
  • Text to music
  • Text to speech

Product

  • Model marketplace
  • Playground
  • Pricing
  • Image API Cost Calculator
  • Free GPT Image 2 Generator
  • Free Nano Banana Image Generator
  • Outfit Preview
  • Product Photo Lab

Developers

  • Documentation
  • API Reference
  • Agent Skills
  • LLM integration index
  • Blog

Company

  • About
  • Contact support
  • Terms of Service
  • Privacy Policy

© 2026 hiapi. All rights reserved.

Open source on GitHubPython SDK on PyPI
  • What you're building, and what you need
  • The minimal request: curl
  • The parameters ideogram-v4 actually accepts
  • A complete Python script
  • Production notes: callbacks, idempotency, and errors
  • Related reading
  • FAQ
TutorialJul 7, 2026

How to use ideogram-v4 via the hiapi API: curl, Python, and a working request

hiapiideogram-v4Image APITutorialTypography

Latest models

Explore models

Contents
  • What you're building, and what you need
  • The minimal request: curl
  • The parameters ideogram-v4 actually accepts
  • A complete Python script
  • Production notes: callbacks, idempotency, and errors
  • Related reading
  • FAQ

Generate it with HiAPI

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

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

Ideogram models built their reputation on one thing most image models still fumble: typography. Posters where the headline is spelled correctly, logos with clean lettering, signage that doesn't dissolve into alphabet soup. ideogram-v4 is available on hiapi through the same unified task API as every other image and video model, and this guide walks through the exact request: a copy-paste curl version, a complete Python script, the parameters the schema actually validates (they are not the same surface as Ideogram's native API), and the errors you'll hit in practice.

What you're building, and what you need

Goal: send a text prompt to POST /v1/tasks, wait for the task to finish, and download an image whose text renders the way you asked.

You need exactly one thing: a hiapi API key — create one in the dashboard. It's used as a Bearer token on every request. There is no free unauthenticated tier; every call below assumes Authorization: Bearer sk-....

Like all models on hiapi, ideogram-v4 is asynchronous: you create a task, get a taskId back immediately, and then either poll for the result or receive a callback. There is no synchronous "wait 40 seconds on one HTTP connection" mode — and you don't want one for image generation anyway.

The minimal request: curl

Create the task:

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": "A vintage art-deco poster for a jazz festival. Headline text \"MIDNIGHT & BRASS\" in bold gold lettering on deep navy, subtitle \"Live at the Riverside, Fridays\" in a thin sans-serif underneath.",
      "rendering_speed": "BALANCED",
      "aspect_ratio": "3:4"
    }
  }'

The response comes back immediately with a task id in data.taskId (it looks like tk-hiapi-...). Poll it:

curl https://api.hiapi.ai/v1/tasks/tk-hiapi-XXXXXXXX \
  -H "Authorization: Bearer $HIAPI_KEY"

While the image is being generated, data.status moves through queued and handling. On a terminal state it becomes success or fail. On success, the image URL is at data.output[0].url:

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-XXXXXXXX",
    "status": "success",
    "output": [
      { "url": "https://.../result.png?...expireAt=..." }
    ]
  }
}

One thing to notice in that URL: it's signed and it expires (expireAt). Download the bytes as soon as the task succeeds and store them on your own storage. Never save the hot link in your database.

The parameters ideogram-v4 actually accepts

This is the part worth being precise about. If you've read Ideogram's own documentation, you know its native API exposes style presets, magic-prompt toggles, negative prompts, and batch counts. hiapi's task schema for ideogram-v4 is deliberately smaller, and the validator rejects anything outside it. Here is the full surface, confirmed against the live API:

FieldRequiredType / values
promptyesstring
rendering_speedyes"TURBO", "BALANCED", "QUALITY"
aspect_rationo"1:1", "16:9", "4:3", "9:16", "3:4"
seednointeger

Both required fields are enforced. Send an empty input and you get:

invalid input: prompt: missing required field "prompt";
rendering_speed: missing required field "rendering_speed"

Misspell an enum value and the error tells you the legal set:

invalid input: rendering_speed: value must be one of 'TURBO', 'BALANCED', 'QUALITY'

And anything from Ideogram's native surface that isn't in the table above is rejected as an unknown property — style_type, magic_prompt, negative_prompt, num_images, size, and image inputs all return a 400 like:

invalid input: <root>: additional properties 'style_type' not allowed

Practical consequences:

  • Typography control lives entirely in the prompt. Put the exact text you want rendered in double quotes inside the prompt, and describe the lettering ("bold art-deco lettering", "thin geometric sans-serif", "hand-painted sign lettering"). This is how you get the poster/logo/signage results Ideogram is known for — there is no separate style parameter to lean on.
  • One image per task. There's no n or num_images. If you want four candidates, submit four tasks and poll each taskId.
  • seed is your reproducibility knob. Same prompt + same seed gives you a stable starting point for iterating on wording.
  • Text-to-image only. The schema does not accept reference images on this model. If your workflow needs image-to-image, pick a model that supports it — see how to call multiple image models with one API key for switching models without changing your integration.

On rendering_speed: TURBO is the fast tier for drafts while you iterate on prompt wording; QUALITY is the slow, careful tier for the final render; BALANCED is the sensible default. Pricing is usage-based per image — check current numbers on the pricing page.

A complete Python script

The same flow — create, poll, download — with timeouts and terminal-state handling. Only dependency is 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=('Minimal logo for a coffee brand called "Driftwood", '
                'the word Driftwood in a warm serif wordmark, single-color, '
                'cream background'),
        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   # signed URL expires - download now
    with open("driftwood-logo.png", "wb") as f:
        f.write(png)
    print("saved driftwood-logo.png,", len(png), "bytes")

Production notes: callbacks, idempotency, and errors

Polling vs. callback. For an interactive tool generating one image at a time, polling every few seconds is simpler and perfectly fine. For batch or server-side workloads, add a callback to the create request so hiapi POSTs the terminal result to you instead:

{
  "model": "ideogram-v4",
  "input": { "prompt": "...", "rendering_speed": "BALANCED" },
  "callback": { "url": "https://your.domain.example/hiapi/hook", "when": "final" }
}

Two constraints, both enforced at create time: the URL must be https:// and reachable from the public internet, and when accepts only "final" — the API literally responds invalid callback.when: only 'final' is supported if you try anything else. Make your handler idempotent on taskId, return 2xx fast, and keep a polling fallback for tasks whose callback never lands. If a callback doesn't arrive, work through why your hiapi task callback isn't firing before blaming the queue.

Idempotency. Creating a task is not idempotent — every successful POST /v1/tasks is a new task and a new charge. Store the taskId against your own job id the moment you receive it, and on any later retry, poll the stored taskId instead of resubmitting.

The errors you'll actually see.

  • 401 with "code": "permission_denied" — the key is invalid or can't use this model. The message says exactly that: "This API key cannot use the selected model. Please check permissions or use another key." Fix it in the dashboard, don't retry.
  • 400 with "error_code": "INVALID_REQUEST" — a validation failure. The message names the exact field and the legal values; read it, fix the payload. Retrying the same body will fail forever.
  • 404 "task not found" on GET /v1/tasks/{id} — wrong task id, or a task created with a different key.
  • fail status on a task that was accepted — inspect data.error.code / data.error.message from the poll response. These are safe to retry as a new task.

Related reading

  • ideogram-v4 model page — capabilities and current pricing tier
  • Why your hiapi task callback isn't firing — the callback debugging checklist
  • How to call multiple image models with one API key — same task API, different model string
  • Cheapest image generation API — how to compare real per-image cost across models
  • API docs — full POST /v1/tasks / GET /v1/tasks/{id} reference

FAQ

Does ideogram-v4 on hiapi support image-to-image or reference images? No. The task schema for this model accepts only prompt, rendering_speed, aspect_ratio, and seed — any image-input field is rejected with a 400. Use a model with image-to-image support (e.g. the gpt-image-2 family) if you need to edit or restyle an existing image.

Which rendering_speed should I use? Iterate with TURBO while you're refining the prompt and the exact wording of the text, then re-render the winner with QUALITY and the same seed. BALANCED is a fine default when you only render once.

How do I make ideogram-v4 render exact text? Put the literal text in double quotes inside the prompt and describe the typography around it: headline text "SUMMER SALE" in heavy condensed sans-serif. Shorter strings render more reliably than full sentences; if a long line comes out mangled, split it into a headline and a subtitle.

Can I generate several images in one request? No — one task produces one image. Submit multiple tasks in parallel instead; each gets its own taskId and queues independently.

Why do I get 401 permission_denied even though my key works with other models? Model access is per-key. Check the key's model permissions in the dashboard, or create a new key with access to ideogram-v4.

How long is the output URL valid? It's a signed URL with an expireAt timestamp. Treat it as minutes, not days: download the image as soon as the task reaches success and store the file yourself.

What aspect ratios are available? Exactly five: 1:1, 16:9, 4:3, 9:16, and 3:4. There is no free-form size parameter — a request with size is rejected as an unknown property.

Latest models

View all models
  • GPT Image 2From $0.007/image
  • Nano Banana 2From $0.051/image
  • Seedream 5.0 ProFrom $0.050/image
  • Seedance 2.5From $0.121/s

Explore models

TextImageVideoAudio
Back to blog
GPT Image 2From $0.007/image
Nano Banana 2From $0.051/image
Seedream 5.0 ProFrom $0.050/image
Seedance 2.5From $0.121/s
View all models
TextChat and reasoning
ImageGenerate and edit
VideoText and image to video
AudioSpeech and music
Start generating
View model pricing
View all articles
How to Use the flux-3 API for Text-to-Video, Audio, and Continuation

How to Use the flux-3 API for Text-to-Video, Audio, and Continuation

minimax-music-3 API: curl & Python Guide

minimax-music-3 API: curl & Python Guide

How to use grok-imagine-image-2.0/image-to-image via the hiapi API: curl, Python, and a working request

How to use grok-imagine-image-2.0/image-to-image via the hiapi API: curl, Python, and a working request

How to Use grok-imagine-image-2.0/text-to-image via the hiapi API: curl, Python, and a Working Request

How to Use grok-imagine-image-2.0/text-to-image via the hiapi API: curl, Python, and a Working Request

How to Use the qwen-image-3.0 API: curl, Python, and a Working Request

How to Use the qwen-image-3.0 API: curl, Python, and a Working Request

How to Use qwen-image-3.0-pro via the hiapi API: curl, Python, and a Working Request

How to Use qwen-image-3.0-pro via the hiapi API: curl, Python, and a Working Request

Start generating