Appearance
Polling Jobs
POST /sessions returns immediately with a job_id. Poll the status endpoint until the job reaches a terminal state, then keep polling until output.download_url is available.
Status endpoint
http
GET https://api.motion.so/api/motion/sessions/{job_id}
Authorization: Bearer motion_your_api_keyStatus values
| Status | Meaning |
|---|---|
queued | The job was accepted and is waiting to start. |
created | The backing Mosaic Motion session exists and is preparing to run. |
running | The job is actively generating. |
awaiting_user_input | The job is waiting on user input. API initiated runs auto approve planning stages where possible. |
completed | The job finished successfully. |
failed | The job failed. Check the error field. |
Polling interval
Start with a 2 to 5 second interval. Increase the interval for long-running jobs.
There is no separate public output or download endpoint. The status response includes output: null until the job is completed. After completion, output.status moves through pending, queued, or processing; the MP4 is ready when output.status === "completed" and output.download_url is non-null.
The same status response can include sources, an additive array of source assets currently used in the composition. Use this to audit where media came from without exposing internal storage paths. Each source includes a category (source_kind), provider, source/display URLs when available, rights status, and usages entries with timestamps and scene/composition placement.
js
async function waitForMotionJob(jobId, apiKey) {
while (true) {
const response = await fetch(
`https://api.motion.so/api/motion/sessions/${jobId}`,
{
headers: {
Authorization: `Bearer ${apiKey}`,
},
},
)
const job = await response.json()
if (job.status === 'failed') {
return job
}
if (job.output?.status === 'completed' && job.output?.download_url) return job
await new Promise((resolve) => setTimeout(resolve, 3000))
}
}