API Documentation

WHIP/WHEP authentication error codes for integrators

Contents

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 Server URLs

Premium users can use direct WHIP URLs with their stream key embedded:

WHIP URL 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" }
Client Action: Prompt user to verify their stream key. Do not retry automatically.

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 }
Client Action: User can retry in free/anonymous mode, or stop an existing stream first.

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 }
Client Action: User can retry in free/anonymous mode. Quota resets monthly.

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" }
Client Action: Stop other stream, or append ?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" }
Client Action: User should sign in or create an account. WHIP/WHEP available for all users including 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 }
Client Action: Viewer should try again later when other viewers disconnect.

QUOTA_EXCEEDED 429

Anonymous session has exceeded its bandwidth quota.

{ "error": "Anonymous bandwidth quota exceeded", "code": "QUOTA_EXCEEDED" }
Client Action: User should wait for quota reset or use an authenticated account.

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

TierMax Streams
Free1
Registered1
Solo Creator4
Creator Plus10
Studio Pro25

Monthly Bandwidth

TierBandwidth
Free50 GB
Registered200 GB
Solo Creator500 GB
Creator Plus1 TB
Studio Pro2 TB

Viewer Limits

TierMax Viewers
Free20
Registered20
Solo Creator30
Creator Plus50
Studio Pro100

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

  1. On STREAM_LIMIT_REACHED or BANDWIDTH_EXCEEDED:
    Prompt: "Your account limit was reached. Retry with free servers?"
    If yes, switch to anonymous mode on shared servers.
  2. On INVALID_KEY:
    Prompt: "Invalid stream key. Please check your Meshcast dashboard."
    Do not retry automatically.
  3. On KEY_ALREADY_IN_USE:
    Prompt: "This key is active elsewhere. Override or use a different key?"
    If override, retry with ?force=1 appended.

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

StatusMeaningRetry Strategy
401Invalid credentialsCheck stream key, don't retry
403Access deniedMay retry with unregistered (free)
409ConflictOverride or use different key
429Rate limited/quotaWait or use unregistered (free)
Need Help?

Contact steve@seguin.email for integration support.