> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knowlify.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Poll video status

> Track render progress and completion of a queued generation job

## Overview

After [creating a video](/api-reference/create-video), use the returned `uuid` to poll for progress. The endpoint accepts the same `X-API-Key` you used to create the job.

```
GET {API_BASE}/v1/videos/{uuid}
```

<Note>
  Your `API_BASE` is shown in the Developer tab of your dashboard. The default production base is `https://api.knowlify.com`.
</Note>

## Authentication

Send your key in the `X-API-Key` header — the same key (personal or organization) that created the job.

```bash theme={null}
X-API-Key: kn_<64 hex chars>
```

See [Authentication](/api-reference/authentication) for details on key issuance, rotation, and JWT alternatives.

## Path parameters

<ParamField path="uuid" type="string" required>
  The job ID returned in `results[].uuid` from `POST /v1/videos`.
</ParamField>

## Code examples

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.knowlify.com/v1/videos/550e8400-e29b-41d4-a716-446655440000" \
    -H "X-API-Key: kn_YOUR_KEY_HERE"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(`https://api.knowlify.com/v1/videos/${uuid}`, {
    headers: { "X-API-Key": "kn_YOUR_KEY_HERE" },
  });
  const status = await res.json();
  if (status.is_complete) {
    console.log("Video ready");
  }
  ```

  ```python Python theme={null}
  import requests

  resp = requests.get(
      f"https://api.knowlify.com/v1/videos/{uuid}",
      headers={"X-API-Key": "kn_YOUR_KEY_HERE"},
      timeout=15,
  )
  resp.raise_for_status()
  status = resp.json()
  if status["is_complete"]:
      print("Video ready")
  ```
</CodeGroup>

## Response

<ResponseField name="uuid" type="string">
  The job ID (echoes the path parameter).
</ResponseField>

<ResponseField name="status" type="string">
  Current pipeline stage. One of: `pending`, `queued`, `voiceover`, `highlevel`, `lowlevel`, `scan_assets`, `generating_frames`, `complete`, `failed`.
</ResponseField>

<ResponseField name="is_complete" type="boolean">
  `true` once rendering finished successfully.
</ResponseField>

<ResponseField name="is_failed" type="boolean">
  `true` if the job stopped due to an unrecoverable error. Inspect `error_message`.
</ResponseField>

<ResponseField name="progress" type="object">
  <Expandable title="progress fields">
    <ResponseField name="stage" type="string">
      Same as top-level `status`.
    </ResponseField>

    <ResponseField name="percent" type="integer">
      Coarse 0–100 progress estimate. Stage-driven, with a finer-grained band during `generating_frames` based on `current_scene` / `total_scenes`.
    </ResponseField>

    <ResponseField name="current_scene" type="integer">
      Scenes rendered so far (only meaningful during `generating_frames`).
    </ResponseField>

    <ResponseField name="total_scenes" type="integer">
      Total scenes for this video.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="error_message" type="string">
  Human-readable failure reason. `null` on healthy jobs.
</ResponseField>

<ResponseField name="task" type="string">
  The original `task` prompt for this job (echoed for convenience).
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO-8601 timestamp when the job was first queued.
</ResponseField>

<ResponseField name="updated_at" type="string">
  ISO-8601 timestamp of the last status change. Use this to detect stalled jobs.
</ResponseField>

#### Example response (mid-render)

```json theme={null}
{
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "generating_frames",
  "is_complete": false,
  "is_failed": false,
  "progress": {
    "stage": "generating_frames",
    "percent": 88,
    "current_scene": 4,
    "total_scenes": 5
  },
  "error_message": null,
  "task": "Explain how HTTPS works in 30 seconds",
  "created_at": "2026-04-25T12:34:56.789012+00:00",
  "updated_at": "2026-04-25T12:36:18.123456+00:00"
}
```

#### Example response (complete)

```json theme={null}
{
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "complete",
  "is_complete": true,
  "is_failed": false,
  "progress": { "stage": "complete", "percent": 100, "current_scene": 5, "total_scenes": 5 },
  "error_message": null,
  "task": "Explain how HTTPS works in 30 seconds",
  "created_at": "2026-04-25T12:34:56.789012+00:00",
  "updated_at": "2026-04-25T12:39:42.500000+00:00"
}
```

<Tip>
  Poll at most once every 5 seconds — status changes are stage-level, not per-frame. Production integrations should subscribe to Supabase realtime updates on the `corporate_engine_v2` table. Reach out for a Supabase anon key scoped to your account.
</Tip>

## Limits & errors

* The same 30 requests / 60 seconds rate limit applies to polling. See [Rate Limits](/api-reference/rate-limits).
* Full status code reference: [Errors](/api-reference/errors).
