Documentation Index
Fetch the complete documentation index at: https://docs.mixlarlabs.com/llms.txt
Use this file to discover all available pages before exploring further.
Toast Notification API
The Toast Notification API is a lightweight HTTP REST server that allows external applications to send toast notifications to your Mixlar device.
Base URL
Network Access Options
- Local:
http://localhost:8889 (this computer only)
- Local Network:
http://[YOUR-LOCAL-IP]:8889 (e.g., http://192.168.1.100:8889)
- Tailscale:
http://[TAILSCALE-IP]:8889 or https://[HOSTNAME]:8889 (with certificates)
To get all available network addresses:
Authentication
All endpoints (except /health) require API key authentication.
Methods
Header Authentication (Recommended)
X-API-Key: your-api-key-here
Query Parameter Authentication
?api_key=your-api-key-here
Getting Your API Key
The API key is automatically generated on first startup and stored in mixer_config.json under the key toast_api_key. You can also:
- Check the console output when the server starts
- Use the Toast Settings UI in the desktop app
- Call
POST /api/toast/regenerate to generate a new key
Rate Limiting
- Limit: 30 requests per minute per IP address
- Window: 60 seconds rolling window
- Response: HTTP 429 Too Many Requests
{
"error": "Rate limited",
"message": "Too many requests"
}
Endpoints
Health Check
Check if the API server is running.
Authentication: Not required
Response: 200 OK
{
"status": "ok",
"version": "1.0",
"port": 8889
}
Send Toast Notification
Send a toast notification to the device.
Authentication: Required
Request Body:
{
"message": "Build Complete!",
"icon": "checkmark",
"subtitle": "webpack compiled successfully",
"duration_ms": 5000,
"color": "00FF00"
}
Parameters:
| Field | Type | Required | Description | Constraints |
|---|
message | string | Yes | Header text displayed in bold | Max 30 characters |
icon | string | No | Icon name (see below) | Default: "bell" |
subtitle | string | No | Subtitle text displayed below | Max 40 characters |
duration_ms | integer | No | Display duration in milliseconds | 1000-30000, default: 3000 |
color | string | No | Background color (hex) | With or without # prefix |
Available Icons:
bell - Notification bell
checkmark - Success checkmark
warning - Warning triangle
close - Error/close X
settings - Gear icon
wifi - WiFi signal
audio - Speaker icon
play - Play button
pause - Pause button
volume - Volume icon
mute - Mute icon
power - Power button
refresh - Refresh/reload
home - Home icon
download - Download arrow
upload - Upload arrow
Response: 200 OK
{
"status": "success",
"message": "Toast notification sent"
}
Error Responses:
400 Bad Request - Missing required fields
{
"error": "Bad request",
"message": "message field is required"
}
401 Unauthorized - Invalid API key
{
"error": "Unauthorized",
"message": "Invalid API key"
}
429 Too Many Requests - Rate limit exceeded
{
"error": "Rate limited",
"message": "Too many requests"
}
List Toast Handlers
Get a list of all available toast handlers and their status.
Authentication: Required
Response: 200 OK
{
"status": "success",
"handlers": [
{
"id": "obs",
"name": "OBS Studio",
"enabled": true,
"loaded": true,
"color": "#9147FF"
},
{
"id": "spotify",
"name": "Spotify",
"enabled": true,
"loaded": false,
"color": "#1DB954"
}
]
}
Get Server Status
Get information about the API server and device connection.
Authentication: Required
Response: 200 OK
{
"status": "success",
"server_running": true,
"device_connected": true,
"port": 8889,
"rate_limit": {
"window_seconds": 60,
"max_requests": 30
}
}
Get all available network addresses and Tailscale status.
Authentication: Required
Response: 200 OK
{
"status": "success",
"addresses": [
{
"ip": "localhost",
"url": "http://localhost:8889",
"type": "This Computer"
},
{
"ip": "100.64.1.2",
"url": "https://mydevice.tailnet.ts.net:8889",
"type": "Tailscale (HTTPS - Secure Remote Access)",
"tailscale": true,
"https": true
},
{
"ip": "192.168.1.100",
"url": "http://192.168.1.100:8889",
"type": "Local Network"
}
],
"tailscale": {
"installed": true,
"running": true,
"ip": "100.64.1.2",
"hostname": "mydevice.tailnet.ts.net"
},
"recommended": "tailscale"
}
Example Usage
cURL
Basic Example:
curl -X POST http://localhost:8889/api/toast/send \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"message": "Test Notification",
"icon": "bell",
"subtitle": "From API",
"duration_ms": 5000,
"color": "FF5733"
}'
Success Notification:
curl -X POST http://localhost:8889/api/toast/send \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"message": "Build Complete!",
"icon": "checkmark",
"color": "00FF00"
}'
Error Notification:
curl -X POST http://localhost:8889/api/toast/send \
-H "X-API-Key: YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"message": "Build Failed",
"icon": "close",
"subtitle": "Check console for errors",
"duration_ms": 10000,
"color": "FF0000"
}'
Python
import requests
API_KEY = "YOUR_API_KEY_HERE"
BASE_URL = "http://localhost:8889"
def send_toast(message, icon="bell", subtitle=None, duration_ms=3000, color=None):
"""Send a toast notification."""
url = f"{BASE_URL}/api/toast/send"
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
payload = {
"message": message,
"icon": icon
}
if subtitle:
payload["subtitle"] = subtitle
if duration_ms:
payload["duration_ms"] = duration_ms
if color:
payload["color"] = color
response = requests.post(url, json=payload, headers=headers)
return response.json()
# Examples
send_toast("Server Started", icon="checkmark", color="00FF00")
send_toast("New Email", icon="bell", subtitle="From: john@example.com")
send_toast("Critical Error", icon="warning", color="FF0000", duration_ms=10000)
JavaScript / Node.js
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY_HERE';
const BASE_URL = 'http://localhost:8889';
async function sendToast(message, options = {}) {
const {
icon = 'bell',
subtitle = null,
duration_ms = 3000,
color = null
} = options;
const payload = { message, icon };
if (subtitle) payload.subtitle = subtitle;
if (duration_ms) payload.duration_ms = duration_ms;
if (color) payload.color = color;
try {
const response = await axios.post(`${BASE_URL}/api/toast/send`, payload, {
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
}
});
return response.data;
} catch (error) {
console.error('Toast error:', error.response?.data || error.message);
throw error;
}
}
// Examples
await sendToast('Deployment Complete', { icon: 'checkmark', color: '00FF00' });
await sendToast('Test Failed', {
icon: 'close',
subtitle: 'Unit tests: 15 failed',
color: 'FF0000',
duration_ms: 8000
});
PowerShell
$apiKey = "YOUR_API_KEY_HERE"
$baseUrl = "http://localhost:8889"
function Send-Toast {
param(
[string]$Message,
[string]$Icon = "bell",
[string]$Subtitle,
[int]$DurationMs = 3000,
[string]$Color
)
$headers = @{
"X-API-Key" = $apiKey
"Content-Type" = "application/json"
}
$body = @{
message = $Message
icon = $Icon
}
if ($Subtitle) { $body.subtitle = $Subtitle }
if ($DurationMs) { $body.duration_ms = $DurationMs }
if ($Color) { $body.color = $Color }
$json = $body | ConvertTo-Json
Invoke-RestMethod -Uri "$baseUrl/api/toast/send" `
-Method Post `
-Headers $headers `
-Body $json
}
# Examples
Send-Toast -Message "Backup Complete" -Icon "checkmark" -Color "00FF00"
Send-Toast -Message "Disk Space Low" -Icon "warning" -Subtitle "Only 5GB remaining" -Color "FFA500"
Bash
#!/bin/bash
API_KEY="YOUR_API_KEY_HERE"
BASE_URL="http://localhost:8889"
send_toast() {
local message="$1"
local icon="${2:-bell}"
local subtitle="$3"
local duration_ms="${4:-3000}"
local color="$5"
local json="{\"message\":\"$message\",\"icon\":\"$icon\""
[ -n "$subtitle" ] && json="$json,\"subtitle\":\"$subtitle\""
[ -n "$duration_ms" ] && json="$json,\"duration_ms\":$duration_ms"
[ -n "$color" ] && json="$json,\"color\":\"$color\""
json="$json}"
curl -X POST "$BASE_URL/api/toast/send" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "$json"
}
# Examples
send_toast "Tests Passed" "checkmark" "" 3000 "00FF00"
send_toast "Build Started" "settings" "Running webpack..." 5000 "0080FF"
Use Cases
CI/CD Integration
GitHub Actions:
- name: Notify Build Complete
run: |
curl -X POST http://YOUR_SERVER:8889/api/toast/send \
-H "X-API-Key: ${{ secrets.TOAST_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"message": "Build Complete", "icon": "checkmark", "color": "00FF00"}'
Jenkins Pipeline:
post {
success {
sh '''
curl -X POST http://localhost:8889/api/toast/send \
-H "X-API-Key: ${TOAST_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"message": "Deploy Success", "icon": "checkmark", "color": "00FF00"}'
'''
}
failure {
sh '''
curl -X POST http://localhost:8889/api/toast/send \
-H "X-API-Key: ${TOAST_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"message": "Deploy Failed", "icon": "close", "color": "FF0000"}'
'''
}
}
Server Monitoring
# Monitor disk space
import psutil
def check_disk_space():
disk = psutil.disk_usage('/')
percent_used = disk.percent
if percent_used > 90:
send_toast(
"Disk Space Critical",
icon="warning",
subtitle=f"{percent_used}% used",
color="FF0000",
duration_ms=10000
)
elif percent_used > 75:
send_toast(
"Disk Space Low",
icon="warning",
subtitle=f"{percent_used}% used",
color="FFA500"
)
Task Automation
# Long-running task completion
import time
def process_data():
# Long task...
time.sleep(3600)
send_toast(
"Data Processing Complete",
icon="checkmark",
subtitle="1000 records processed",
color="00FF00"
)
HTTPS with Tailscale
For secure remote access, use Tailscale with HTTPS:
- Install Tailscale: https://tailscale.com/download
- Enable MagicDNS: In Tailscale admin console
- Generate Certificates:
tailscale cert yourhostname.tailnet.ts.net
- Place Certificates: Copy
.crt and .key files to main/certs/ folder
- Restart App: API server will automatically detect and use HTTPS
Your API will now be available at:
https://yourhostname.tailnet.ts.net:8889
Troubleshooting
Cannot Connect to API
-
Check if server is running:
curl http://localhost:8889/api/toast/health
-
Check firewall: Ensure port 8889 is not blocked
-
Check device connection: API requires device to be connected
Unauthorized Errors
- Verify API key: Check
mixer_config.json for toast_api_key
- Check header format: Use
X-API-Key (case-sensitive)
- Regenerate key: Use desktop app settings or restart server
Rate Limit Errors
- Wait: Rate limits reset after 60 seconds
- Reduce frequency: Send max 30 requests per minute
- Batch notifications: Combine multiple events into single notification
Security Considerations
- API Key Storage: Store API keys securely (environment variables, secrets manager)
- Local Network: API accessible to anyone on your network by default
- Tailscale: Recommended for secure remote access
- HTTPS: Use Tailscale certificates for encrypted communication
- Firewall: Block port 8889 from internet if not using Tailscale
Documentation Version: 1.0
Last Updated: 2025-12-10
API Port: 8889