API Documentation

RESTful API for managing digital signage programmatically

Overview

TheiaCast provides a comprehensive RESTful API for managing digital signage devices, content, playlists, and broadcasts. All endpoints require authentication via JWT Bearer token or API key.

Base URL

http://your-server:5001

Interactive API Documentation (Swagger)

TheiaCast includes an interactive Swagger UI where you can explore and test all API endpoints:

http://your-server:5001/swagger

Using Swagger UI

  1. Navigate to the Swagger UI URL
  2. Click the "Authorize" button (lock icon)
  3. Enter your JWT token in the format: Bearer YOUR_JWT_TOKEN
  4. Click "Authorize"
  5. Now you can test any endpoint directly from the browser

Authentication

TheiaCast supports two authentication methods:

  1. JWT Bearer Tokens - Short-lived tokens (1 hour) for interactive use
  2. API Keys - Long-lived tokens (years) for automation and integrations

Method 1: JWT Bearer Authentication

JWT tokens are ideal for web applications and interactive use. They expire after 1 hour but can be refreshed.

Get JWT Token

Endpoint: POST /auth/login

Request Body:

{
  "username": "admin",
  "password": "your-password",
  "totpCode": "123456"  // Optional - only if MFA is enabled
}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "refresh-token-here",
  "expiresAt": "2026-01-15T10:00:00Z"
}

Using JWT Tokens

Include the token in the Authorization header:

curl -X GET "http://localhost:5001/content" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Method 2: API Key Authentication

API keys are ideal for automation, scripts, CI/CD pipelines, and long-running integrations. They can be configured to never expire or expire after several years.

Create API Key

Endpoint: POST /api-keys

Authentication Required: JWT Bearer token (must be logged in to create API keys)

Request Body:

{
  "name": "Production Automation Script",
  "expiresInYears": 5  // Optional - null means never expires
}

Example Request:

curl -X POST "http://localhost:5001/api-keys" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Automation Script",
    "expiresInYears": 5
  }'

Example Response:

{
  "id": 1,
  "key": "tc_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8",
  "name": "Production Automation Script",
  "prefix": "tc_a1b2c",
  "createdAt": "2026-01-14T10:00:00Z",
  "expiresAt": "2031-01-14T10:00:00Z",
  "message": "⚠️ IMPORTANT: Save this API key now. You won't be able to see it again!"
}

⚠️ CRITICAL: The API key is only shown once upon creation. Store it securely - you cannot retrieve it again.

List Your API Keys

curl -X GET "http://localhost:5001/api-keys" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Revoke API Key

curl -X DELETE "http://localhost:5001/api-keys/1" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Using API Keys

Include the API key in the X-API-Key header:

curl -X GET "http://localhost:5001/content" \
  -H "X-API-Key: tc_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8"

JavaScript Example:

const apiKey = 'tc_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8';

fetch('http://localhost:5001/content', {
  headers: {
    'X-API-Key': apiKey
  }
})
.then(res => res.json())
.then(data => console.log(data));

Python Example:

import requests

api_key = 'tc_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8'

response = requests.get(
    'http://localhost:5001/content',
    headers={'X-API-Key': api_key}
)

print(response.json())

Environment Variable (Recommended):

# Store API key in environment variable
export THEIACAST_API_KEY="tc_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8"

# Use in scripts
curl -X GET "http://localhost:5001/content" \
  -H "X-API-Key: $THEIACAST_API_KEY"

Comparison: JWT vs API Keys

FeatureJWT Bearer TokensAPI Keys
Lifespan1 hour (refreshable)Years or never expires
Use CaseInteractive web appsAutomation, scripts, CI/CD
CreationLogin with username/passwordCreate via authenticated endpoint
HeaderAuthorization: Bearer {token}X-API-Key: {key}

Content Endpoints

Content items represent URLs, websites, or media that can be displayed on devices.

📄 Get All Content

Endpoint: GET /content

Retrieve all content items including URLs, auto-login credentials, and thumbnails.

curl -X GET "http://localhost:5001/content" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

➕ Create Content

Endpoint: POST /content

Create a new content item with optional auto-authentication.

curl -X POST "http://localhost:5001/content" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weather Dashboard",
    "url": "https://weather.example.com",
    "defaultDuration": 30
  }'

🔍 Get Content by ID

Endpoint: GET /content/{id}

curl -X GET "http://localhost:5001/content/1" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

✏️ Update Content

Endpoint: PATCH /content/{id}

Update an existing content item. Only include fields you want to change.

curl -X PATCH "http://localhost:5001/content/1" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "New Name"}'

🗑️ Delete Content

Endpoint: DELETE /content/{id}

curl -X DELETE "http://localhost:5001/content/1" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Broadcast Endpoints

Broadcasts allow you to push content to all devices or specific tagged devices, overriding their normal playlists.

📡 Start Broadcast

Endpoint: POST /broadcast/start

Start a new broadcast to all devices or specific tagged devices. Type can be 'url' or 'message'.

Example (URL Broadcast):

curl -X POST "http://localhost:5001/broadcast/start" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "url",
    "url": "https://emergency.example.com",
    "duration": 600,
    "tagIds": null
  }'

Example (Message Broadcast):

curl -X POST "http://localhost:5001/broadcast/start" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "message",
    "message": "Emergency: Building evacuation in progress.",
    "duration": null,
    "tagIds": [1, 2, 3]
  }'

🛑 End Broadcast

Endpoint: POST /broadcast/end

End the currently active broadcast and return devices to their normal playlists.

curl -X POST "http://localhost:5001/broadcast/end" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

🎬 Start Media Broadcast

Endpoint: POST /broadcast/start-media

Start a broadcast with an uploaded media file (image or video). Maximum file size: 4GB.

curl -X POST "http://localhost:5001/broadcast/start-media" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -F "type=image" \
  -F "file=@/path/to/emergency-notice.jpg" \
  -F "tagIds=1,2"

📻 Get Active Broadcast

Endpoint: GET /broadcast/active

Get the currently active broadcast, or null if no broadcast is active.

curl -X GET "http://localhost:5001/broadcast/active" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Common Use Cases

1. Emergency Broadcast to All Devices

# Start emergency URL broadcast
curl -X POST "http://localhost:5001/broadcast/start" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "url",
    "url": "https://emergency-procedures.com",
    "duration": null
  }'

# When emergency is over, end the broadcast
curl -X POST "http://localhost:5001/broadcast/end" \
  -H "Authorization: Bearer $TOKEN"

2. Automation Script Example (Python)

import requests

BASE_URL = "http://localhost:5001"
API_KEY = "tc_your_api_key_here"

headers = {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
}

# Get all content
response = requests.get(f"{BASE_URL}/content", headers=headers)
content_items = response.json()
print(f"Total content items: {len(content_items)}")

# Start emergency broadcast
broadcast_data = {
    "type": "url",
    "url": "https://emergency.example.com",
    "duration": 600  # 10 minutes
}
response = requests.post(f"{BASE_URL}/broadcast/start",
                         headers=headers,
                         json=broadcast_data)
broadcast = response.json()
print(f"Broadcast started: {broadcast['id']}")

Response Status Codes

  • 200 OK - Request successful
  • 201 Created - Resource created successfully
  • 400 Bad Request - Invalid request (check error message)
  • 401 Unauthorized - Missing or invalid authentication
  • 404 Not Found - Resource not found
  • 500 Internal Server Error - Server error (check logs)

Need Help?

Last Updated: January 14, 2026

API Version: v1