sangtao.ai
API key

Create

GPT Image

Generate images with the latest GPT Image model.

POSThttps://api.sangtao.ai/v2/images/generations

Headers

X-Api-Keystringrequired

Your API key. Create one on the API Key page in your account.

Content-Typestringrequired

application/json

Request

Each job returns 1 image, sometimes 2 for A/B testing.

modelstringrequired

The model. gpt-image-latest is always the current GPT Image; gpt-image-2.6 pins this version.

Available options:gpt-image-latestgpt-image-2.6

promptstringrequired

What to draw — the scene, the style, the composition. One or two words ("blue square") comes back as PROMPT_UNCLEAR.

serverstringoptionaldefault "standard"

Where the job runs. Leave it out for the default.

Available options:standard

aspectRatiostringoptionaldefault "auto"

"auto" lets the model choose; any W:H works too (1–100 each, no flatter than 3:1).

Suggested:auto1:11:33:11:22:19:1616:910:1616:102:33:23:44:34:55:4

formatstringoptionaldefault "png"

The image file type.

Available options:pngjpeg

referenceImagesstring[]optional

Up to 20 image links (http/https) to draw from. A link that does not exist is refused before any credit is locked. An image on your machine: upload it first.

resolutionstringoptionaldefault "original"

Image size. original keeps the model’s image (16:9 is 1672×941); 1k / 2k make the long edge about 1024 / 2048px.

Available options:original1k2k

requireTransparentbooloptional

Ask for a transparent background.

dpiintoptional

1–1200. Print metadata only — the pixel size stays the same.

idempotencyKeystringoptional

Sent again with the same key and the same body within 24 hours, the call returns the same job (idempotentReplay: true) and charges nothing again; with another body, 422 IDEMPOTENCY_KEY_REUSED. A new key per new image (a UUID, say) — send an old one again only to retry that exact request. The Idempotency-Key header works too.

webhookUrlstringoptional

A public https URL (port 443) to POST this job’s result to when it is done — see Webhook. A bad URL is 422 INVALID_WEBHOOK_URL, before anything is created or charged

webhookSecretstringoptional

Signs those deliveries (X-Sangtao-Signature). Up to 200 characters. Without it they come unsigned

A missing or wrong value is refused before any job is made and before any credits are locked, with 422 rather than 400, and an errorCode: MODEL_REQUIRED, PROMPT_REQUIRED, MODEL_WRONG_CATEGORY, SERVER_NOT_FOUND, INVALID_ASPECT_RATIO, INVALID_FORMAT, INVALID_RESOLUTION (RESOLUTION_NOT_SUPPORTED for 4k), INVALID_DPI, REFERENCE_IMAGE_UNREACHABLE, INVALID_WEBHOOK_URL (webhookUrl), or IDEMPOTENCY_KEY_REUSED (an idempotencyKey already used for another body). An unknown model name is 404 MODEL_NOT_FOUND. A value of the wrong type (dpi: "abc") is 400 VALIDATION_ERROR, with details[0].code INVALID_TYPE.

Response

jobIdstring

The job id. Pass it to GET /images/generations/{jobId} to poll for the result. Store it against your own order or record — it is the only handle you have on the job afterwards.

statusstring

"WaitingForAgent" for a new job — queued, not running yet. On a replay, the job's status now: it may already be "Processing" or "complete".

chargeSourcestring

"Subscription" when a monthly plan covers it, "Credit" when it is paid from your balance.

creditCostnumber

What this job costs. 0 when a plan covered it. On a replay, the original job's cost — not charged again.

quotaRemainingnumber

Plan allowance left after this job. null when credits paid; null on a replay (idempotentReplay).

queuePositionnumber

How many jobs not yet picked up by a machine are ahead of this one — including jobs about to start within seconds. The same meaning as in GET /jobs/{id}. To know whether it runs right away, check runningJobs < concurrency. null on a replay (idempotentReplay).

queueDepthnumber

How many jobs the queue holds in total. null on a replay (idempotentReplay).

runningJobsnumber

Your jobs running right now. null on a replay (idempotentReplay).

concurrencynumber

How many of your jobs may run at once. Extra jobs queue rather than fail. null on a replay (idempotentReplay).

capReasonstring

Why that concurrency figure. null on a replay (idempotentReplay).

Available options:subscription planaccount limitworker capacitysystem default

runningOnFallbackbool

Whether a backup machine pool took the job. null in the normal case; null on a replay (idempotentReplay).

modelstring

The model name exactly as you sent it, e.g. "gpt-image-latest".

resolvedModelstring

The model that actually runs the job, e.g. "gpt-image-2.6". Fixed when the job is created: if gpt-image-latest later moves to a newer version, this job still says the one it ran on.

serverstring

The server the job runs on: "standard".

idempotentReplaybool

true only when this answers a repeated idempotencyKey: the job was made earlier, nothing new was created or charged. Absent otherwise.

Then poll with the jobId until status is "complete" or "error" — the next page: GET /images/generations/{jobId}.

Errors while running

A failed job comes back with status "error" and a failureKind. This is the field that decides whether retrying is worth anything — retrying a permanent failure only burns more money.

failureKindMeaningRetry?
PROMPT_UNCLEARDescription too vagueNo — change the prompt
CONTENT_REJECTEDAgainst the content policyNo — change the prompt
TRANSPARENT_CREATION_FAILEDTransparency asked for, image came back without alphaNo — be more explicit in the prompt
REFERENCE_DOWNLOAD_FAILEDCould not fetch a reference imageNo — fix the link
GENERATION_TIMEOUTRan out of timeYes — usually works
QUOTA_EXHAUSTEDTemporarily at capacityYes — after a few hours
SESSION_EXPIREDA problem on our side, not with your requestContact support
INVALID_PAYLOADA problem on our sideContact support
POST/images/generations
curl -X POST \
  https://api.sangtao.ai/v2/images/generations \
  -H "X-Api-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-latest",
    "prompt": "A vintage travel poster of Ha Long Bay at sunset",
    "aspectRatio": "9:16",
    "resolution": "2k"
  }'
{
  "success": true,
  "data": {
    "jobId": "acff47cbfacf4e27bbc08770c9ea246d",
    "status": "WaitingForAgent",
    "chargeSource": "Subscription",
    "creditCost": 0.0,
    "quotaRemaining": 966,
    "queuePosition": 0,
    "queueDepth": 50,
    "runningJobs": 0,
    "concurrency": 10,
    "capReason": "subscription plan",
    "runningOnFallback": null,
    "model": "gpt-image-latest",
    "resolvedModel": "gpt-image-2.6",
    "server": "standard"
  },
  "error": null,
  "errorCode": null
}