
Read Imagine video progress while polling
Surface approximate completion while a video job is still pending so your queue UI, worker logs, or operator dashboard can show percent done instead of a silent wait. Official REST reference for GET https://api.x.ai/v1/videos/{request_id} documents an optional progress field: while status is pending, progress sits between 0 and 99; when status is done, progress is 100; when status is failed, progress is omitted. Pair this with the same start-and-poll flow covered in Poll Imagine video manually with start and get. Create a key and load credits at console.x.ai before you bill a generation that you will monitor.
What you need
An XAI_API_KEY with Console balance, a generation or edit request that already returns a request_id, and a place to print or store the percent between polls. The xAI Python SDK's blocking generate() hides status checks for you; read progress when you poll REST yourself or when you call start() / get() and inspect the raw deferred result. Sleep a few seconds between checks — official examples use about five seconds — so you do not hammer the status endpoint.
Poll and print progress
- Export the key locally and keep it out of chat logs and public repos:
export XAI_API_KEY="your_api_key"
- Start a generation and capture
request_id:
REQUEST_ID=$(curl -s -X POST https://api.x.ai/v1/videos/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $XAI_API_KEY" \
-d '{
"model": "grok-imagine-video-1.5",
"prompt": "A cat lounging in a sunbeam, tail gently swishing",
"duration": 5,
"aspect_ratio": "16:9",
"resolution": "720p"
}' | jq -r '.request_id')
echo "Request ID: $REQUEST_ID"
- Loop on the status endpoint and read both
statusandprogress:
while true; do
RESULT=$(curl -s "https://api.x.ai/v1/videos/$REQUEST_ID" \
-H "Authorization: Bearer $XAI_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.status')
PROGRESS=$(echo "$RESULT" | jq -r '.progress // empty')
echo "status=$STATUS progress=${PROGRESS:-n/a}"
if [ "$STATUS" = "done" ]; then
echo "$RESULT" | jq -r '.video.url'
break
elif [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ]; then
echo "$RESULT" | jq .
break
fi
sleep 5
done
- Treat progress as approximate completion for UX only — gate retries and downloads on
status, not on a specific percent. - When generation fails, read the
error.code/error.messageobject instead of waiting for progress; see Handle Imagine video generation errors.
After the generate
Log request_id with the final progress line so support can correlate a slow job. If you need a longer wait or calmer interval on the SDK's blocking helpers, use Customize Imagine video SDK poll timeout and interval. Download the temporary video.url promptly once status is done, and confirm Check respect_moderation on Imagine video before you publish the file.
Pitfalls
Driving business logic off progress alone fails when the field is missing on failed or briefly unset. Polling every few hundred milliseconds wastes quota and still will not finish the encode faster. Ignoring expired and failed while staring at a stuck percent leaves workers looping forever. Mixing Console API spend with SuperGrok weekly Imagine quotas on grok.com confuses two meters. Pasting keys into tickets or committing them to git forces a rotate.