API Documentation
WHIP/WHEP authentication error codes for integrators
Overview
When WHIP/WHEP authentication fails, Meshcast returns structured JSON error responses with machine-readable codes. This allows clients like VDO.Ninja to provide intelligent fallback behavior.
Premium users can use direct WHIP URLs with their stream key embedded:
wss://[server-ip]:8889/[stream-key]/whip
Error Response Format
All authentication errors return JSON with this structure:
{
"error": "Human-readable error message",
"code": "MACHINE_READABLE_CODE",
// Additional context fields vary by error type
}
Error Codes Reference
INVALID_KEY 401
The stream key does not exist or is not valid.
{
"error": "Invalid stream key",
"code": "INVALID_KEY"
}
STREAM_LIMIT_REACHED 429
User has reached their maximum concurrent stream limit.
{
"error": "Maximum concurrent streams (1) reached",
"code": "STREAM_LIMIT_REACHED",
"current": 1,
"limit": 1
}
BANDWIDTH_EXCEEDED 429
User has exceeded their monthly bandwidth quota.
{
"error": "Bandwidth limit reached (50.1/50 GB)",
"code": "BANDWIDTH_EXCEEDED",
"percentage_used": 100.2
}
KEY_ALREADY_IN_USE 409
This stream key is currently being used for an active publish session.
{
"error": "Stream key already in use",
"code": "KEY_ALREADY_IN_USE",
"detail": "Use ?force=1 to override.",
"server": "node1"
}
?force=1 to WHIP URL to override.PROTOCOL_NOT_ALLOWED 403
Anonymous users can only use WHIP/WHEP. Sign in for RTMP/SRT/HLS access.
{
"error": "Protocol rtmp requires an account",
"code": "PROTOCOL_NOT_ALLOWED",
"protocol": "rtmp",
"tier": "anonymous"
}
VIEWER_LIMIT_REACHED 403
The stream has reached its maximum viewer count.
{
"error": "Viewer limit (20) reached",
"code": "VIEWER_LIMIT_REACHED",
"current": 20,
"limit": 20
}
QUOTA_EXCEEDED 429
Anonymous session has exceeded its bandwidth quota.
{
"error": "Anonymous bandwidth quota exceeded",
"code": "QUOTA_EXCEEDED"
}
Tier Limits
Free (no account): Web Studio + VDO.Ninja. Free (account): RTMP/SRT/HLS. HLS embeds for free tiers are limited to meshcast.io / vdo.ninja.
Concurrent Streams
| Tier | Max Streams |
|---|---|
| Free | 1 |
| Registered | 1 |
| Solo Creator | 4 |
| Creator Plus | 10 |
| Studio Pro | 25 |
Monthly Bandwidth
| Tier | Bandwidth |
|---|---|
| Free | 50 GB |
| Registered | 200 GB |
| Solo Creator | 500 GB |
| Creator Plus | 1 TB |
| Studio Pro | 2 TB |
Viewer Limits
| Tier | Max Viewers |
|---|---|
| Free | 20 |
| Registered | 20 |
| Solo Creator | 30 |
| Creator Plus | 50 |
| Studio Pro | 100 |
VDO.Ninja Integration
When VDO.Ninja uses Meshcast premium servers with a user's stream key, it can handle these error codes to provide fallback behavior.
Recommended Fallback Strategy
- On
STREAM_LIMIT_REACHEDorBANDWIDTH_EXCEEDED:
Prompt: "Your account limit was reached. Retry with free servers?"
If yes, switch to anonymous mode on shared servers. - On
INVALID_KEY:
Prompt: "Invalid stream key. Please check your Meshcast dashboard."
Do not retry automatically. - On
KEY_ALREADY_IN_USE:
Prompt: "This key is active elsewhere. Override or use a different key?"
If override, retry with?force=1appended.
JavaScript Example
async function connectWithFallback(whipUrl, streamKey) {
try {
await whipClient.connect(whipUrl);
} catch (error) {
const errorData = await error.response?.json();
switch (errorData?.code) {
case 'STREAM_LIMIT_REACHED':
case 'BANDWIDTH_EXCEEDED':
if (confirm(`${errorData.error}\n\nRetry with free servers?`)) {
return connectAnonymous();
}
break;
case 'KEY_ALREADY_IN_USE':
if (confirm('Key in use elsewhere. Override?')) {
return whipClient.connect(whipUrl + '?force=1');
}
break;
case 'INVALID_KEY':
alert('Invalid stream key. Check your Meshcast dashboard.');
break;
}
throw error;
}
}
HTTP Status Codes
| Status | Meaning | Retry Strategy |
|---|---|---|
401 | Invalid credentials | Check stream key, don't retry |
403 | Access denied | May retry with unregistered (free) |
409 | Conflict | Override or use different key |
429 | Rate limited/quota | Wait or use unregistered (free) |
Contact steve@seguin.email for integration support.