Job Polling
https://sangtao.ai/api/v2/jobs/{jobId}Reference for Job Polling.
All generation endpoints (image, video, voiceover, etc.) return a jobId. Poll this endpoint to track progress and get results.
Job Flow
| Status | Description | Action |
|---|---|---|
| pending | Job queued, waiting to start | Continue polling |
| processing | Job running, progress updates available | Show progress bar |
| complete | Done! Results available in resultUrl / resultImages | Display results |
| error | Failed. Error message in error field | Show error + retry option |
Response Fields
jobIdstringUnique job identifier
statusstring"WaitingForAgent" | "processing" | "complete" | "error". Compare case-insensitively — this endpoint answers lowercase while some others answer "Complete".
progressnumber0 to 100. Measured: it stays at 0 until the job finishes, so it is not a live progress bar.
stepstringCurrent step, for multi-step jobs like voiceover. null for image jobs.
resultUrlstringThe 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.
resultDataobjectDetails of the output — resultUrl, imageUrls, width, height, durationMs.
thumbnailUrlstringThumbnail, for video jobs.
errorstringWhy it failed, in plain language. null when it did not.
failureKindstringThe machine-readable reason. This is the field that decides whether a retry is worth anything.
elapsedSecondsnumberHow long it took. Around 13s for a plain image in this measurement.
creditCostnumberActual cost, settled on completion. 0 when a monthly plan covered it. A failed job is not charged — credits are refunded automatically.
paramsobjectThe request as we stored it — useful for checking what was actually sent.
createdAtstringWhen the job was accepted; processingAt when a machine picked it up; completedAt when it finished.
retryCountnumberHow many times we retried it internally. Not something you control.
Response Examples
Processing:
{
"success": true,
"data": {
"jobId": "abc-123",
"status": "processing",
"progress": 60,
"step": "generating_images"
}
}Complete (video):
{
"success": true,
"data": {
"jobId": "abc-123",
"status": "complete",
"resultUrl": "https://cdn.sangtao.ai/videos/result.mp4",
"thumbnailUrl": "https://cdn.sangtao.ai/videos/thumb.jpg",
"creditCost": 8
}
}Complete (image):
{
"success": true,
"data": {
"jobId": "img-456",
"status": "complete",
"resultImages": [
"https://cdn.sangtao.ai/images/result1.jpg",
"https://cdn.sangtao.ai/images/result2.jpg"
],
"creditCost": 1
}
}Error:
{
"success": true,
"data": {
"jobId": "abc-123",
"status": "error",
"error": "Content moderation: prompt contains unsafe content"
}
}Polling Intervals
Wait about ten seconds before the first poll — nothing finishes faster than that, so an immediate one always comes back unfinished.
| Job Type | Recommended Interval | Typical Duration |
|---|---|---|
| Image Generation | 5 seconds | 13-90 seconds |
| Video Generation | 5 seconds | 30s - 3 minutes |
| Voiceover Video | 3 seconds | 1-5 minutes |
| Stock Video | 3 seconds | 1-3 minutes |
| Article to Video | 5 seconds | 2-5 minutes |
Step Names (Voiceover/Stock Video)
| Step | Description |
|---|---|
| generating_script | AI is writing/splitting the script into scenes |
| generating_voice | Text-to-speech narration is being generated |
| generating_images | AI images are being created for each scene |
| searching_stock | Finding stock footage for each scene |
| rendering | Final video is being rendered |
Full example
for i in $(seq 60); do
R=$(curl -sS https://sangtao.ai/api/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