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.

Base URL https://purplesquirrel.media
API Version v1
Content-Type application/json

Quick Start

Get Your API Key

1
Sign in to Dashboard

Go to purplesquirrel.media/dashboard and log in with your account.

2
Navigate to API Keys

Click SettingsAPI Keys in the sidebar menu.

3
Create New Key

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:

bash
# 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:

bash
curl https://purplesquirrel.media/api/v1/assets \
  -H "Authorization: Bearer YOUR_API_KEY"
javascript
const response = await fetch('https://purplesquirrel.media/api/v1/assets', {
  headers: {
    'Authorization': `Bearer ${API_KEY}`
  }
});

const data = await response.json();
python
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:

CodeStatusDescription
200OKRequest succeeded
201CreatedResource created successfully
400Bad RequestInvalid request parameters
401UnauthorizedInvalid or missing API key
403ForbiddenAPI key lacks required permissions
404Not FoundResource doesn't exist
429Rate LimitedToo many requests
500Server ErrorInternal error, try again later

Rate Limits

API requests are rate limited to ensure fair usage:

Endpoint TypeLimitWindow
API requests100 requestsper minute
Authentication10 requestsper minute
Upload/Encode20 requestsper minute
Analytics beacon1000 requestsper 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:

json
{
  "error": "unauthorized",
  "message": "Invalid API key",
  "status": 401,
  "timestamp": "2026-01-04T15:30:00Z"
}

Health Check

GET /health

Check platform status and service health. No authentication required.

Assets

GET /api/v1/assets

List all video assets in your account.

ParameterTypeDescription
limitintegerMax results (default: 20)
offsetintegerPagination offset
statusstringFilter by status: pending, encoding, ready

Response

json
{
  "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
}
POST /api/v1/assets

Create a new video asset and get an upload URL.

ParameterTypeDescription
title requiredstringAsset title
descriptionstringAsset description
profilestringEncoding profile: sd, hd, 4k (default: hd)

Encoding

POST /encode

Submit a video for encoding. Returns job ID for status tracking.

json
{
  "asset_id": "asset_dare2stream",
  "input_key": "uploads/video.mp4",
  "profile": "hd"
}

Analytics

POST /beacon

Send player analytics events. Use for tracking playback, buffering, and QoE metrics.

javascript
// 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 /stats

Get aggregated analytics for your account.

Response

json
{
  "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 /api/v1/analytics/devices

Get device, browser, and OS breakdown of your viewers.

Query Parameters

periodTime period: 1h, 24h, 7d, 30d

Response

json
{
  "period": "7d",
  "devices": [
    { "name": "Desktop", "count": 4520 },
    { "name": "Mobile", "count": 2180 }
  ],
  "browsers": [...],
  "operating_systems": [...]
}
GET /api/v1/analytics/geographic

Get geographic breakdown by country and city.

Response

json
{
  "countries": [
    { "name": "United States", "views": 5420, "unique_viewers": 2840 }
  ],
  "cities": [...]
}
GET /api/v1/analytics/qoe

Get Quality of Experience metrics including error rates, rebuffering, and bitrate quality.

Response

json
{
  "metrics": {
    "error_rate": 0.5,
    "rebuffer_rate": 1.2,
    "avg_bitrate_kbps": 4500,
    "avg_buffer_time_ms": 250
  },
  "quality_breakdown": [...],
  "error_breakdown": [...]
}
GET /api/v1/analytics/realtime

Get real-time metrics (last 5 minutes) including active viewers and live streams.

Response

json
{
  "active_viewers": 42,
  "assets_being_watched": 8,
  "events_per_minute": 156,
  "live_streams_active": 2,
  "studio_rooms": 1
}

AI Analysis

POST /analyze

Run AI analysis on a video asset. Extracts metadata, generates tags, and creates smart thumbnails.

json
// 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.

POST /api/v1/live

Create a new live stream. Returns RTMP ingest URL and stream key.

ParameterTypeDescription
title requiredstringStream title
descriptionstringStream description
json
// 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"
}
GET /api/v1/live/list

List all live streams in your account.

GET /api/v1/live/{stream_id}

Get details for a specific live stream including status and viewer count.

DELETE /api/v1/live/{stream_id}

End and delete a live stream.

Using with OBS Studio

Configure OBS or any RTMP-compatible encoder:

text
# 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.

No Software Required

Stream live using just your web browser. Works with any modern browser that supports WebRTC (Chrome, Firefox, Safari, Edge).

Getting Started

  1. Go to your Dashboard
  2. Click Studio in the sidebar
  3. Select your camera and microphone from the dropdowns
  4. Configure your scene layout and overlays
  5. Click Go Live to start streaming

Scenes & Layouts

Switch between different layouts instantly while live:

SceneDescriptionBest For
CameraFull-screen camera viewTalking head, vlogs
ScreenFull-screen screen shareTutorials, demos
PiPScreen share with camera overlayCoding streams, presentations
SplitSide-by-side layoutInterviews, 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:

Logo/Watermark

Upload your logo or brand image with full positioning control:

Lower Third

Display professional name tags with multiple style options:

Customize primary color and text color to match your brand.

Frame Overlays

Add visual framing to your stream with built-in styles:

StyleDescription
SimpleClean border around the entire frame
RoundedBorder with rounded corners
GlowBorder with glowing effect
CornersAccent brackets in each corner
VignetteDarkened edges fading to center
CinematicLetterbox bars (top and bottom)
CustomUpload your own PNG frame overlay

Background Options

Set custom backgrounds for your stream (useful for screen-only or starting soon scenes):

Overlay Presets

Quickly apply common overlay combinations:

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

  1. Click + Invite in the Guests panel
  2. Enter the guest's name (optional)
  3. Click Generate New Link
  4. Share the invite link with your guest

Guest Experience

When a guest opens the invite link:

  1. They see a camera/microphone preview
  2. They select their preferred devices
  3. They click Join Stream
  4. Their video appears in your studio

Managing Guests

As the host, you can:

Phone as Camera

Use your smartphone as a wireless camera or microphone in your stream. Perfect for:

Connecting Your Phone

  1. In the Studio sidebar, find the Phone Camera panel
  2. Click Connect to generate a connection code
  3. On your phone, open purplesquirrel.media/phone
  4. Enter the 6-digit code shown in the studio
  5. Allow camera/microphone access when prompted
  6. Your phone's video will appear in the studio

Using Phone as Camera Source

Once connected:

Tip: Keep your phone plugged in during long streams - video streaming uses significant battery.

Stream Health Monitor

Real-time monitoring of your stream's technical performance. The health panel appears automatically when you go live.

MetricDescriptionIdeal Value
BitrateCurrent upload speed> 2500 kbps
FPSFrames per second30 or 60
DroppedDropped frame count0
RTTRound-trip time to server< 100ms
Packet LossLost data percentage< 1%

Quality Indicators

Low-Latency Viewing

Viewers can switch to low-latency mode for near-real-time playback using WebRTC (WHEP).

ModeLatencyTechnologyBest For
Normal6-10 secondsHLSGeneral viewing, VOD-like experience
Low< 1 secondWebRTC/WHEPLive auctions, Q&A, gaming

Viewers can toggle between modes using the Latency: Normal | Low buttons below the player on the /live page.

javascript
// 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.

POST /api/v1/webhooks/configure

Configure a webhook endpoint to receive event notifications.

ParameterTypeDescription
url requiredstringHTTPS URL to receive webhooks
GET /api/v1/webhooks

List recent webhook deliveries and their status.

Webhook Events

Your endpoint will receive POST requests with the following event types:

EventDescription
video.encoding.startedEncoding job has begun
video.encoding.completeVideo is ready for playback
video.encoding.failedEncoding encountered an error

Verifying Signatures

Each webhook includes a signature header for verification:

javascript
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.

html
<!-- 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:

javascript
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

Studio Control API

RESTful endpoints for programmatic studio control. All endpoints require authentication via X-API-Key header.

GET /api/v1/studio/state

Get the current studio configuration state including all overlay settings, scene layout, and stream status.

json
{
  "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 }
  }
}
PUT /api/v1/studio/scene

Set the current scene layout. Available scenes: camera, screen, pip, sidebyside.

json
{ "scene": "pip" }
PUT /api/v1/studio/overlay/{type}

Configure a specific overlay. Types: text, logo, lowerthird, frame, countdown.

json
// PUT /api/v1/studio/overlay/lowerthird
{
  "enabled": true,
  "name": "Sarah Johnson",
  "title": "Product Manager",
  "style": "modern"
}
POST /api/v1/studio/preset

Apply a preset configuration. Presets: professional, gaming, podcast, webinar, event, clean.

json
{ "preset": "professional" }
POST /api/v1/studio/ai

Configure the studio using natural language. The AI parses your prompt and applies the appropriate settings.

json
// 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

bash
# 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):

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:

examples
# 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.

GET /api/v1/social/config

Returns the connection status for each platform.

json
{
  "twitter": { "connected": true, "username": "@yourhandle" },
  "facebook": { "connected": false, "page_name": null },
  "linkedin": { "connected": true, "profile_name": "Your Name" }
}
POST /api/v1/social/config

Save credentials for a platform. Provide the platform name and its OAuth credentials.

bash
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.

POST /api/v1/social/post
bash
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:

json
{
  "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.

POST /api/v1/social/auto-post
bash
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:

Tutorial: Upload Your First Video

A complete walkthrough from upload to playback in 5 steps.

1
Create an Asset

First, create an asset record and get a signed upload URL.

bash
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"}'
2
Upload Your File

Use the returned upload_url to upload your video file directly.

bash
curl -X PUT "UPLOAD_URL_FROM_STEP_1" \
  -H "Content-Type: video/mp4" \
  --data-binary @my-video.mp4
3
Trigger Encoding

Start the encoding process to generate HLS streams.

bash
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"}'
4
Wait for Completion

Poll the asset status or use webhooks to know when encoding is done.

5
Play Your Video

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.

1
Create a Stream

Create a new live stream to get your RTMP credentials.

bash
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"}'
2
Configure OBS

Open OBS Studio → Settings → Stream:

text
Service: Custom
Server: rtmp://purplesquirrel.media/live
Stream Key: [paste your stream_key from Step 1]
3
Start Streaming

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.

1
Open Browser Studio

Navigate to your Dashboard and click "Browser Studio" in the Live Streaming section. Allow camera and microphone access when prompted.

2
Configure Your Stream

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)
3
Invite Guests (Optional)

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.

4
Go Live

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.

javascript
// 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.

1
Include the Script

Add the player script to your HTML head or body.

html
<script src="https://cdn.purplesquirrel.media/player.js"></script>
2
Create Container

Add a div where the player will render.

html
<div id="my-player" style="width: 100%; aspect-ratio: 16/9;"></div>
3
Initialize Player

Create the player instance with your asset ID.

javascript
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).