/status/{uuid}
Poll the status of a video generation job. Call this endpoint repeatedly after submitting a generation request until the done field is true. When complete, the response includes the permanent video URL and thumbnail.
Poll every 3–5 seconds
Do not poll faster than once every 3 seconds. Generation typically takes 60–180 seconds depending on frame count and server load. The progress field (0–100) gives a rough estimate of completion.
Endpoint
GET https://coals.ai/api/v1/magicoal/status/{uuid}
Processing Stages
| Stage | Applies To | Progress Range | Description |
|---|---|---|---|
| generating_image | T2V only | 5–20% | FLUX is synthesizing the keyframe image from the text prompt. |
| uploading_image | T2V only | 20–25% | The generated keyframe is being prepared and transferred to the animation worker. |
| generating_video | I2V and T2V | 25–90% | Wan2.2 is generating video frames. This is the longest stage. |
| saving | I2V and T2V | 90–100% | Video frames are being encoded, saved to storage, and a thumbnail is generated. |
| completed | I2V and T2V | 100% | done: true — video_url and thumbnail_url are populated. |
For I2V jobs, stages begin at generating_video (25%) since there is no image generation step.
Response — In Progress
{ "success": true, "data": { "uuid": "3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d", "type": "i2v", "status": "generating_video", "stage": "generating_video", "progress": 54, "done": false, "video_url": null, "thumbnail_url": null, "credits_charged": 50.0, "created_at": "2026-03-03T14:22:11Z" } }
Response — Completed
{ "success": true, "data": { "uuid": "3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d", "type": "i2v", "status": "completed", "stage": "completed", "progress": 100, "done": true, "video_url": "https://coals.ai/storage/videos/3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d.mp4", "thumbnail_url": "https://coals.ai/storage/thumbnails/3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d.jpg", "duration_seconds": 5.0625, "credits_charged": 50.0, "created_at": "2026-03-03T14:22:11Z", "completed_at": "2026-03-03T14:24:38Z" } }
When done is true, the video_url and thumbnail_url are permanent and can be embedded or downloaded directly.
Credit refunds: Credits are charged upfront at submission. If the job reaches a failed status for any reason, the full credit amount is refunded to your account automatically — no action required.
curl https://coals.ai/api/v1/magicoal/status/3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d \ -H "Authorization: Bearer YOUR_API_KEY"
// Using Guzzle $response = $client->get('https://coals.ai/api/v1/magicoal/status/3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d', [ 'headers' => ['Authorization' => 'Bearer YOUR_API_KEY'] ]); $data = json_decode($response->getBody(), true);
# Using requests import requests response = requests.get( "https://coals.ai/api/v1/magicoal/status/3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d", headers={"Authorization": "Bearer YOUR_API_KEY"} ) data = response.json()
# Using net/http require "net/http" require "json" uri = URI("https://coals.ai/api/v1/magicoal/status/3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer YOUR_API_KEY" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } data = JSON.parse(res.body)
// Using fetch (Node 18+) const response = await fetch("https://coals.ai/api/v1/magicoal/status/3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d", { method: "GET", headers: { "Authorization": "Bearer YOUR_API_KEY" } }); const data = await response.json();