The entire API is one image URL.
No SDK to install, no key to authenticate, no request to sign. Read this page once and you are done — or hand it to your agent and let it write the URL.
Quickstart
Construct a URL and use it as an img src. The first request generates the image; every request after returns it from cache.
<img src="https://{project}.imagegpt.host/image?prompt=A%20sunset%20over%20mountains" alt="Sunset" />prompt is the only required parameter, and a missing one is the only value that fails a request. Everything else has a documented default.
The body is the image. x-cache is EDGE_HIT, R2_HIT, SIMILARITY_HIT, MISS or BYPASS; igpt-credits appears only on a request that actually generated something.
Your host
Every project gets its own subdomain. That host — not a key — is what identifies you, and it can be scoped to the domains you allow-list.
https://{project}.imagegpt.host/imageProject slugs look like {org}-{project}, so a real host reads acme-marketing.imagegpt.host. In code and in agent setups, read the slug from the IMAGEGPT_PROJECT environment variable; fall back to YOUR-PROJECT when it is unset.
/health on the same host answers without generating anything, and every response carries access-control-allow-origin: *, so a browser on any origin can load the image.
Parameters
Query parameters only — no headers, no body, no signing.
Anything else in the query string is passed through to the model that serves the request and coerced against the options it declares — steps, guidance, style, resolution, transparency and so on. Unknown or out-of-range values are replaced, never fatal.
There is no width, height or size: dimensions come from aspect_ratio and the model's own resolution.
Routes & aliases
Use route= to ask for an outcome and let us pick the model — this is the reliable default, because a route can select across models. Use model= when you want a named model; most aliases still have more than one provider behind them. When both are present, route wins.
Aspect ratios
Ratios are written w:h, and the spelling is forgiving — 16x9, 16/9 and 1.7778 are all read as 16:9.
These five work on every model. Another eighteen — 3:2, 4:5, 21:9, 1:2 and so on — are accepted and honoured wherever the chosen model supports them; anywhere else they land on the nearest ratio it does, and the substitution comes back in IGPT-Warning. The per-model list is in the model table and in llms.txt.
There is no API-wide default: omit aspect_ratio and the model's own default applies — usually 1:1. Every URL this site builds sets one explicitly.
Invalid parameters
An unrecognised value never fails the request. These URLs are written once and then fetched by every visitor to a page, so a bad value is replaced with a documented default and a real image is still returned with HTTP 200.
Every substitution is reported in an IGPT-Warning response header, one per parameter:
HTTP/2 200 content-type: image/png igpt-warning: code=PARAM_COERCED; param=aspect_ratio; requested="4:4"; used="1:1" igpt-warning: code=PARAM_DROPPED; param=seed; requested="latest"
PARAM_COERCED means a substitute value was used; PARAM_DROPPED means the parameter was ignored. requested always echoes what you sent. Coercion runs twice — once against every active model, then again against the model that actually serves the request — which is why a warning can name a model-specific substitution. The header is present on cache hits and on responses blocked by policy too.
The only requests that fail are ones that cannot be served at all: a missing prompt, an unknown or disabled project, a request blocked by a policy, or a project past its credit limit. Those return an SVG placeholder image sized to the aspect ratio you asked for — never JSON — with an IGPT-Error header, so your layout still holds and already-generated URLs keep serving.
HTTP/2 402 content-type: image/svg+xml cache-control: no-store x-image-type: placeholder igpt-error: code=CREDIT_LIMIT_REACHED; message="Monthly credit limit of 30,000 credits reached. Enable overages in billing settings to continue." igpt-upgrade-url: https://imagegpt.cloud/dashboard
The codes are VALIDATION_ERROR and INVALID_HOSTNAME (400), PROJECT_NOT_FOUND (404), PROJECT_INACTIVE, POLICY_BLOCKED and FEATURE_UNAVAILABLE (403), SETUP_INCOMPLETE, TRIAL_CREDITS_EXHAUSTED, CREDIT_LIMIT_REACHED, PAYMENT_PAST_DUE and SUBSCRIPTION_CANCELED (402), LIMIT and PROVIDER_LIMIT (429, with Retry-After when there is a hint), and ROUTE_EXHAUSTED, GENERATION_ERROR or INTERNAL_ERROR (500). None of them is billed.
Caching
The cache key is the generation, not the URL: a hash of prompt, route or model, aspect_ratio, seed, image_url, image_input_strength and preset, scoped to your project. Change one of those and you have a new image; add a tracking parameter, or anything else outside that list, and you get the same one back.
A repeat request is answered by whichever layer sees it first: a 304 against your ETag, then the edge cache (x-cache: EDGE_HIT), then durable object storage (R2_HIT) — served from the nearest of 240+ edge nodes in under 50 ms and never billed again. Cached bytes carry cache-control: public, max-age=31536000, immutable, the cache is per project, and cache=false skips every layer when you deliberately want a fresh generation.
Because results are stable, ImageGPT URLs work as permanent asset paths: commit them, put them in emails, render them server-side, or generate thousands at once and let the browser pull each one on demand.
Building URLs in code
Any language that can build a query string can use ImageGPT. In JavaScript, URLSearchParams handles the encoding for you.
function buildImageUrl(prompt, options = {}) {
const project = process.env.IMAGEGPT_PROJECT || "YOUR-PROJECT";
const params = new URLSearchParams({
prompt,
route: options.route || "quality/fast",
aspect_ratio: options.aspectRatio || "16:9",
});
return `https://${project}.imagegpt.host/image?${params}`;
}The same snippet in ten more languages — React, Vue, Svelte, TypeScript, Python, Ruby, Go, Rust, Elixir and plain HTML — is in llms-full.txt, or add ?lang=python to llms.txt for just one.
Agents
Coding agents are first-class users here. There is no SDK surface to learn, so any model that can write a string can ship imagery. Point yours at one of these:
Every HTML page on this site also advertises those files in its headers (X-Llms-Txt and a Link: rel=alternate), so a crawler finds them without reading this page.
Setting up a specific tool? See the agents page — it fills these URLs in with your project and carries the per-tool snippets for Claude Code, Cursor and chat models.