Reaching Ideogram’s models from your own code takes one host and one header: requests go to api.ideogram.ai with an Api-Key header, and no other authentication path is documented. Ideogram 4.0 is served synchronously and asynchronously, and the same account exposes editing and single-purpose image tools. Everything below comes from Ideogram’s own developer reference or pricing page; where the vendor publishes nothing, this page says so.
What the official API exposes
The overview page groups the offering into four capability blocks: Ideogram 4.0, background control, typography, and custom models. It also states that 4.0 is reachable through the app, API workflows, MCP for agents and the open-weights release, and that those surfaces are not interchangeable. The API is the metered server-side path, billed separately from any app subscription. The Ideogram 4.0 hub holds the model-level facts.
Getting access: the documented setup path
The documented setup sequence
Four moves, in order: accept the developer terms, add a payment method, add credits, then create a key in the API dashboard. No separate approval step is documented.
Your subscription does not pay for API calls
The product documentation puts the arrangement in one sentence: “Ideogram user subscriptions and API accounts are separate, with separate payment and billing setup.” Top-ups are one-off amounts of $20, $50 or $100, or a custom amount with a $1 minimum and a $300 ceiling. The getting-started guide covers the app side, and every figure here is dated to 2026-09-13.
Your first request: generate with Ideogram 4.0
Generation is a single multipart POST. The reference names Content-Type: multipart/form-data, and the key travels in an Api-Key header rather than as a bearer token.
# Requires curl and jq; export IDEOGRAM_API_KEY first.
API="https://api.ideogram.ai/v1/ideogram-v4/generate"
# One multipart POST. The key is an Api-Key header, not a bearer token.
curl -s "${API}" \
-H "Api-Key: ${IDEOGRAM_API_KEY}" \
-F 'text_prompt=A poster on a wall with text that reads: "Everything you can imagine is real."' \
-F "resolution=1024x1024" \
-F "enable_copyright_detection=false" \
-o generated.json
# The reply carries data[].url and data[].is_image_safe. Links expire,
# so pull the bytes down in the same run.
jq -r '.data[0].is_image_safe' generated.json
curl -sL -o poster.png "$(jq -r '.data[0].url' generated.json)"
The response holds created and a data array whose entries carry prompt, resolution, is_image_safe, seed and url. Two fields decide how much interpretation happens before the diffusion model runs. text_prompt turns magic prompt on automatically, so your string is expanded first; json_prompt disables it and hands the object to the model directly. The reference marks the two mutually exclusive. rendering_speed=FLASH is coming soon and currently returns a 400. Handle 400, 401, 422 and 429.
Polling, storing and the expiring image URL
Behind a queue, use the asynchronous endpoint: it returns a generation_id immediately, accepts an optional webhook_url query parameter, and is polled through GET /v1/generations/{generation_id}.
import os
import time
import requests
BASE = "https://api.ideogram.ai/v1"
HEADERS = {"Api-Key": os.environ["IDEOGRAM_API_KEY"]}
# Submit and keep the id: it correlates the webhook and drives polling.
submitted = requests.post(
f"{BASE}/ideogram-v4/async/generate",
headers=HEADERS,
params={"webhook_url": "https://example.com/ideogram-webhook"},
data={"text_prompt": "A poster for a night market, bold headline at the top."},
timeout=30,
)
submitted.raise_for_status()
generation_id = submitted.json()["generation_id"]
while True:
status = requests.get(
f"{BASE}/generations/{generation_id}", headers=HEADERS, timeout=30
).json()
if status["status"] != "pending":
break
time.sleep(5)
if status["status"] == "failed":
raise SystemExit(status.get("failure_reason", "generation failed"))
# Ideogram's image links expire, so store the bytes now.
for index, image in enumerate(status["data"]):
if not image["is_image_safe"]:
continue
with open(f"out-{index}.png", "wb") as handle:
handle.write(requests.get(image["url"], timeout=60).content)
The poll response is stricter than it looks: a pending or failed job returns only generation_id, status and created, with no data key at all. A completed response adds response_type and data, so branch on status first.
Image links are temporary, and the documentation is blunt: “Image links created by the Ideogram API expire. If you want to keep the image, you must download it and store it.” No TTL is published, so download inside the same run. Webhooks are optional: webhook_url receives an Ed25519-signed POST once every image finishes, and because retries are capped, keep polling as the fallback.
Typography over the API: text prompts and JSON prompts

Text inside the image is the capability Ideogram leads on, and the API offers two routes. The plain one is a quoted line inside text_prompt: put the words early, wrap them in double quotes, keep the scene simple. The structured one is json_prompt, and the reason for it is stated outright: “Ideogram 4.0 was trained exclusively on structured JSON captions.”
What the caption schema requires
Three top-level fields. high_level_description is strongly recommended, style_description is optional, and compositional_deconstruction is required, carrying background first and then elements. Inside style_description you supply exactly one of photo or art_style, plus aesthetics, lighting and medium; color_palette caps at 16 uppercase #RRGGBB values. Each element is an object ("obj") or a text element ("text"): both carry a desc, text elements add a literal text string, and bbox is optional, formatted [y_min, x_min, y_max, x_max] on a normalised 0–1000 scale.
{
"high_level_description": "A bold event poster for a jazz night called 'Blue Note Sessions'.",
"style_description": {
"aesthetics": "moody, retro, sophisticated",
"lighting": "dramatic, deep shadows, warm spotlight glow",
"medium": "graphic_design",
"art_style": "vintage poster design, textured paper, bold typography",
"color_palette": ["#1A1A2E", "#E8C97A", "#F5F0E8"]
},
"compositional_deconstruction": {
"background": "Deep navy background with subtle aged paper texture.",
"elements": [
{
"type": "text",
"bbox": [30, 50, 140, 950],
"text": "BLUE NOTE SESSIONS",
"desc": "Large bold all-caps headline in warm golden-yellow near the top."
},
{
"type": "obj",
"bbox": [150, 200, 650, 800],
"desc": "A silhouetted jazz trumpeter in side profile, lit from above."
}
]
}
}
Key order is not cosmetic: the model was trained on captions with a consistent order, and keeping it improves quality. Two limits are not negotiable — English renders most accurately, non-Latin scripts often prove unpredictable, and a typeface cannot be requested by name.
The other documented endpoints
Generation is only part of the surface. Editing endpoints take an image plus a prompt. Tool endpoints are named after outcomes rather than models, and take no model id because Ideogram picks the model for each. Custom models are a workflow: create a dataset, upload assets, train, then generate against the resulting URI. Prices are per endpoint and per image, read on 2026-09-13:
| Endpoint | Published unit price |
|---|---|
| Generate, Ideogram 4.0 | $0.03 Turbo, $0.06 Default, $0.10 Quality per image |
| Transparent background, 4.0 | $0.03 at 1K and 2K on Turbo, $0.19 at 4K, $0.35 at 8K |
| Describe | $0.01, and $0.015 for V4 |
| Remove Background | $0.01 |
| Upscale | $0.06 |
| Layerize | $0.09 |
Material pricing changes reach existing developers at least fourteen days in advance, and older model values — V_3_1, V_3_0, V_2_1, V_1_5, V_1_1, V_0_3 and AUTO — still appear for endpoints that accept them.
Rate limits and what Ideogram does not publish
One hard number is published: a default rate limit of 10 in-flight requests, with anything larger routed through partnership@ideogram.ai. No figure is published for that larger tier.
- Output pixels. Dimensions depend on the model, the size tier and the endpoint; no pixel table is published.
- Latency. No per-endpoint figure appears anywhere in the reference.
- Text accuracy. No success rate is published for any language, so any percentage attached to Ideogram typography is a third party’s number.
- Idempotency and lifetime. No dedup key is described for a retried POST, links expire with no published TTL, and webhook retries are capped without a published count.
The Nano Banana Pro API walkthrough covers the same polling and storage habits on the image side.
Third-party gateways are not the official API
Searching for “ideogram api” also returns mirror sites and gateways that resell generation under an Ideogram-like name. Some admit they are third parties; others present themselves as the vendor, which is why this page cites only ideogram.ai, docs.ideogram.ai and developer.ideogram.ai. A gateway’s prices, model list and rate limits are its own claims, not the vendor’s, so we do not restate them. If the base URL is not api.ideogram.ai, the fields above do not apply.
Frequently asked questions
How do I get an Ideogram API key? Accept the developer terms, add a payment method, add credits, then create the key in the API dashboard. It is shown in full once, so store it before closing the page.
Is the API included in an Ideogram subscription? No. Subscriptions and API accounts are separate, with separate payment and billing.
Should I send text_prompt or json_prompt? text_prompt for exploration, because magic prompt expands it for you. json_prompt when layout has to be repeatable, because it disables magic prompt and gives the model the structure you wrote.
Why did my image URL stop working? Because the links expire. Download the bytes as soon as a call returns, and note that regenerating produces a different image. The getting-started guide covers the browser workflow if you would rather try the model before writing code.
Start with the synchronous call to confirm the key and the response shape, move to the async endpoint and polling once a queue exists, and download inside the same run. Those three decisions cover most of what the specification says.