api
a small REST API for generating and managing images. JSON in, JSON out, with a bearer key and a transparent credit ledger.
base url
all endpoints are relative to the versioned base url.
https://imaagine.app/api/v1authentication
pass your key as a bearer token. keys are prefixed imgn_ and created in the dashboard.
curl https://imaagine.app/api/v1/whoami \
-H "Authorization: Bearer imgn_abcd1234_sk_..."attribution headers
send optional client attribution headers so usage is grouped by surface in your ledger.
X-Imaagine-Client: cli/1.4.0
X-Imaagine-Source: cli # cli · api · web
X-Imaagine-Request-Id: <uuid> # echoed back for tracingendpoints
/whoamiidentify the authenticated account and key.
{
"account_id": "acct_2b71",
"key_prefix": "imgn_8fa20c",
"scopes": ["images:generate", "images:read", "usage:read"]
}/modelslist model aliases with resolutions and credit costs.
{
"models": [
{
"alias": "basic",
"resolutions": ["1K", "2K", "4K"],
"credit_cost": { "1K": 3, "2K": 6, "4K": 12 }
}
]
}/usagecurrent credit balance and recent spend.
{
"available": 62,
"reserved": 3,
"lifetime_granted": 100,
"lifetime_spent": 35
}/images/generationsgenerate an image from a text prompt.
{
"prompt": "isometric server rack, blueprint style",
"model": "basic",
"aspect_ratio": "1:1",
"resolution": "1K",
"visibility": "public"
}{
"image": {
"id": "img_8fa20c",
"status": "completed",
"model": "basic",
"aspect_ratio": "1:1",
"resolution": "1K",
"width": 1024,
"height": 1024,
"visibility": "public",
"public_url": "https://cdn.imaagine.app/i/8fa20c"
},
"credits": { "charged": 3, "available": 59, "reserved": 0 }
}/images/editsedit an existing image with a prompt.
{
"image_id": "img_8fa20c",
"prompt": "warmer palette, add soft grain",
"model": "edit-basic",
"visibility": "private"
}{
"image": {
"id": "img_91ab3d",
"status": "completed",
"parent_id": "img_8fa20c",
"visibility": "private"
},
"credits": { "charged": 3, "available": 56, "reserved": 0 }
}/jobs/:idpoll an async job's status.
{
"id": "job_44ce",
"status": "completed",
"image_id": "img_8fa20c"
}/images/:id/download-urlmint a short-lived signed url for a private image.
{
"url": "https://files.imaagine.app/…?sig=…",
"expires_at": "2026-06-07T12:00:00Z"
}error codes
errors share a stable shape: { code, message, details?, requestId? }.
| code | http | meaning |
|---|---|---|
| unauthorized | 401 | missing or invalid api key |
| forbidden | 403 | key lacks the required scope |
| validation_error | 422 | invalid request body or parameters |
| insufficient_credits | 402 | not enough credits to reserve |
| rate_limited | 429 | too many requests; back off |
| idempotency_conflict | 409 | key reused with a different payload |
| moderation_blocked | 422 | prompt or output blocked by safety |
| provider_unavailable | 503 | upstream provider down; reservation released |
| generation_failed | 502 | provider returned an error |
| not_found | 404 | resource does not exist |
| internal_error | 500 | unexpected server error |
idempotency
pass an Idempotency-Key header on generation requests. retries with the same key return the original result instead of charging again; reusing a key with a different body yields idempotency_conflict.
curl https://imaagine.app/api/v1/images/generations \
-H "Authorization: Bearer imgn_abcd1234_sk_..." \
-H "Idempotency-Key: 4f9c-build-8821" \
-H "Content-Type: application/json" \
-d '{ "prompt": "…", "model": "basic", "resolution": "1K" }'rate limits
limits are per key. when exceeded you receive rate_limited (429) with a Retry-After header — back off and retry.
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1717761600
Retry-After: 12new to the API? start with the CLI docs →.