# Get the storyboard

`GET https://api.vidmoat.com/v1/projects/{id}/storyboard`

- Scope: `projects.read`
- Cost: Free

The project's scenes in timeline order. A scene stores intent (title, script, voice, footage, look, captions, target length); its span comes from the clips that carry its `sceneId`, so it is always current. Includes the board's problems and a quote per unbuilt scene.

> **Note.** Edit scenes with the scene commands on POST /v1/projects/{id}/commands: addScene, updateScene, moveScene, removeScene, splitScene, mergeScenes, assignToScene.

### Path parameters

- `id` (string, required): The project id.

## Response

Returns `200`.

### Response fields

- `hasStoryboard` (boolean): Whether the project has a board.
- `scenes` (array): `{ id, index, title, start, end, seconds, targetSeconds?, script?, voice?, footage?, captions?, locked?, clipIds, placeholders, built, review? }` in timeline order. `start`/`end` are null for an empty scene.
- `problems` (array): `{ sceneId?, severity, code, message }`: empty scenes, placeholder slots, overlaps, a scene far from its target, captions asked for and missing.
- `estimate` (object): `{ scenes: [{ sceneId, steps, credits, built }], total, remaining }` for a run of the unbuilt scenes.
- `nextScene` (string or null): The first unbuilt scene.

## Errors

Besides the errors any request can get ([authentication](https://developer.vidmoat.com/developer/docs/authentication#when-a-request-is-refused), [rate limits](https://developer.vidmoat.com/developer/docs/rate-limits)):

| Status | Code | When |
| --- | --- | --- |
| 404 | [`not_found`](https://developer.vidmoat.com/developer/docs/errors#not_found) | No such project, or it is not yours. The two are indistinguishable on purpose. |

## Request examples

```bash curl
curl https://api.vidmoat.com/v1/projects/$ID/storyboard \
  -H "Authorization: Bearer $VIDMOAT_KEY"
```

```js Node
const ID = 'YOUR_PROJECT_ID';

const res = await fetch(`https://api.vidmoat.com/v1/projects/${ID}/storyboard`, {
  headers: {
    Authorization: `Bearer ${process.env.VIDMOAT_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error?.message ?? `HTTP ${res.status}`);
console.log(data);
```

```python Python
import os
import requests

ID = "YOUR_PROJECT_ID"

res = requests.get(
    f"https://api.vidmoat.com/v1/projects/{ID}/storyboard",
    headers={"Authorization": f"Bearer {os.environ['VIDMOAT_KEY']}"},
    timeout=60,
)
res.raise_for_status()
print(res.json())
```

## Example response

```json
{
  "projectId": "cm1abc",
  "hasStoryboard": true,
  "scenes": [{ "id": "sc_hook0001", "index": 0, "title": "Hook", "start": 0, "end": 3, "seconds": 3, "targetSeconds": 3, "clipIds": ["slot_1"], "placeholders": 1, "built": false }],
  "problems": [{ "sceneId": "sc_hook0001", "severity": "warning", "code": "placeholder", "message": "Scene 1 (Hook) still has 1 empty slot to replace with footage." }],
  "estimate": { "scenes": [{ "sceneId": "sc_hook0001", "steps": 4, "credits": 14, "built": false }], "total": 14, "remaining": 1 },
  "nextScene": "sc_hook0001"
}
```

---

Source: https://developer.vidmoat.com/developer/docs/api/projects/get-storyboard
Previous: [Validate commands](https://developer.vidmoat.com/developer/docs/api/projects/validate-commands.md)
Next: [Create a storyboard](https://developer.vidmoat.com/developer/docs/api/projects/create-storyboard.md)
All documentation: https://developer.vidmoat.com/llms-full.txt
