Developer API
- Build on your RedMumble server
API overview
The RedMumble API lets you query your Mumble server state, embed live status badges in READMEs and community sites, and build bots and integrations. Server endpoints need an API key; badge endpoints are public.
Base URL
https://redmumble.eu
Quick start
Authentication
All /api/v1/* endpoints require an API key. Generate one under Settings → Advanced → API, badges and webhooks in your dashboard.
# Bearer header (preferred) curl -H "Authorization: Bearer YOUR_API_KEY" https://redmumble.eu/api/v1/server # Query parameter (alternative) curl "https://redmumble.eu/api/v1/server?key=YOUR_API_KEY"
Server API
GET /api/v1/server
Cached 15s. Returns current server status.
curl -H "Authorization: Bearer YOUR_API_KEY" https://redmumble.eu/api/v1/server
Response (200)
{
"id": 3,
"name": "MyServer",
"isRunning": true,
"connectedUsers": 4,
"maxUsers": "15",
"uptimeSeconds": 86400,
"welcomeText": "Welcome!"
}
Errors: 401 Unauthorized, 503 server unreachable.
GET /api/v1/server/users
Cached 10s. Returns connected users.
curl -H "Authorization: Bearer YOUR_API_KEY" https://redmumble.eu/api/v1/server/users
Response (200), one item shown
[
{
"session": 1,
"name": "Alice",
"channelId": 0,
"channelName": "Root",
"onlineSeconds": 1234,
"selfMute": false,
"selfDeaf": false
}
]
Errors: 401 Unauthorized, 503 server unreachable.
GET /api/v1/server/channels
Cached 60s. Returns the channel list.
curl -H "Authorization: Bearer YOUR_API_KEY" https://redmumble.eu/api/v1/server/channels
Response (200), abbreviated
[
{
"id": 0,
"name": "Root",
"parentId": -1,
"description": ""
}
]
Errors: 401 Unauthorized, 503 server unreachable.
POST /api/v1/server/message
Broadcasts a text message to all connected users. message is required, max 1000 characters.
curl -X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"message\":\"Hello from the API!\"}" \
https://redmumble.eu/api/v1/server/message
Response: 204 No Content on success. Errors: 400 validation error (message empty or over 1000 chars), 401 Unauthorized, 503 server unreachable.
Badge API
Badge endpoints are public, no API key needed. Every badge needs the serverId query parameter (the badge server ID shown in your dashboard), and badges must be turned on under Settings → Advanced. Responses are cached for 5 minutes (Cache-Control: public, max-age=300).
| Endpoint | What it shows | Use it in |
|---|---|---|
/api/badge/status | MUMBLE | ONLINE or OFFLINE (SVG) | GitHub, Markdown |
/api/badge/players | ONLINE | N/M players (SVG) | GitHub, Markdown |
/api/badge/shields | Shields.io JSON endpoint | Custom Shields.io badges |
/api/badge/status.png/api/badge/players.png | Same badges as PNG, 2× scale | Reddit, Discord, sites that block SVG |
/api/badge/userbar/api/badge/userbar.png | 350×19 pixel-font userbar | Forum signatures (HTML/BBCode) |
/api/badge/banner/api/badge/banner.png | 468×60 signature banner | Forum signatures (HTML/BBCode) |
Markdown example (GitHub README)

Shields.io response
{
"schemaVersion": 1,
"label": "mumble",
"message": "4/15 players",
"color": "brightgreen"
}
BBCode example (forum signature)
[img]https://redmumble.eu/api/badge/banner.png?serverId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx[/img]
Rate limits and errors
| Endpoint group | Limit | Window | Notes |
|---|---|---|---|
/api/v1/* | 6 req/min | Sliding window | Per API key |
/api/badge/* | Exempt | Public, CDN-friendly |
All /api/v1/* responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix timestamp).
429 response
{"error":"Rate limit exceeded. Please try again later."}
| Status | Meaning |
|---|---|
| 401 | Missing or invalid API key |
| 404 | Server not found or badges not enabled |
| 429 | Rate limit exceeded |
| 503 | Murmur server unreachable |
Webhooks
Webhooks send real-time server events to an HTTPS endpoint you control. When something happens, RedMumble POSTs a signed JSON payload to your URL within seconds.
Register a webhook under Settings → Advanced → API, badges and webhooks in your dashboard. Pick which events you want and copy the signing secret, which is shown once.
https://discord.com/api/webhooks/…) and RedMumble sends Discord-native embeds instead of the JSON below. Discord applies its own rate limits, so a very busy server may see some events dropped after retries.Envelope
{
"eventType": "user.connected",
"serverId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"occurredAt": "2026-02-22T14:30:00.000Z",
"payload": { ... }
}
Event types
| Event | When | Payload fields |
|---|---|---|
user.connected | A user joined your server | session, userId, userName |
user.disconnected | A user left your server | session, userId, userName |
message.sent | A broadcast was sent from the dashboard | session, userId, userName, text |
channel.created | A channel was created | channelId, name, parentId |
channel.deleted | A channel was deleted | channelId, name |
channel.renamed | A channel was renamed | channelId, oldName, newName |
server.config_updated | Server name or welcome text changed | null |
webhook.test | Test event sent from the dashboard | null |
User event fields
session: Murmur’s per-connection id. Use it to match a connect with its disconnect. New on every reconnect.userId: the user’s registered id on your server, or-1if they haven’t registered.userName: the name the user chose in their Mumble client.
Verifying the signature
Every delivery has an X-Webhook-Signature header with sha256=<hex>: an HMAC-SHA256 of the raw body using your webhook secret (a 64-character hex string). Always verify it before processing.
curl / openssl
SECRET="your-64-char-hex-secret"
BODY='{"eventType":"user.connected","serverId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","occurredAt":"2026-02-22T14:30:00Z","payload":null}'
EXPECTED=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$(echo "$SECRET" | xxd -r -p)" -binary | xxd -p | tr -d '\n')
echo "sha256=$EXPECTED"
C#
using System.Security.Cryptography;
using System.Text;
bool VerifyWebhookSignature(string secretHex, byte[] requestBody, string signatureHeader)
{
var secretBytes = Convert.FromHexString(secretHex);
using var hmac = new HMACSHA256(secretBytes);
var expected = "sha256=" + Convert.ToHexString(hmac.ComputeHash(requestBody)).ToLowerInvariant();
// Timing-safe comparison
return CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(expected),
Encoding.UTF8.GetBytes(signatureHeader));
}
Retries
| Attempt | Delay after previous |
|---|---|
| 1st | Immediate |
| 2nd | 5 seconds |
| 3rd | 30 seconds |
| 4th | 2 minutes |
After 4 attempts the delivery is marked failed; you can retrigger it from the delivery history in your dashboard. Your endpoint must respond within 10 seconds with any 2xx status.