Videos API
Upload, manage, and stream videos.
Base URL
https://api.playvideo.dev/v1
Authentication
All endpoints require a Bearer token:
Authorization: Bearer play_live_xxx
Upload Video
Upload a new video to a collection.
POST /videos
Request
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
file | File | Yes | Video file (mp4, mov, avi, mkv, webm) |
collection | String | Yes | Collection slug to upload to |
Example
curl -X POST https://api.playvideo.dev/v1/videos \
-H "Authorization: Bearer play_live_xxx" \
-F "[email protected]" \
-F "collection=my-app"
const result = await bb.videos.upload({
file: './video.mp4',
collection: 'my-app'
});
Response
{
"message": "Video uploaded and queued for processing",
"video": {
"id": "clx1234567890",
"filename": "video.mp4",
"status": "PENDING",
"collection": "my-app"
}
}
Status Codes
| Code | Description |
|---|---|
| 202 | Video accepted for processing |
| 400 | Invalid request (missing file or collection) |
| 404 | Collection not found |
| 413 | File too large for your plan |
List Videos
Get all videos, optionally filtered.
GET /videos
Query Parameters
| Parameter | Type | Description |
|---|---|---|
collection | String | Filter by collection slug |
status | String | Filter by status (PENDING, PROCESSING, COMPLETED, FAILED) |
limit | Number | Results per page (max 100, default 50) |
offset | Number | Pagination offset |
Example
curl "https://api.playvideo.dev/v1/videos?collection=my-app&status=COMPLETED" \
-H "Authorization: Bearer play_live_xxx"
const { videos } = await bb.videos.list({
collection: 'my-app',
status: 'COMPLETED',
limit: 10
});
Response
{
"videos": [
{
"id": "clx1234567890",
"filename": "video.mp4",
"status": "COMPLETED",
"duration": 120.5,
"originalSize": 52428800,
"processedSize": 31457280,
"playlistUrl": "https://cdn.playvideo.dev/.../playlist.m3u8",
"thumbnailUrl": "https://cdn.playvideo.dev/.../thumb.jpg",
"previewUrl": "https://cdn.playvideo.dev/.../preview.mp4",
"resolutions": ["360p", "480p", "720p", "1080p"],
"errorMessage": null,
"collection": {
"slug": "my-app",
"name": "My App"
},
"createdAt": "2026-01-07T12:00:00.000Z",
"updatedAt": "2026-01-07T12:05:00.000Z"
}
]
}
Get Video
Get details for a specific video.
GET /videos/:id
Example
curl https://api.playvideo.dev/v1/videos/clx1234567890 \
-H "Authorization: Bearer play_live_xxx"
const video = await bb.videos.get('clx1234567890');
Response
{
"id": "clx1234567890",
"filename": "video.mp4",
"status": "COMPLETED",
"duration": 120.5,
"originalSize": 52428800,
"processedSize": 31457280,
"playlistUrl": "https://cdn.playvideo.dev/.../playlist.m3u8",
"thumbnailUrl": "https://cdn.playvideo.dev/.../thumb.jpg",
"previewUrl": "https://cdn.playvideo.dev/.../preview.mp4",
"resolutions": ["360p", "480p", "720p", "1080p"],
"errorMessage": null,
"collection": {
"slug": "my-app",
"name": "My App"
},
"createdAt": "2026-01-07T12:00:00.000Z",
"updatedAt": "2026-01-07T12:05:00.000Z"
}
Video Status
| Status | Description |
|---|---|
PENDING | Upload complete, waiting for processing |
PROCESSING | Video is being transcoded |
COMPLETED | Ready to stream |
FAILED | Processing failed (see errorMessage) |
Delete Video
Delete a video and its files.
DELETE /videos/:id
Example
curl -X DELETE https://api.playvideo.dev/v1/videos/clx1234567890 \
-H "Authorization: Bearer play_live_xxx"
await bb.videos.delete('clx1234567890');
Response
{
"message": "Video deleted"
}
Video Object
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier |
filename | String | Original filename |
status | String | Processing status |
duration | Number | Duration in seconds (null if not processed) |
originalSize | Number | Original file size in bytes |
processedSize | Number | Processed size in bytes (null if not complete) |
playlistUrl | String | HLS playlist URL (null if not ready) |
thumbnailUrl | String | Thumbnail image URL (null if not ready) |
previewUrl | String | Short preview clip URL (null if not ready) |
resolutions | Array | Available resolutions |
errorMessage | String | Error description (null if no error) |
collection | Object | Parent collection info |
createdAt | String | ISO 8601 timestamp |
updatedAt | String | ISO 8601 timestamp |
Polling for Completion
Videos are processed asynchronously. Poll the video endpoint to check status:
// Manual polling
let video = await bb.videos.get(videoId);
while (video.status === 'PROCESSING' || video.status === 'PENDING') {
await new Promise(r => setTimeout(r, 2000));
video = await bb.videos.get(videoId);
}
// Or use the SDK helper
const video = await bb.videos.waitForReady(videoId);
For real-time notifications, use webhooks.
Supported Formats
Input
- MP4 (.mp4)
- QuickTime (.mov)
- AVI (.avi)
- Matroska (.mkv)
- WebM (.webm)
- OGG (.ogv)
- FLV (.flv)
- WMV (.wmv)
- MPEG (.mpeg, .mpg)
- 3GPP (.3gp, .3g2)
Output
- HLS (HTTP Live Streaming) - Universal playback
- Auto-generated thumbnail (JPEG)
- Preview clip (MP4)