API Documentation
API Integration Guide
Complete developer reference for WAVE Streaming API
Version 1.0•Updated November 2025•45-55 min read
API Overview
Base URLs
| Environment | Base URL | Purpose |
|---|---|---|
| Production | https://api.wave.av/v1 | Live production traffic |
| Staging | https://api-staging.wave.av/v1 | Pre-production testing |
| Sandbox | https://api-sandbox.wave.av/v1 | Development and testing |
API Characteristics
REST-based
Standard HTTP methods (GET, POST, PUT, PATCH, DELETE) with JSON format
Idempotent
Safe to retry POST/PUT/DELETE operations with idempotency keys
Versioned
API version in URL path (/v1, /v2) ensures backward compatibility
Rate Limited
Tiered rate limits based on plan with burst allowances
Authentication
API Key Authentication
Primary authentication method for server-to-server integrations using Bearer tokens.
# Generate API Key
1. Log in to https://dashboard.wave.av
2. Navigate to Settings > API Keys
3. Click "Create API Key"
4. Copy and store securely (shown only once!)
# Usage: Bearer token (RECOMMENDED)
curl -X GET https://api.wave.av/v1/streams \
-H "Authorization: Bearer wave_live_abc123xyz789" \
-H "Content-Type: application/json"
# Alternative: Custom header
curl -X GET https://api.wave.av/v1/streams \
-H "X-API-Key: wave_live_abc123xyz789"JavaScript Example
const WAVE_API_KEY = process.env.WAVE_API_KEY;
async function fetchStreams() {
const response = await fetch('https://api.wave.av/v1/streams', {
headers: {
'Authorization': `Bearer ${WAVE_API_KEY}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
return data.streams;
}Python Example
import os
import requests
WAVE_API_KEY = os.environ.get('WAVE_API_KEY')
def fetch_streams():
headers = {
'Authorization': f'Bearer {WAVE_API_KEY}',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.wave.av/v1/streams',
headers=headers
)
response.raise_for_status()
return response.json()['streams']Streams API
Create Stream
POST /v1/streams
{
"title": "Product Launch Event",
"description": "Live product unveiling",
"protocol": "webrtc",
"quality": {
"resolution": "1080p",
"bitrate": 5000,
"frameRate": 30
},
"recording": {
"enabled": true,
"format": "mp4"
},
"privacy": "public"
}
# Response
{
"stream": {
"id": "str_abc123",
"title": "Product Launch Event",
"status": "ready",
"ingest": {
"url": "webrtc://ingest.wave.av/str_abc123",
"streamKey": "live_xyz789"
},
"playback": {
"url": "https://stream.wave.av/str_abc123",
"embedCode": "<iframe src=\"...\"></iframe>"
},
"createdAt": "2025-11-16T10:00:00Z"
}
}List Streams
GET /v1/streams?status=live&limit=20&offset=0
# Response
{
"streams": [
{
"id": "str_abc123",
"title": "Product Launch Event",
"status": "live",
"viewers": 1234,
"duration": 3600
}
],
"pagination": {
"total": 45,
"limit": 20,
"offset": 0,
"hasMore": true
}
}Update Stream
PATCH /v1/streams/str_abc123
{
"title": "Updated Title",
"privacy": "private"
}
# Response
{
"stream": {
"id": "str_abc123",
"title": "Updated Title",
"privacy": "private",
"updatedAt": "2025-11-16T11:00:00Z"
}
}Start/Stop Stream
POST /v1/streams/str_abc123/start
POST /v1/streams/str_abc123/stop
# Response
{
"stream": {
"id": "str_abc123",
"status": "live", // or "ended"
"startedAt": "2025-11-16T12:00:00Z"
}
}Productions API
Multi-camera productions with scene switching, composition, and real-time graphics.
Create Production
POST /v1/productions
{
"name": "Studio Production",
"cameras": [
{
"id": "cam1",
"label": "Main Camera",
"source": "rtmp://input.wave.av/cam1"
},
{
"id": "cam2",
"label": "Close-up",
"source": "rtmp://input.wave.av/cam2"
}
],
"scenes": [
{
"id": "scene1",
"name": "Full Screen Main",
"layout": "single",
"cameras": ["cam1"]
},
{
"id": "scene2",
"name": "Picture-in-Picture",
"layout": "pip",
"cameras": ["cam1", "cam2"]
}
],
"output": {
"streamId": "str_abc123"
}
}
# Response
{
"production": {
"id": "prod_xyz789",
"name": "Studio Production",
"status": "ready",
"activeScene": "scene1"
}
}Switch Scene
POST /v1/productions/prod_xyz789/switch-scene
{
"sceneId": "scene2",
"transition": {
"type": "fade",
"duration": 500
}
}
# Response
{
"production": {
"id": "prod_xyz789",
"activeScene": "scene2",
"previousScene": "scene1"
}
}Analytics API
Real-Time Metrics
GET /v1/analytics/streams/str_abc123/realtime
# Response
{
"metrics": {
"currentViewers": 1234,
"peakViewers": 2500,
"averageBitrate": 4500,
"bufferRatio": 0.02,
"qualityScore": 98.5,
"geographicDistribution": {
"US": 45.2,
"EU": 32.8,
"ASIA": 22.0
}
},
"timestamp": "2025-11-16T12:00:00Z"
}Historical Analytics
GET /v1/analytics/streams/str_abc123/historical
?from=2025-11-01
&to=2025-11-16
&granularity=day
# Response
{
"data": [
{
"date": "2025-11-01",
"totalViewers": 5234,
"averageWatchTime": 1800,
"peakConcurrent": 1234,
"totalWatchHours": 9234
}
],
"summary": {
"totalViewers": 45234,
"totalWatchHours": 123456,
"averageEngagement": 0.78
}
}WebSocket & Real-Time Events
Subscribe to real-time stream events via WebSocket for live updates.
Connect to WebSocket
const ws = new WebSocket('wss://ws.wave.av/v1');
ws.on('open', () => {
// Authenticate
ws.send(JSON.stringify({
type: 'auth',
token: 'wave_live_abc123xyz789'
}));
// Subscribe to stream events
ws.send(JSON.stringify({
type: 'subscribe',
channel: 'stream:str_abc123'
}));
});
ws.on('message', (data) => {
const event = JSON.parse(data);
switch (event.type) {
case 'viewer.joined':
console.log('New viewer:', event.data);
break;
case 'stream.quality.changed':
console.log('Quality changed:', event.data);
break;
case 'stream.ended':
console.log('Stream ended');
break;
}
});Event Types
| Event | Description |
|---|---|
| stream.started | Stream went live |
| stream.ended | Stream stopped |
| viewer.joined | New viewer connected |
| viewer.left | Viewer disconnected |
| stream.quality.changed | Quality settings updated |
Webhooks
Receive HTTP POST notifications when events occur on your streams.
Configure Webhook
POST /v1/webhooks
{
"url": "https://yourdomain.com/webhooks/wave",
"events": [
"stream.started",
"stream.ended",
"stream.error",
"recording.ready"
],
"secret": "webhook_secret_abc123"
}
# Response
{
"webhook": {
"id": "wh_xyz789",
"url": "https://yourdomain.com/webhooks/wave",
"events": ["stream.started", "stream.ended", ...],
"status": "active"
}
}Handle Webhook (Node.js)
const crypto = require('crypto');
app.post('/webhooks/wave', (req, res) => {
// Verify signature
const signature = req.headers['x-wave-signature'];
const body = JSON.stringify(req.body);
const secret = process.env.WEBHOOK_SECRET;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
if (signature !== expectedSignature) {
return res.status(401).send('Invalid signature');
}
// Handle event
const { event, data } = req.body;
switch (event) {
case 'stream.started':
console.log('Stream started:', data.streamId);
break;
case 'recording.ready':
console.log('Recording ready:', data.recordingUrl);
break;
}
res.status(200).send('OK');
});SDKs & Client Libraries
JavaScript/TypeScript SDK
# Installation
npm install @wave/sdk
# Usage
import { WaveClient } from '@wave/sdk';
import { DesignTokens, getContainer, getSection } from '@/lib/design-tokens';
const wave = new WaveClient({
apiKey: process.env.WAVE_API_KEY,
environment: 'production'
});
// Create stream
const stream = await wave.streams.create({
title: 'My Stream',
protocol: 'webrtc'
});
// Start stream
await wave.streams.start(stream.id);
// Get analytics
const metrics = await wave.analytics.getRealtime(stream.id);Python SDK
# Installation
pip install wave-sdk
# Usage
from wave import WaveClient
wave = WaveClient(
api_key=os.environ.get('WAVE_API_KEY'),
environment='production'
)
# Create stream
stream = wave.streams.create(
title='My Stream',
protocol='webrtc'
)
# Start stream
wave.streams.start(stream['id'])
# Get analytics
metrics = wave.analytics.get_realtime(stream['id'])Integration Best Practices
Security
- • Never expose API keys in client-side code
- • Use environment variables for secrets
- • Rotate API keys regularly (quarterly)
- • Implement webhook signature verification
- • Use HTTPS for all API communication
Performance
- • Implement exponential backoff for retries
- • Cache API responses when appropriate
- • Use pagination for large result sets
- • Batch operations when possible
- • Monitor rate limit headers
Reliability
- • Implement comprehensive error handling
- • Use idempotency keys for critical operations
- • Set appropriate timeouts (30s for API calls)
- • Log all API interactions for debugging
- • Test failure scenarios regularly
Monitoring
- • Track API latency and success rates
- • Set up alerts for API errors
- • Monitor webhook delivery status
- • Review analytics regularly
- • Use structured logging