Skip to main content
POST
/
v1
/
images
/
generations
Image Generations
curl --request POST \
  --url https://kymaapi.com/v1/images/generations \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "model": "<string>",
  "prompt": "<string>",
  "n": 123,
  "size": "<string>",
  "image_url": "<string>",
  "idempotency_key": "<string>",
  "extra": {}
}
'
{
  "id": "<string>",
  "status": "<string>",
  "estimated_cost": 123,
  "charged_amount": {}
}
Async endpoint. The request returns immediately with a job_id; the actual generation runs in the background and is charged on success only.

Request body

model
string
required
One of: flux-1.1-ultra, flux-kontext-pro, ideogram-v3, recraft-v3. See Image Generation.
prompt
string
required
Text prompt describing the desired image. Maximum 4000 characters.
n
number
default:"1"
Number of images to generate. Range 1–4. Each image is billed at the model’s per-image rate.
size
string
Output dimensions or aspect ratio. Accepted forms: "auto", "WIDTHxHEIGHT" (e.g. "1024x1024"), or an aspect string like "16:9". Mapped to one of the canonical aspect ratios: 1:1, 16:9, 9:16, 4:3, 3:4, 21:9. Unrecognized sizes use the model default.
image_url
string
HTTPS URL of the source image. Required for flux-kontext-pro (image-edit model). Ignored by text-to-image models. A kontext request without image_url returns 400 image_url_required.
idempotency_key
string
Client-supplied key (≤128 chars) to make the request safe to retry. Repeated POSTs with the same (api_key, idempotency_key) pair return the same job — no duplicate charge, no duplicate generation.
extra
object
Pass-through model-specific parameters (e.g. seed, style). Forwarded to the underlying provider unchanged.

Response

202 Accepted for new jobs, 200 OK if the same idempotency_key is replayed.
{
  "id": "f3a9c8b2e1d0a4b6c7d8e9f0",
  "object": "image.job",
  "status": "pending",
  "model": "flux-1.1-ultra",
  "created_at": "2026-04-25T10:00:00.000Z",
  "completed_at": null,
  "output": null,
  "error": null,
  "estimated_cost": 0.081,
  "charged_amount": null
}
id
string
Job ID. Use it to poll GET /v1/jobs/{id}.
status
string
One of: pending, processing, succeeded, failed, refunded, expired.
estimated_cost
number
Hold amount placed at submit time (USD). Refunded if the job fails.
charged_amount
number | null
Final billed amount once the job succeeds. null until then.

Poll for the result

GET /v1/jobs/{id}
Same response shape. Poll every 1–2 seconds until status is succeeded, failed, refunded, or expired. Most images complete within 30 seconds; the runner times out at 5 minutes.
{
  "id": "f3a9c8b2e1d0a4b6c7d8e9f0",
  "object": "image.job",
  "status": "succeeded",
  "model": "flux-1.1-ultra",
  "created_at": "2026-04-25T10:00:00.000Z",
  "completed_at": "2026-04-25T10:00:14.220Z",
  "output": {
    "url": "https://blob.vercel-storage.com/.../image.jpg",
    "metadata": { "images": [{ "width": 1920, "height": 1080, "content_type": "image/jpeg" }] }
  },
  "error": null,
  "estimated_cost": 0.081,
  "charged_amount": 0.081
}
The output.url points to a Vercel Blob URL hosted by Kyma — the original upstream URL is rehosted so it remains stable after the upstream TTL expires.

Errors

Statuserror.codeWhen
400invalid_modelModel is not a supported image model
400invalid_promptMissing prompt or > 4000 chars
400image_url_requiredflux-kontext-pro called without image_url
401auth_errorMissing or invalid API key
402insufficient_balanceHold could not be placed
413invalid_requestRequest body > 25 MB
429rate_limitedTier limit exceeded
500db_error / provider_errorInternal failure — hold is fully refunded
When status becomes failed or refunded, no charge is made and the held funds are returned to your balance via a hold_release ledger entry.

Examples

Cinematic hero shot

curl -X POST https://kymaapi.com/v1/images/generations \
  -H "Authorization: Bearer $KYMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-1.1-ultra",
    "prompt": "an architectural photo of a modernist house at dusk, long exposure",
    "size": "16:9"
  }'

Image edit with kontext

curl -X POST https://kymaapi.com/v1/images/generations \
  -H "Authorization: Bearer $KYMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-kontext-pro",
    "prompt": "replace the sky with a stormy sunset",
    "image_url": "https://example.com/source.jpg"
  }'

Idempotent retry

curl -X POST https://kymaapi.com/v1/images/generations \
  -H "Authorization: Bearer $KYMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ideogram-v3",
    "prompt": "minimalist coffee bag label that reads KYMA ROAST",
    "idempotency_key": "order-78421-asset-1"
  }'
Replaying this exact request returns the same job — no new charge.