๐Ÿ“ก Self Hosted API

Test your stream and integrate with our API

๐Ÿงช Live Test

Get your API key from the dashboard after adding a "Self Hosted" destination

๐Ÿ“บ HLS Stream Player

Check stream status first to load the HLS player.

๐Ÿ“š API Documentation

Get Stream Status

GET /api/public/stream/status

Returns the current live/offline status of your stream, HLS playback URL, and bandwidth usage information.

Authentication

Provide your API key using one of these methods (in order of preference):

1. Header (Recommended)
X-API-Key: YOUR_API_KEY
2. Authorization Header
Authorization: Bearer YOUR_API_KEY
3. Query String (Fallback)
?apiKey=YOUR_API_KEY or ?key=YOUR_API_KEY

Rate Limiting

60 requests per minute per API key. Exceeding this limit will return a 429 Too Many Requests error.

Response Format

When Stream is Live:

{
  "isLive": true,
  "hlsUrl": "https://simulcast.me/hls/abc123/index.m3u8?apiKey=...",
  "streamKeyLabel": "My Gaming Stream",
  "startedAt": 1234567890,
  "playbackToken": "abc123...",
  "bandwidth": {
    "usedGB": "2.45",
    "limitGB": 10,
    "remainingGB": "7.55",
    "overageGB": "0.00",
    "overageSats": 0,
    "hourStart": 1234560000
  }
}

When Stream is Offline:

{
  "isLive": false,
  "hlsUrl": null,
  "streamKeyLabel": "My Gaming Stream",
  "startedAt": null,
  "playbackToken": null,
  "bandwidth": {
    "usedGB": "0.00",
    "limitGB": 10,
    "remainingGB": "10.00",
    "overageGB": "0.00",
    "overageSats": 0,
    "hourStart": 1234560000
  }
}

Response Fields:

isLive (boolean) - Whether the stream is currently live
hlsUrl (string|null) - HLS playback URL (includes API key in query string)
streamKeyLabel (string) - Your stream key's label/name
startedAt (number|null) - Unix timestamp when stream started
playbackToken (string|null) - Secure token for HLS preview (not needed for API)
bandwidth (object) - Bandwidth usage information for current hour
usedGB - GB used this hour
limitGB - Free tier limit (10 GB/hour)
remainingGB - GB remaining in free tier
overageGB - GB over limit (charged at 5 sats/GB)
overageSats - Sats charged for overage this hour

Error Responses

401 Unauthorized - Invalid API Key
{
  "error": "Invalid API key or destination disabled"
}
429 Too Many Requests - Rate Limit Exceeded
{
  "error": "Rate limit exceeded. Maximum 60 requests per minute.",
  "retryAfter": 30
}
400 Bad Request - Missing API Key
{
  "error": "API key required. Provide via X-API-Key header, Authorization: Bearer header, or ?apiKey= query parameter."
}

๐Ÿ’ป Code Examples

cURL (Command Line)

Using header (recommended):
curl -H "X-API-Key: YOUR_API_KEY" \
  https://simulcast.me/api/public/stream/status
Using query string:
curl "https://simulcast.me/api/public/stream/status?apiKey=YOUR_API_KEY"

JavaScript (Browser/Fetch)

const API_KEY = 'YOUR_API_KEY';
const API_URL = 'https://simulcast.me/api/public/stream/status';

async function checkStream() {
  try {
    const response = await fetch(API_URL, {
      headers: { 'X-API-Key': API_KEY }
    });
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    
    const data = await response.json();
    
    if (data.isLive) {
      console.log('Stream is LIVE:', data.hlsUrl);
      // Use data.hlsUrl in your video player
    } else {
      console.log('Stream is OFFLINE');
    }
  } catch (error) {
    console.error('Error:', error);
  }
}

// Check every 5 seconds
checkStream();
setInterval(checkStream, 5000);

Python (requests)

import requests

API_KEY = "YOUR_API_KEY"
API_URL = "https://simulcast.me/api/public/stream/status"

# Using header (recommended)
response = requests.get(
    API_URL,
    headers={"X-API-Key": API_KEY}
)

if response.status_code == 200:
    data = response.json()
    if data["isLive"]:
        print(f"Stream is LIVE: {data['hlsUrl']}")
        print(f"Bandwidth: {data['bandwidth']['usedGB']} GB used")
    else:
        print("Stream is OFFLINE")
else:
    print(f"Error: {response.status_code} - {response.text}")

Node.js (fetch/axios)

const API_KEY = 'YOUR_API_KEY';
const API_URL = 'https://simulcast.me/api/public/stream/status';

// Using fetch
async function checkStream() {
  try {
    const response = await fetch(API_URL, {
      headers: { 'X-API-Key': API_KEY }
    });
    const data = await response.json();
    
    if (data.isLive) {
      console.log('Stream is LIVE:', data.hlsUrl);
    } else {
      console.log('Stream is OFFLINE');
    }
  } catch (error) {
    console.error('Error:', error);
  }
}

// Or using axios
const axios = require('axios');
axios.get(API_URL, {
  headers: { 'X-API-Key': API_KEY }
})
.then(response => {
  const data = response.data;
  if (data.isLive) {
    console.log('Stream is LIVE:', data.hlsUrl);
  }
})
.catch(error => console.error('Error:', error));

HTML Integration Example

<!DOCTYPE html>
<html>
<head>
    <title>My Stream</title>
    <script src="https://vjs.zencdn.net/8.6.1/video.min.js"></script>
    <link href="https://vjs.zencdn.net/8.6.1/video-js.css" rel="stylesheet">
</head>
<body>
    <div id="status">Loading...</div>
    <video id="video" class="video-js" controls style="display:none;"></video>

    <script>
        const API_KEY = 'YOUR_API_KEY';
        const API_URL = 'https://simulcast.me/api/public/stream/status';

        async function checkStream() {
            const response = await fetch(API_URL, {
                headers: { 'X-API-Key': API_KEY }
            });
            const data = await response.json();
            
            const statusDiv = document.getElementById('status');
            const video = document.getElementById('video');
            
            if (data.isLive) {
                statusDiv.textContent = `๐Ÿ”ด LIVE: ${data.streamKeyLabel}`;
                videojs('video').src({ 
                    type: 'application/x-mpegURL', 
                    src: data.hlsUrl 
                });
                video.style.display = 'block';
            } else {
                statusDiv.textContent = 'โšซ OFFLINE';
                video.style.display = 'none';
            }
        }

        checkStream();
        setInterval(checkStream, 5000);
    </script>
</body>
</html>

VLC Media Player

You can play your HLS stream directly in VLC Media Player using the HLS URL from the API response.

Method 1: Open Network Stream
  1. Open VLC Media Player
  2. Go to Media โ†’ Open Network Stream (or press Ctrl+N / Cmd+N)
  3. Paste your HLS URL from the API response (data.hlsUrl)
  4. Click Play
Method 2: Command Line
vlc "https://simulcast.me/hls/YOUR_TOKEN/index.m3u8?apiKey=YOUR_API_KEY"
Note: VLC will automatically handle HLS playback and buffering. The stream URL includes your API key for authentication.

WordPress Plugin

A WordPress plugin to easily embed your self-hosted Simulcast.me livestream using the API and HLS player.

โœจ Features:
  • Live Status Indicator: Automatically polls your stream status every 5 seconds
  • Auto-Play: Automatically shows and loads the player when you go live
  • HLS Support: Uses Video.js for reliable HLS playback
  • Stream Tipping: Integrated support for viewer tips using WooCommerce
  • Secure: Proxies API requests through your WordPress backend to keep your API Key hidden
  • Customizable: Simple shortcode to place the player anywhere
๐Ÿ’ฐ Stream Tips:

To accept tips, simply install and activate WooCommerce. The plugin will automatically create a hidden "Stream Tip" product for you. Users can click "Support the Stream" on the player, select an amount, and checkout via your existing WooCommerce payment gateways.

Bitcoin Payment Options: To accept Bitcoin tips via Lightning Network, you can install one of these payment plugins:

๐Ÿ“ฆ Installation:
  1. Upload the plugin folder to the /wp-content/plugins/ directory
  2. Activate the plugin through the 'Plugins' menu in WordPress
  3. Keep the file structure intact
โš™๏ธ Configuration:
  1. Go to Settings > Simulcast.me Stream
  2. Enter your Simulcast Public API Key
  3. Use the "Show/Hide" button to verify your key
  4. Click Save Changes
๐Ÿ“ Usage:

Embed the player on any page or post using the shortcode:

[simulcast_player]

๐Ÿ’ฐ Pricing & Bandwidth

โœ… Included Free:
  • 3 sats/min for Self Hosted destination (same as other platforms)
  • FREE if it's your first active destination
  • 10 GB/hour bandwidth included
๐Ÿ’ธ Overage Charges:
  • 5 sats per GB for bandwidth over 10 GB/hour
  • Overage is calculated and billed per-minute (not hourly)
  • Bandwidth resets at the top of each hour
๐Ÿ’ก Example:

If you use 12 GB in one hour, you'll be charged:
โ€ข 3 sats/min for streaming (if not first destination)
โ€ข 2 GB ร— 5 sats/GB = 10 sats for bandwidth overage
Total: 3 sats/min + 10 sats/hour overage

๐Ÿ”— Quick Test URLs

Status API (small JSON response):
HLS Playback URL (consumes bandwidth):