API Documentation
Everything you need to integrate Purple Squirrel Media into your application. Our API is RESTful, returns JSON, and uses standard HTTP response codes.
https://purplesquirrel.media
v1
application/json
Quick Start
Get up and running in 5 minutes
Upload Video
Ingest and encode your first video
Track Playback
Send player analytics events
Quick Start
Get Your API Key
Go to purplesquirrel.media/dashboard and log in with your account.
Click Settings → API Keys in the sidebar menu.
Click "Create API Key", give it a name (e.g., "Production"), and copy the key immediately—it won't be shown again.
Now make your first request:
# Check API health
curl https://purplesquirrel.media/health
# Response
{
"status": "healthy",
"version": "1.0.0",
"timestamp": "2026-01-03T12:00:00Z"
}
Authentication
All API requests require an API key passed in the header:
curl https://purplesquirrel.media/api/v1/assets \
-H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch('https://purplesquirrel.media/api/v1/assets', {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
const data = await response.json();
import requests
response = requests.get(
'https://purplesquirrel.media/api/v1/assets',
headers={'Authorization': f'Bearer {API_KEY}'}
)
data = response.json()
Status Codes
The API uses standard HTTP status codes:
| Code | Status | Description |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | Invalid or missing API key |
403 | Forbidden | API key lacks required permissions |
404 | Not Found | Resource doesn't exist |
429 | Rate Limited | Too many requests |
500 | Server Error | Internal error, try again later |
Rate Limits
API requests are rate limited to ensure fair usage:
| Endpoint Type | Limit | Window |
|---|---|---|
| API requests | 100 requests | per minute |
| Authentication | 10 requests | per minute |
| Upload/Encode | 20 requests | per minute |
| Analytics beacon | 1000 requests | per minute |
Rate limit headers are included in all responses: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Error Responses
All errors return a consistent JSON format:
{
"error": "unauthorized",
"message": "Invalid API key",
"status": 401,
"timestamp": "2026-01-04T15:30:00Z"
}
Health Check
Check platform status and service health. No authentication required.
Assets
List all video assets in your account.
| Parameter | Type | Description |
|---|---|---|
limit | integer | Max results (default: 20) |
offset | integer | Pagination offset |
status | string | Filter by status: pending, encoding, ready |
Response
{
"assets": [
{
"id": "asset_dare2stream",
"title": "My Video",
"status": "ready",
"duration": 125.4,
"created_at": "2026-01-04T12:00:00Z",
"playback_url": "https://cdn.purplesquirrel.media/v/asset_dare2stream/index.m3u8"
}
],
"total": 1,
"limit": 20,
"offset": 0
}
Create a new video asset and get an upload URL.
| Parameter | Type | Description |
|---|---|---|
title required | string | Asset title |
description | string | Asset description |
profile | string | Encoding profile: sd, hd, 4k (default: hd) |
Encoding
Submit a video for encoding. Returns job ID for status tracking.
{
"asset_id": "asset_dare2stream",
"input_key": "uploads/video.mp4",
"profile": "hd"
}
Analytics
Send player analytics events. Use for tracking playback, buffering, and QoE metrics.
// Send a playback event
fetch('/beacon', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
event: 'play',
asset_id: 'asset_dare2stream',
session_id: 'session_xyz',
position: 0,
bitrate: 4500000
})
});
Get aggregated analytics for your account.
Response
{
"total_views": 15420,
"unique_viewers": 8234,
"total_watch_time_seconds": 1847293,
"avg_view_duration_seconds": 119.8,
"top_assets": [
{ "id": "asset_abc123", "views": 5420 },
{ "id": "asset_def456", "views": 3210 }
],
"period": "last_30_days"
}
Get device, browser, and OS breakdown of your viewers.
Query Parameters
period | Time period: 1h, 24h, 7d, 30d |
Response
{
"period": "7d",
"devices": [
{ "name": "Desktop", "count": 4520 },
{ "name": "Mobile", "count": 2180 }
],
"browsers": [...],
"operating_systems": [...]
}
Get geographic breakdown by country and city.
Response
{
"countries": [
{ "name": "United States", "views": 5420, "unique_viewers": 2840 }
],
"cities": [...]
}
Get Quality of Experience metrics including error rates, rebuffering, and bitrate quality.
Response
{
"metrics": {
"error_rate": 0.5,
"rebuffer_rate": 1.2,
"avg_bitrate_kbps": 4500,
"avg_buffer_time_ms": 250
},
"quality_breakdown": [...],
"error_breakdown": [...]
}
Get real-time metrics (last 5 minutes) including active viewers and live streams.
Response
{
"active_viewers": 42,
"assets_being_watched": 8,
"events_per_minute": 156,
"live_streams_active": 2,
"studio_rooms": 1
}
AI Analysis
Run AI analysis on a video asset. Extracts metadata, generates tags, and creates smart thumbnails.
// Request
{
"asset_id": "asset_dare2stream",
"features": ["tags", "description", "thumbnails"]
}
// Response
{
"tags": ["tutorial", "coding", "javascript"],
"description": "A comprehensive guide to...",
"thumbnails": ["thumb_001.jpg", "thumb_002.jpg"]
}
Live Streaming
Create and manage live streams with RTMP ingest and HLS output.
Create a new live stream. Returns RTMP ingest URL and stream key.
| Parameter | Type | Description |
|---|---|---|
title required | string | Stream title |
description | string | Stream description |
// Response
{
"stream_id": "stream_abc123",
"rtmp_url": "rtmp://purplesquirrel.media/live",
"stream_key": "sk_abc123xyz",
"playback_url": "https://purplesquirrel.media/live/stream_abc123/index.m3u8",
"status": "pending"
}
List all live streams in your account.
Get details for a specific live stream including status and viewer count.
End and delete a live stream.
Using with OBS Studio
Configure OBS or any RTMP-compatible encoder:
# OBS Settings → Stream
Service: Custom
Server: rtmp://purplesquirrel.media/live
Stream Key: YOUR_STREAM_KEY
# Recommended Output Settings
Encoder: x264 or NVENC
Bitrate: 4500-6000 Kbps
Keyframe Interval: 2 seconds
Browser Studio
Stream directly from your browser without any additional software. The Browser Studio includes professional features like scene switching, overlays, multi-guest support, and real-time stream health monitoring.
Stream live using just your web browser. Works with any modern browser that supports WebRTC (Chrome, Firefox, Safari, Edge).
Getting Started
- Go to your Dashboard
- Click Studio in the sidebar
- Select your camera and microphone from the dropdowns
- Configure your scene layout and overlays
- Click Go Live to start streaming
Scenes & Layouts
Switch between different layouts instantly while live:
| Scene | Description | Best For |
|---|---|---|
| Camera | Full-screen camera view | Talking head, vlogs |
| Screen | Full-screen screen share | Tutorials, demos |
| PiP | Screen share with camera overlay | Coding streams, presentations |
| Split | Side-by-side layout | Interviews, co-hosts |
Click any scene card to switch instantly. The transition is seamless with no interruption to your stream.
Graphics & Overlays
Add professional graphics and overlays to your stream. Access the full overlay editor by clicking Edit All in the Graphics & Overlays panel, or use the quick toggles for common overlays.
Text Overlay
Display custom text anywhere on your stream with full styling control:
- Font - Choose from Cabinet Grotesk, Arial, Helvetica, Georgia, Times New Roman, Courier New, or Impact
- Size - Adjustable from 12px to 72px
- Colors - Custom text color and background color with opacity control
- Position - 9-point grid placement (corners, edges, center)
- Animations - None, Fade, Slide from Left/Right, Scrolling ticker, or Pulse effect
Logo/Watermark
Upload your logo or brand image with full positioning control:
- Upload - Supports PNG, JPG, GIF, SVG (transparent PNGs recommended)
- Size - Adjustable from 30px to 200px
- Opacity - Control transparency from 10% to 100%
- Position - 9-point grid placement
Lower Third
Display professional name tags with multiple style options:
- Modern - Gradient fade effect with brand color
- Classic - Dark semi-transparent background
- Minimal - Simple underline accent
- Boxed - Solid color background
Customize primary color and text color to match your brand.
Frame Overlays
Add visual framing to your stream with built-in styles:
| Style | Description |
|---|---|
| Simple | Clean border around the entire frame |
| Rounded | Border with rounded corners |
| Glow | Border with glowing effect |
| Corners | Accent brackets in each corner |
| Vignette | Darkened edges fading to center |
| Cinematic | Letterbox bars (top and bottom) |
| Custom | Upload your own PNG frame overlay |
Background Options
Set custom backgrounds for your stream (useful for screen-only or starting soon scenes):
- Solid Color - Single color background
- Gradient - Two-color gradient with direction control
- Image - Upload a background image with fit mode and blur options
Overlay Presets
Quickly apply common overlay combinations:
- Professional - Subtle logo + clean lower third
- Gaming - Neon glow frame + "LIVE" text indicator
- Podcast - Minimal lower third + gradient background
- Webinar - Logo + boxed lower third + simple frame
- Live Event - Full branding package with all elements
- Clean - No overlays (raw camera feed)
You can also save your current overlay configuration as a custom preset for quick access later.
Countdown Timer
Show a "Starting Soon" countdown before your stream begins. Set the duration (1-60 minutes) and click Start. The countdown displays centered on screen with a dark background.
Quick Toggles
The sidebar provides quick toggle buttons for Logo, Text, Lower Third, and Frame overlays. Click any button to enable/disable that overlay instantly without opening the full editor.
Multi-Guest Streaming
Bring guests onto your stream with real-time WebRTC video connections.
Inviting Guests
- Click + Invite in the Guests panel
- Enter the guest's name (optional)
- Click Generate New Link
- Share the invite link with your guest
Guest Experience
When a guest opens the invite link:
- They see a camera/microphone preview
- They select their preferred devices
- They click Join Stream
- Their video appears in your studio
Managing Guests
As the host, you can:
- Mute - Temporarily mute a guest's audio
- Remove - Disconnect a guest from the stream
- Use the Split scene to show host and guest side-by-side
Phone as Camera
Use your smartphone as a wireless camera or microphone in your stream. Perfect for:
- Adding a second camera angle
- Mobile/roaming shots
- Using your phone's high-quality camera
- Remote microphone placement
Connecting Your Phone
- In the Studio sidebar, find the Phone Camera panel
- Click Connect to generate a connection code
- On your phone, open
purplesquirrel.media/phone - Enter the 6-digit code shown in the studio
- Allow camera/microphone access when prompted
- Your phone's video will appear in the studio
Using Phone as Camera Source
Once connected:
- Click Use next to the connected phone to switch to it
- Switch between front and back cameras on your phone
- Toggle mic/camera on/off from your phone
- The connection stays active as long as the browser tab is open
Stream Health Monitor
Real-time monitoring of your stream's technical performance. The health panel appears automatically when you go live.
| Metric | Description | Ideal Value |
|---|---|---|
| Bitrate | Current upload speed | > 2500 kbps |
| FPS | Frames per second | 30 or 60 |
| Dropped | Dropped frame count | 0 |
| RTT | Round-trip time to server | < 100ms |
| Packet Loss | Lost data percentage | < 1% |
Quality Indicators
- ● Excellent - Bitrate > 3000 kbps, RTT < 100ms
- ● Good - Bitrate > 2500 kbps, RTT < 150ms
- ● Fair - Bitrate > 1500 kbps, RTT < 300ms
- ● Poor - Below fair thresholds, consider reducing quality
Low-Latency Viewing
Viewers can switch to low-latency mode for near-real-time playback using WebRTC (WHEP).
| Mode | Latency | Technology | Best For |
|---|---|---|---|
| Normal | 6-10 seconds | HLS | General viewing, VOD-like experience |
| Low | < 1 second | WebRTC/WHEP | Live auctions, Q&A, gaming |
Viewers can toggle between modes using the Latency: Normal | Low buttons below the player on the /live page.
// WHEP playback endpoint
const whepUrl = `/rtc/v1/whep/?app=live&stream=\${streamKey}`;
// Create WebRTC connection for low-latency viewing
const pc = new RTCPeerConnection();
pc.addTransceiver('video', { direction: 'recvonly' });
pc.addTransceiver('audio', { direction: 'recvonly' });
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const response = await fetch(whepUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/sdp' },
body: pc.localDescription.sdp
});
const answer = await response.text();
await pc.setRemoteDescription({ type: 'answer', sdp: answer });
Webhooks
Receive real-time notifications when events occur in your account.
Configure a webhook endpoint to receive event notifications.
| Parameter | Type | Description |
|---|---|---|
url required | string | HTTPS URL to receive webhooks |
List recent webhook deliveries and their status.
Webhook Events
Your endpoint will receive POST requests with the following event types:
| Event | Description |
|---|---|
video.encoding.started | Encoding job has begun |
video.encoding.complete | Video is ready for playback |
video.encoding.failed | Encoding encountered an error |
Verifying Signatures
Each webhook includes a signature header for verification:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const parts = signature.split(',');
const timestamp = parts[0].split('=')[1];
const sig = parts[1].split('=')[1];
const expected = crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + JSON.stringify(payload))
.digest('hex');
return sig === expected;
}
Player SDK
Drop-in player with built-in analytics and adaptive streaming.
<!-- Include the player -->
<script src="https://cdn.purplesquirrel.media/player.js"></script>
<!-- Create player container -->
<div id="player"></div>
<!-- Initialize -->
<script>
const player = new PSMPlayer('#player', {
assetId: 'asset_dare2stream',
apiKey: 'YOUR_API_KEY',
autoplay: false
});
</script>
Player Events
Listen to player events for custom integrations:
player.on('play', () => console.log('Playing'));
player.on('pause', () => console.log('Paused'));
player.on('ended', () => console.log('Finished'));
player.on('error', (e) => console.error('Error:', e));
player.on('qualitychange', (q) => console.log('Quality:', q));
AI Studio Control
Control your studio using natural language or structured API calls. Configure overlays, scenes, and stream settings using AI prompts from the web interface or via an MCP server for Claude integration.
Two Integration Options
- Web UI Chat: Built-in AI assistant in the dashboard sidebar for quick studio configuration
- MCP Server: Connect Claude Desktop or Claude Code to control your studio via natural language
Studio Control API
RESTful endpoints for programmatic studio control. All endpoints require authentication via X-API-Key header.
Get the current studio configuration state including all overlay settings, scene layout, and stream status.
{
"success": true,
"state": {
"scene": "camera",
"overlays": {
"logo": { "enabled": true, "position": "top-right" },
"lowerthird": { "enabled": true, "name": "John Doe", "title": "CEO" },
"frame": { "enabled": false }
},
"stream": { "is_live": false }
}
}
Set the current scene layout. Available scenes: camera, screen, pip, sidebyside.
{ "scene": "pip" }
Configure a specific overlay. Types: text, logo, lowerthird, frame, countdown.
// PUT /api/v1/studio/overlay/lowerthird
{
"enabled": true,
"name": "Sarah Johnson",
"title": "Product Manager",
"style": "modern"
}
Apply a preset configuration. Presets: professional, gaming, podcast, webinar, event, clean.
{ "preset": "professional" }
Configure the studio using natural language. The AI parses your prompt and applies the appropriate settings.
// Request
{ "prompt": "professional look with logo in bottom right and show my name as CEO" }
// Response
{
"success": true,
"response": "Applied professional preset. Logo positioned bottom-right. Lower third showing 'CEO'.",
"applied": { "preset": "professional", "logo": { "position": "bottom-right" } }
}
MCP Server Integration
The MCP (Model Context Protocol) server allows Claude Desktop or Claude Code to control your studio via natural language. Download and configure the server for seamless AI integration.
Installation
# Install dependencies
pip install mcp httpx
# Download the MCP server
curl -O https://purplesquirrel.media/mcp_studio_server.py
Claude Desktop Configuration
Add to your Claude Desktop config file (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"psm-studio": {
"command": "python",
"args": ["/path/to/mcp_studio_server.py"],
"env": {
"PSM_API_KEY": "your-api-key",
"PSM_API_URL": "https://purplesquirrel.media"
}
}
}
}
Available Tools
| Tool | Description |
|---|---|
studio_ai_configure |
Configure studio using natural language prompts |
studio_get_state |
Get current studio configuration state |
studio_set_scene |
Set scene layout (camera, screen, pip, sidebyside) |
studio_set_overlay |
Configure individual overlay settings |
studio_apply_preset |
Apply a preset configuration |
studio_stream_control |
Go live or end stream |
Example Prompts
Use these natural language prompts with the AI chat or MCP server:
# Basic setup
"Set up a professional stream with logo in the corner"
"Apply gaming preset with neon frame"
# Lower thirds
"Show my name as John Smith with title Product Manager"
"Use modern style lower third"
# Scene control
"Switch to picture-in-picture layout"
"Show screen share with camera in corner"
# Overlays
"Add LIVE text in top left with red color"
"Put the logo in bottom right at 80% opacity"
# Stream control
"Go live with title 'Weekly Update'"
"End the stream"
Social Sharing API
Automatically share your streams and videos to social media platforms. Connect your Twitter/X, Facebook, and LinkedIn accounts to enable one-click sharing and auto-posting.
Connect Social Accounts
Configure your social media credentials to enable posting. Retrieve connection status or save new credentials.
/api/v1/social/config
Returns the connection status for each platform.
{
"twitter": { "connected": true, "username": "@yourhandle" },
"facebook": { "connected": false, "page_name": null },
"linkedin": { "connected": true, "profile_name": "Your Name" }
}
/api/v1/social/config
Save credentials for a platform. Provide the platform name and its OAuth credentials.
curl -X POST https://purplesquirrel.media/api/v1/social/config \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "twitter",
"api_key": "YOUR_TWITTER_API_KEY",
"api_secret": "YOUR_TWITTER_API_SECRET",
"access_token": "YOUR_ACCESS_TOKEN",
"access_secret": "YOUR_ACCESS_SECRET",
"username": "@yourhandle"
}'
Post to Social Media
Manually post to one or more platforms with a custom message.
/api/v1/social/post
curl -X POST https://purplesquirrel.media/api/v1/social/post \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platforms": ["twitter", "linkedin"],
"message": "Check out my new stream!",
"url": "https://purplesquirrel.media/live?stream=abc123",
"title": "My Awesome Stream",
"content_type": "stream"
}'
Response includes success status for each platform:
{
"success": true,
"results": {
"twitter": { "success": true, "message": "Tweet posted" },
"linkedin": { "success": true, "message": "Post created" }
}
}
Auto-Post Configuration
Configure automatic posting when streams go live or videos are published.
/api/v1/social/auto-post
curl -X POST https://purplesquirrel.media/api/v1/social/auto-post \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"platforms": ["twitter", "facebook", "linkedin"],
"on_stream_live": true,
"on_video_publish": false,
"message_template": "Now live: {title}! Watch at {url}"
}'
Template Variables:
{title}- Stream or video title{url}- Playback URL{description}- Content description
Tutorial: Upload Your First Video
A complete walkthrough from upload to playback in 5 steps.
First, create an asset record and get a signed upload URL.
curl -X POST https://purplesquirrel.media/api/v1/assets \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "My First Video", "profile": "hd"}'
Use the returned upload_url to upload your video file directly.
curl -X PUT "UPLOAD_URL_FROM_STEP_1" \
-H "Content-Type: video/mp4" \
--data-binary @my-video.mp4
Start the encoding process to generate HLS streams.
curl -X POST https://purplesquirrel.media/encode \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"asset_id": "YOUR_ASSET_ID", "profile": "hd"}'
Poll the asset status or use webhooks to know when encoding is done.
Use the playback_url from the asset to stream your video.
Tutorial: Go Live with OBS
Set up a live stream in under 5 minutes.
Create a new live stream to get your RTMP credentials.
curl -X POST https://purplesquirrel.media/api/v1/live \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "My Live Stream"}'
Open OBS Studio → Settings → Stream:
Service: Custom
Server: rtmp://purplesquirrel.media/live
Stream Key: [paste your stream_key from Step 1]
Click "Start Streaming" in OBS. Your stream will be live at the playback_url returned in Step 1.
Tutorial: Go Live from Browser
Stream directly from your browser with no software required.
Navigate to your Dashboard and click "Browser Studio" in the Live Streaming section. Allow camera and microphone access when prompted.
Set up your broadcast:
- Select your camera and microphone from the dropdowns
- Choose a scene layout (Camera, Screen Share, Picture-in-Picture, or Split)
- Add overlays: logo, lower third with name/title, or countdown timer
- Adjust video quality (720p, 1080p, or 4K)
For multi-guest streams, click "Invite Guest" and share the invite link. Guests join via browser with no account needed. Manage guests with mute/remove controls.
Click "Start Streaming" to begin. Monitor stream health in real-time (bitrate, FPS, dropped frames, latency). Your stream is available at your playback URL immediately.
// Browser Studio uses WebRTC WHIP for low-latency publishing
const pc = new RTCPeerConnection();
// Add camera/mic tracks
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 1920, height: 1080 },
audio: true
});
stream.getTracks().forEach(track => pc.addTrack(track, stream));
// Connect via WHIP
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const resp = await fetch(`/rtc/v1/whip/?app=live&stream=\${streamKey}`, {
method: 'POST',
headers: { 'Content-Type': 'application/sdp' },
body: pc.localDescription.sdp
});
await pc.setRemoteDescription({ type: 'answer', sdp: await resp.text() });
Tutorial: Embed the Player
Add the Purple Squirrel player to any website.
Add the player script to your HTML head or body.
<script src="https://cdn.purplesquirrel.media/player.js"></script>
Add a div where the player will render.
<div id="my-player" style="width: 100%; aspect-ratio: 16/9;"></div>
Create the player instance with your asset ID.
const player = new PSMPlayer('#my-player', {
assetId: 'YOUR_ASSET_ID',
apiKey: 'YOUR_PUBLIC_API_KEY',
autoplay: false,
muted: false,
controls: true
});
Tip: For React, Vue, or Angular, wrap the player initialization in the appropriate lifecycle hook (useEffect, onMounted, ngOnInit).