Skip to main content
A video is the root object. Its settings, its embed code, its uploaded media, and (if it has one) its playlist all live under the id returned here. Start on this page, then follow the links out to Video Settings, Uploads and Playlists for the deeper flows. Reading needs a token with videos:read. Creating, changing or deleting a video needs videos:write. See Authentication.

List videos

string
One of id, title, code, created_at, updated_at. Anything else is ignored and the list falls back to id.
string
default:"desc"
asc or desc.
integer
default:"50"
Page size.
curl
200 OK
The list is deliberately slim: id, title, code, created_at, updated_at, workspace_id. Fetch a single video for everything else.

Get a video

curl
200 OK
This is the same “everything” payload the dashboard editor loads: every option group the video carries, not the summary fields the list returns. The example above is trimmed. For the settings alone, or the embed code alone, use the narrower endpoints below instead of parsing this one.

Read settings, embed code and player config

integer
required
The video’s numeric id.
GET /v1/videos/{video}/settings returns the option groups alone, under a settings key: {"settings": { "style_options": {...}, "playback_options": {...}, ... }}. This is the same shape POST .../draft and POST .../deploy accept as a payload. See Video Settings for the full lifecycle.

Create a video

A video created through the API is a shell: a title and, optionally, folder, tags and a starting player version. It has no media until you upload one (see Uploads) and no settings until you deploy some (see Video Settings), unless you copy them from an existing video.
string
required
Max 255 characters.
integer
Puts the video in an existing folder of this workspace. Create one with POST /v1/folders. A folder id from another workspace, or one that does not exist, is refused with 422 FOLDER_NOT_FOUND.
string[]
Each tag max 64 characters.
boolean
default:"false"
true makes the video a silent looping clip with no overlays, prompts or controls. See Plain mode.
string
default:"v2"
One of v1, v2, 1, 2.
integer
The id of another video in the same workspace. Copies its player version and all 18 option-group columns (style, playback, autoplay, progress, actions, pixels, continue watching, turbo, timed events, user events, chapters, playlist, engagement, lead form, notes, quiz, watch gate, cross-device resume) onto the new video, so it launches configured instead of blank.
An unknown copy_from id, or one from another workspace, is not an error. The video is created anyway, with nothing copied. Read the new video back and check its settings if you are relying on copy_from to have worked.
201 Created
status is the same status object you poll after an upload. Side effect: fires the video.created webhook, with {"video": {"id", "code", "title"}}. See Webhooks API to subscribe.

Update title, folder or tags

string
Max 255 characters.
integer
A folder in this workspace (anything else is 422 FOLDER_NOT_FOUND). Pass null to move it out of its folder.
string[]
Replaces the tag list entirely. There is no add-one-tag call.
curl
200 OK
Every field is optional: send only what changed. This endpoint touches title, folder and tags only. It does not fire a webhook and does not touch settings, media or playlist state.

Duplicate a video

curl
201 Created
The copy takes the title (with ” (copy)” appended), settings and player version. It does not take the media: both HLS URLs and both thumbnails come back null, because the copy needs its own upload. No webhook fires.

Delete a video

curl
200 OK
Deleting a video also deletes its pending settings draft, if it has one, and fires the video.deleted webhook with {"video_id": 512}.

Webhooks fired from this resource

Update and duplicate fire nothing.

Errors

The token is wrong, expired, or revoked.
Reads need videos:read. Create, update, duplicate and delete need videos:write.
GET /v1/videos/{video}, .../settings, .../embed and .../config return {"error": {"code": "NOT_FOUND", "message": "Video not found"}}.PATCH, DELETE and .../duplicate instead return Laravel’s default model-not-found body: {"message": "No query results for model [App\\Models\\WorkspaceVideo] 512"}. Both mean the same thing: no video with that id in your workspace. Match on status code (404), not on body shape, if you handle both call families in one client.
Validation failed on create or update. Laravel’s default shape: {"message": "The given data was invalid.", "errors": {"title": ["The title field is required."]}}.
Rate limited. Reads: 600 per minute per token. Writes: 60 per minute per token.