---
title: "Create a layer"
method: POST
path: "/projects/{id}/layers"
tags: ["Layers"]
---

# Create a layer

`POST /projects/{id}/layers`

## Request

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

Create a new layer in a specific scene. Supports `video`, `videoPlaylist`, and `audioPlaylist` layer types.

## Quick Start
```json
{
  "sceneId": "507f1f77bcf86cd799439011",
  "type": "videoPlaylist",
  "name": "My Playlist",
  "settings": {
    "volume": 10,
    "files": [{ "fileId": "507f1f77bcf86cd799439013" }]
  }
}
```

`sceneId` and `type` are required. Everything else has sensible defaults — position defaults to centered full-screen, and name defaults based on type.

## Layer Types

| Type | Required settings | Description |
|------|-------------------|-------------|
| `video` | `fileId` | Single video file layer |
| `videoPlaylist` | — | Video playlist with optional ad points and name overlay |
| `audioPlaylist` | — | Audio playlist with optional cover image |

For the full list of available settings per type, see the **Settings by Layer Type** table in the [Update Layer](#tag/Layers/operation/updateLayer) endpoint.

## Limits
- Maximum **800 layers** per project
- Maximum **600 files** per playlist

## Copy/Paste Workflow
To duplicate a layer:
1. `GET /projects/{id}/layers/{layerId}` — get full layer config
2. Modify as needed
3. `POST /projects/{id}/layers` — create with the copied config

## Path parameters

- `id` string, required

## Request body

- object
  - `sceneId` string, required: Scene ID to add the layer to
  - `type` 'video' | 'videoPlaylist' | 'audioPlaylist', required: Layer type. - `video`: Single video file layer (requires `settings.fileId`) - `videoPlaylist`: Video playlist with optional ad points and name position overlay - `audioPlaylist`: Audio playlist with optional cover image display
  - `name` string: Layer name (1-19 characters)
  - `hide` boolean: Whether layer is hidden
  - `pinned` boolean: Whether layer appears on all scenes
  - `locked` boolean: Whether layer is locked from editing
  - `position` Position (unresolved $ref)
  - `settings` Settings (unresolved $ref)

## Response `201`

Layer created successfully. The layer detail plus `synced`

- union
  - object: Video playlist layer with multiple video files.
    - `id` string: Unique layer identifier
    - `name` string, nullable: Layer name
    - `hide` boolean: Whether layer is hidden
    - `pinned` boolean: Whether layer appears on all scenes
    - `locked` boolean: Whether layer is locked from editing
    - `position` object: Layer position and size in pixels of the project's current resolution. After a resolution change (for example 720p to 1080p), the values are scaled to the new one.
      - `x` number
      - `y` number
      - `width` number: Width in native resolution (e.g., 1920 for full-width on 1080p)
      - `height` number: Height in native resolution (e.g., 1080 for full-height on 1080p)
    - `type` 'videoPlaylist', required: Layer type identifier
    - `settings` object, required
      - `volume` integer: Audio volume (0-10)
      - `loop` boolean: Loop playlist when it ends
      - `nextScene` string, nullable: Scene ID to switch to when playlist ends
      - `showFileName` boolean: Display file name overlay
      - `showProgressBar` boolean: Show playback progress bar
      - `namePosition` 'bottom left' | 'top left' | 'bottom right' | 'top right' | 'center top' | 'center bottom', nullable: Position of the file name overlay
      - `textStylePreset` 'preset_simple' | 'glassmorphism' | 'gradient_modern' | 'professional' | 'preset1' | 'neon_glow' | 'elegant_serif' | 'dark_contrast' | 'retro_80s' | 'preset6' | 'preset5' | 'preset4' | 'sport_dynamic': Text style preset for file name overlay
      - `textStyles` object: Custom text styling (see UpdateLayerRequest for full schema)
      - `shuffle` boolean: Enable shuffle/random playback order
      - `adPlaceholder` object, nullable: Video placeholder shown during ad breaks. Null when not configured or disabled.
        - `enabled` boolean, required: Whether the ad placeholder is active
        - `fileId` string, required: ID of the placeholder video file
        - `fileName` string, required: Name of the placeholder video file
        - `duration` number, required: Duration of the placeholder video in seconds
      - `files` PlaylistFileItem[], required: Playlist files
        - `playlistItemId` string: Unique playlist item ID. Use this with the play endpoint for precise targeting.
        - `fileId` string: Reference to original File model (24-char hex ID)
        - `name` string: File display name
        - `duration` number: Duration in seconds
        - `isPlaying` boolean: Whether file is currently playing
        - `adPoints` object[]: Ad break points within this video
          - `timestamp` number: Start time in seconds
          - `duration` number: Duration in seconds (5-120)
    - `synced` boolean: Whether the new layer reached a LIVE or PREPARING stream (auto-sync on). A scheduled stream reads the project when it starts
  - object: Audio playlist layer with multiple audio files.
    - `id` string: Unique layer identifier
    - `name` string, nullable: Layer name
    - `hide` boolean: Whether layer is hidden
    - `pinned` boolean: Whether layer appears on all scenes
    - `locked` boolean: Whether layer is locked from editing
    - `position` object: Layer position and size in pixels of the project's current resolution. After a resolution change (for example 720p to 1080p), the values are scaled to the new one.
      - `x` number
      - `y` number
      - `width` number: Width in native resolution (e.g., 1920 for full-width on 1080p)
      - `height` number: Height in native resolution (e.g., 1080 for full-height on 1080p)
    - `type` 'audioPlaylist', required: Layer type identifier
    - `settings` object, required
      - `volume` integer: Audio volume (0-10)
      - `loop` boolean: Loop playlist when it ends
      - `nextScene` string, nullable: Scene ID to switch to when playlist ends
      - `showFileName` boolean: Display file name overlay
      - `showProgressBar` boolean: Show playback progress bar
      - `showCoverImage` boolean: Display album art/cover image
      - `coverImageSize` integer: Size of cover image in pixels
      - `shuffle` boolean: Enable shuffle/random playback order
      - `textStylePreset` 'preset_simple' | 'glassmorphism' | 'gradient_modern' | 'professional' | 'preset1' | 'neon_glow' | 'elegant_serif' | 'dark_contrast' | 'retro_80s' | 'preset6' | 'preset5' | 'preset4' | 'sport_dynamic': Text style preset for file name overlay
      - `textStyles` object: Custom text styling (see UpdateLayerRequest for full schema)
      - `files` AudioPlaylistFileItem[], required: Playlist files
        - `playlistItemId` string: Unique playlist item ID
        - `fileId` string: Reference to original File model
        - `name` string: File display name
        - `duration` number: Duration in seconds
        - `isPlaying` boolean: Whether file is currently playing
    - `synced` boolean: Whether the new layer reached a LIVE or PREPARING stream (auto-sync on). A scheduled stream reads the project when it starts
  - object: Video layer with a single video file.
    - `id` string: Unique layer identifier
    - `name` string, nullable: Layer name
    - `hide` boolean: Whether layer is hidden
    - `pinned` boolean: Whether layer appears on all scenes
    - `locked` boolean: Whether layer is locked from editing
    - `position` object: Layer position and size in pixels of the project's current resolution. After a resolution change (for example 720p to 1080p), the values are scaled to the new one.
      - `x` number
      - `y` number
      - `width` number: Width in native resolution (e.g., 1920 for full-width on 1080p)
      - `height` number: Height in native resolution (e.g., 1080 for full-height on 1080p)
    - `type` 'video', required: Layer type identifier
    - `settings` object, required
      - `fileId` string, required: Video file ID (required)
      - `fileName` string, nullable: Video file name
      - `volume` integer: Audio volume (0-10)
      - `loop` boolean: Loop video when it ends
      - `nextScene` string, nullable: Scene ID to switch to when video ends. Cannot be used with loop=true.
      - `isPlaying` boolean: Current playback state (read-only)
      - `duration` number: Duration in seconds (read-only)
    - `synced` boolean: Whether the new layer reached a LIVE or PREPARING stream (auto-sync on). A scheduled stream reads the project when it starts

## Other responses

- `400`: Validation error or limit reached
- `401`: Authentication failed
- `404`: Project, scene, or file not found
- `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)
