sangtao.ai
API key

Jobs

Get a job

One job: its status and progress while it runs, its results once done.

GEThttps://api.sangtao.ai/v2/jobs/{jobId}

Authorization

  • X-Api-Keystring · headerrequired

    Your API key, from the API keys page of your account.

Path parameters

  • jobIdstringrequired

    The jobId in the path.

Every endpoint that creates a job — GPT Image (POST /images/generations) — returns a jobId. Poll this endpoint to track progress and get results.

For an image job, GET /images/generations/{jobId} gives the same answer — use whichever you like. That route only finds image jobs: any other job is 404 JOB_NOT_FOUND there.

Job Flow

StatusDescriptionAction
pendingJob queued, waiting to startContinue polling
processingJob running, progress updates availableShow progress bar
completeDone! Results available in resultUrl / resultImagesDisplay results
errorFailed. Error message in error fieldShow error + retry option

A GPT Image job starts at "WaitingForAgent" (waiting for a machine), not "pending" — treat it like pending and keep polling.

Response Fields

jobIdstring

Unique job identifier

typestring

The kind of job: "AgentJob" for GPT Image, "RenderVideo" for a custom render. The same value the type filter of GET /jobs takes.

categorystring

The group the kind belongs to, e.g. "agent".

typeDisplayNamestring

The kind as a name to show, e.g. "Agent Job".

titlestring

The job's title. null for jobs that have none — image jobs have none.

promptstring

The prompt you sent. Filled in the list (GET /jobs); here it is null — read params.prompt.

statusstring

"WaitingForAgent" | "processing" | "complete" | "error". Compare case-insensitively — this endpoint answers lowercase while some others answer "Complete".

progressnumber

0 to 100. Measured: it stays at 0 until the job finishes, so it is not a live progress bar.

stepstring

Current step of a multi-step job. null for image jobs.

resultUrlstring

The finished image or video. null until complete. The link holds for seven days — download and store it yourself if you need it longer.

resultImagesstring[]

The same results as an array.

resultDataobject

Details of the output — resultUrl, imageUrls (an array), width, height and durationMs (numbers), and thumbnailUrl when the job has one.

thumbnailUrlstring

Thumbnail, for video jobs.

hasDownloadableAssetsboolean

true when the job has files to download.

queuePositionnumber

While the job waits for a machine: how many jobs not yet picked up are ahead of it (0 = next). null once it is running or done.

etaSecondsnumber

While waiting: about how many seconds until a machine starts it. null when there is not enough data yet, or once it is running.

etaCompleteSecondsnumber

While waiting or running: about how many seconds until the result is ready. null when there is not enough data yet, or once it is done.

errorstring

Why it failed, in plain language. null when it did not.

failureKindstring

The machine-readable reason. This is the field that decides whether a retry is worth anything.

elapsedSecondsnumber

How long it took. Around 13s for a plain image in this measurement.

creditCostnumber

Once settled, what was actually charged. A failed job is refunded automatically, so it shows 0. While the job runs, the amount locked for it. 0 when a monthly plan covered it.

paramsobject

What you sent, for checking. For an image job only the fields you sent, with their proper types (numbers, true/false, arrays); referenceImages are your original links.

createdAtstring

When the job was accepted; processingAt when a machine picked it up; completedAt when it finished.

modelstring

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

resolvedModelstring

The model that ran the job, e.g. "gpt-image-2.6" — fixed when the job was created.

serverstring

The server it ran on: "standard".

retryCountnumber

How many times we retried it internally. Not something you control.

webhookobject

Only when the request had webhookUrl: how its latest delivery went. Never inside the webhook’s own data

Response Examples

Processing:

json
{
  "success": true,
  "data": {
    "jobId": "acff47cbfacf4e27bbc08770c9ea246d",
    "type": "AgentJob",
    "status": "processing",
    "progress": 0,
    "step": null,
    "queuePosition": null,
    "etaSeconds": null,
    "etaCompleteSeconds": 25
  }
}

Complete:

json
{
  "success": true,
  "data": {
    "jobId": "acff47cbfacf4e27bbc08770c9ea246d",
    "type": "AgentJob",
    "category": "agent",
    "typeDisplayName": "Agent Job",
    "title": null,
    "prompt": null,
    "status": "complete",
    "progress": 100.0,
    "resultUrl": "https://cdn.sangtao.ai/agent-jobs/acff47cb.../fa3c91.png",
    "resultImages": [
      "https://cdn.sangtao.ai/agent-jobs/acff47cb.../fa3c91.png"
    ],
    "resultData": {
      "resultUrl": "https://cdn.sangtao.ai/agent-jobs/acff47cb.../fa3c91.png",
      "imageUrls": [
        "https://cdn.sangtao.ai/agent-jobs/acff47cb.../fa3c91.png"
      ],
      "width": 1024,
      "height": 1024,
      "durationMs": 13100
    },
    "error": null,
    "failureKind": null,
    "hasDownloadableAssets": true,
    "queuePosition": null,
    "etaSeconds": null,
    "etaCompleteSeconds": null,
    "elapsedSeconds": 13.1,
    "creditCost": 0.0,
    "createdAt": "2026-09-19T09:42:59Z",
    "processingAt": "2026-09-19T09:43:17Z",
    "completedAt": "2026-09-19T09:43:30Z",
    "model": "gpt-image-latest",
    "resolvedModel": "gpt-image-2.6",
    "server": "standard"
  }
}

Error:

json
{
  "success": true,
  "data": {
    "jobId": "acff47cbfacf4e27bbc08770c9ea246d",
    "status": "error",
    "step": null,
    "failureKind": "PROMPT_UNCLEAR",
    "error": "The prompt is not clear enough to create an image. Describe the image you want more specifically.",
    "creditCost": 0
  }
}

Sent with webhookUrl, also:

json
{
  "webhook": {
    "url": "https://example.com/webhooks/sangtao",
    "status": "succeeded",
    "attemptCount": 1,
    "lastHttpStatus": 200,
    "lastError": null,
    "deliveryId": "dlv_7Fz2kWq4N"
  }
}

Errors

StatuserrorCodeWhen
404JOB_NOT_FOUNDNo job of yours with this jobId

A failed job is not an error of this call: it answers 200 with status "error" (above).

Polling Intervals

Wait about ten seconds before the first poll — nothing finishes faster than that, so an immediate one always comes back unfinished.

Job TypeRecommended IntervalTypical Duration
GPT Image5 seconds30–90 seconds

Full example

for i in $(seq 60); do
  R=$(curl -sS https://api.sangtao.ai/v2/jobs/$JOB \
    -H "X-Api-Key: YOUR_KEY")
  S=$(echo "$R" | jq -r '.data.status' | tr 'A-Z' 'a-z')

  [ "$S" = "complete" ] && {
    echo "$R" | jq -r '.data.resultUrl'; break
  }
  [ "$S" = "error" ] && {
    echo "$R" | jq -r '.data.error'; break
  }
  sleep 5
done
GET/jobs/{jobId}
curl "https://api.sangtao.ai/v2/jobs/acff47cbfacf4e27bbc08770c9ea246d" \
  -H "X-Api-Key: YOUR_API_KEY"
{
  "success": true,
  "data": {
    "jobId": "acff47cbfacf4e27bbc08770c9ea246d",
    "type": "AgentJob",
    "category": "agent",
    "typeDisplayName": "Agent Job",
    "title": null,
    "prompt": null,
    "status": "complete",
    "progress": 100,
    "resultUrl": "https://cdn.sangtao.ai/agent-jobs/acff47cb.../fa3c91.png",
    "resultImages": [
      "https://cdn.sangtao.ai/agent-jobs/acff47cb.../fa3c91.png"
    ],
    "resultData": {
      "resultUrl": "https://cdn.sangtao.ai/agent-jobs/acff47cb.../fa3c91.png",
      "imageUrls": [
        "https://cdn.sangtao.ai/agent-jobs/acff47cb.../fa3c91.png"
      ],
      "width": 1024,
      "height": 1024,
      "durationMs": 13100
    },
    "error": null,
    "failureKind": null,
    "hasDownloadableAssets": true,
    "queuePosition": null,
    "etaSeconds": null,
    "etaCompleteSeconds": null,
    "elapsedSeconds": 13.1,
    "creditCost": 0,
    "createdAt": "2026-09-19T09:42:59Z",
    "processingAt": "2026-09-19T09:43:17Z",
    "completedAt": "2026-09-19T09:43:30Z",
    "model": "gpt-image-latest",
    "resolvedModel": "gpt-image-2.6",
    "server": "standard"
  }
}