---
title: "Start playback"
method: POST
path: "/projects/{id}/layers/{layerId}/play"
tags: ["Playback"]
---

# Start playback

`POST /projects/{id}/layers/{layerId}/play`

## Request

- Base URL: `https://api.livereacting.com/v1/external`
- URL: `https://api.livereacting.com/v1/external/projects/{id}/layers/{layerId}/play`
- Auth: HTTP bearer

Start playback on a layer. Supports `video`, `videoPlaylist`, and `audioPlaylist` layers.

## Request Body by Layer Type

**Video layers (`type: "video"`)**: Use `VideoPlayRequest` schema
- No file identifier needed (single file)
- Optional `startFrom` to seek to position
- Optional `switchScene` to auto-switch scenes

```json
{ "startFrom": 30, "switchScene": false }
```

**Playlist layers (`type: "videoPlaylist"` or `"audioPlaylist"`)**: Use `PlaylistPlayRequest` schema
- Requires exactly **one** file identifier: `playlistItemId`, `fileId`, or `index`
- The `playlistItemId` is recommended for precise targeting. For simple cases like playing the first file, you can use `index: 0`
- Optional `startFrom` to seek to position (video playlists only, ignored for audio)
- Optional `switchScene` to auto-switch scenes

```json
{ "playlistItemId": "file_1706123456789_42", "startFrom": 30 }
```

## File Identifiers (Playlist Layers Only)

| Identifier | Description | When to use |
|------------|-------------|-------------|
| `playlistItemId` | Unique ID of the playlist item | Always unambiguous, best for automation |
| `fileId` | Original file ID | Works if file appears once in playlist |
| `index` | Zero-based position | Simple sequential playback |

### Ambiguous Files
If a file appears multiple times in the playlist (e.g., same intro video repeated), using `fileId` returns a `409 AMBIGUOUS_FILE` error with details about which `playlistItemId` values to use instead.

## Scene Switching
If the layer is in a different scene than the currently active scene:
- **Without `switchScene: true`**: Returns `409 LAYER_NOT_IN_ACTIVE_SCENE` with scene details
- **With `switchScene: true`**: Automatically switches to the layer's scene, then plays

Pinned layers (visible on all scenes) bypass this check entirely.

## Playback Position
Use `startFrom` to seek to a specific position (in seconds). Works for both `video` and `videoPlaylist` layers. Ignored for `audioPlaylist`. Default is `0` (start from beginning).

## Auto-sync
If the project has auto-sync enabled and is live, the playback change is automatically pushed to the stream.

## Path parameters

- `id` string, required
- `layerId` string, required

## Request body

- object
  - `playlistItemId` string: Unique playlist item ID (from GET layer response)
  - `fileId` string: Original file ID (24-char hex). Must be unambiguous.
  - `index` integer: Zero-based position in playlist
  - `switchScene` boolean: Auto-switch to layer's scene if not active
  - `startFrom` number: Start position in seconds

## Response `200`

Playback started successfully

- object
  - `layerId` string: Layer ID
  - `playlistItemId` string: Playlist item ID that started playing
  - `fileName` string, nullable: File name
  - `fileId` string: Original file ID
  - `index` integer: Position in playlist
  - `startedFrom` number: Position playback started from (seconds)
  - `duration` number: File duration in seconds
  - `isPlaying` boolean: Always true on success
  - `sceneSwitched` boolean: Whether scene was switched
  - `activeSceneId` string, nullable: Currently active scene ID
  - `activeSceneName` string, nullable: Currently active scene name
  - `synced` boolean: Whether change was synced to live stream

## Other responses

- `400`: Validation error
- `401`: Authentication failed
- `404`: Resource not found
- `409`: Conflict
- `429`: Rate limit exceeded

---

[API](https://skmtc.dev/livereacting/apis/livereacting-api.md) · [All operations](https://skmtc.dev/livereacting/apis/livereacting-api/llms.txt) · [OpenAPI document](https://skmtc.dev/livereacting/apis/livereacting-api/revisions/17a9f1677fbf?raw)
