Authentication
All authenticated endpoints require a Bearer token in the Authorization header.
POST
/api/auth/register
Create a new account and receive an API token.
Request Body
{
"name": "John Doe",
"email": "john@example.com",
"password": "securepassword123",
"company_name": "My Digital Signage Co"
}
Response (201)
{
"token": "1|abc123...",
"user": { "id": 1, "name": "John Doe", "email": "john@example.com", ... },
"tenant": { "id": 1, "name": "My Digital Signage Co", "plan": "free", ... }
}
POST
/api/auth/login
Authenticate and receive a Bearer token.
Request Body
{
"email": "john@example.com",
"password": "securepassword123"
}
Response (200)
{
"token": "1|abc123...",
"user": { "id": 1, "name": "John Doe", ... },
"tenant": { "id": 1, "name": "My Digital Signage Co", ... }
}
POST
/api/auth/logout
Revoke the current access token.
Headers
Authorization: Bearer {token}
Response (200)
{
"message": "Logged out successfully."
}
GET
/api/auth/user
Get the authenticated user's profile and tenant info.
Headers
Authorization: Bearer {token}
Response (200)
{
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"role": "tenant_admin",
"tenant": { "id": 1, "name": "My Co", "plan": "free", ... }
}
}
Devices
Manage your display devices. All endpoints require Bearer token authentication.
GET
/api/devices
List all devices for your tenant.
Response (200)
{
"data": [
{
"id": 1, "name": "Lobby Display", "uuid": "abc-123",
"status": "online", "model": "Xiaomi Mi Box S",
"os_version": "11", "app_version": "2.0.0",
"last_seen_at": "2026-03-25T12:00:00Z", ...
}
],
"meta": { "current_page": 1, "last_page": 1, "total": 1 }
}
POST
/api/devices/pair
Pair a device using its 6-digit pairing code.
Request Body
{
"pairing_code": "4A7X2B",
"name": "Lobby Display"
}
Response (200)
{
"device": { "id": 1, "name": "Lobby Display", "uuid": "abc-123", "status": "online", ... }
}
GET
/api/devices/{id}
Get detailed information about a specific device.
Response (200)
{
"device": {
"id": 1, "name": "Lobby Display", "uuid": "abc-123",
"status": "online", "ip_address": "192.168.1.100",
"storage_total_mb": 16000, "storage_used_mb": 2400,
"wifi_signal": -45, "volume": 80, "is_locked": false, ...
}
}
PUT
/api/devices/{id}
Update device name, group, or other settings.
Request Body
{
"name": "Lobby Display - Main Entrance",
"device_group_id": 2
}
DELETE
/api/devices/{id}
Remove a device from your account.
Response (200)
{
"message": "Device deleted successfully."
}
POST
/api/devices/{id}/command
Send a remote command to a device (reboot, set_volume, refresh, screenshot, etc.).
Request Body
{
"type": "set_volume",
"payload": { "volume": 50 }
}
POST
/api/devices/{id}/lock
Lock the device to prevent unauthorized access.
Request Body
{
"pin": "1234"
}
POST
/api/devices/{id}/unlock
Unlock a locked device.
Response (200)
{
"message": "Device unlocked."
}
Content
Upload and manage your media content (videos, images, YouTube URLs, web pages).
GET
/api/content
List all content items. Supports filtering by type and status.
Query Parameters
?type=video&status=active&search=promo&per_page=20
Response (200)
{
"data": [
{
"id": 1, "name": "Summer Promo", "type": "video",
"file_size_mb": 12.5, "duration": 30, "status": "active",
"download_url": "https://...", "thumbnail_url": "https://...", ...
}
]
}
POST
/api/content
Upload new content. Use multipart/form-data for file uploads, or provide a source_url for YouTube/web content.
Request Body (multipart/form-data)
name: "Summer Promo Video"
type: "video" // video, image, youtube, web, livestream
file: (binary file) // for video/image uploads
source_url: "" // for youtube/web content
duration: 30 // display duration in seconds
Response (201)
{
"content": { "id": 5, "name": "Summer Promo Video", "type": "video", ... }
}
GET
/api/content/{id}
Get details of a specific content item.
PUT
/api/content/{id}
Update content name, duration, or other metadata.
Request Body
{
"name": "Updated Name",
"duration": 15
}
DELETE
/api/content/{id}
Delete a content item and its associated file.
Response (200)
{
"message": "Content deleted successfully."
}
Playlists
Create and manage playlists that organize your content for playback on devices.
GET
/api/playlists
List all playlists.
Response (200)
{
"data": [
{
"id": 1, "name": "Lobby Playlist", "transition": "fade",
"is_default": true, "items_count": 5, ...
}
]
}
POST
/api/playlists
Create a new playlist.
Request Body
{
"name": "Morning Playlist",
"transition": "fade",
"is_default": false
}
GET
/api/playlists/{id}
Get a playlist with all its items and content details.
PUT
/api/playlists/{id}
Update playlist name, transition, or default status.
DELETE
/api/playlists/{id}
Delete a playlist.
Response (200)
{
"message": "Playlist deleted successfully."
}
Schedules
Schedule playlists to play on specific devices, groups, or locations at specific times.
GET
/api/schedules
List all schedules for your tenant.
POST
/api/schedules
Create a new schedule with optional conditional playback.
Request Body
{
"playlist_id": 1,
"schedulable_type": "device",
"schedulable_id": 5,
"days_of_week": [1, 2, 3, 4, 5],
"start_time": "09:00",
"end_time": "17:00",
"start_date": "2026-04-01",
"end_date": "2026-06-30",
"priority": 10,
"is_active": true,
"conditions": [
{"type": "weather", "operator": "gt", "value": "30", "unit": "celsius"},
{"type": "day_type", "operator": "eq", "value": "weekday"},
{"type": "time_range", "operator": "between", "value": "09:00-17:00"}
]
}
PUT
/api/schedules/{id}
Update an existing schedule.
DELETE
/api/schedules/{id}
Delete a schedule.
Response (200)
{
"message": "Schedule deleted successfully."
}
Device Player API
These endpoints are used by the AdCast Player app running on devices. They do not require Bearer token authentication -- they use the device UUID for identification.
POST
/api/device/register
Register a new device or update an existing device. Returns a pairing code for the dashboard.
Request Body
{
"uuid": "unique-device-id-abc123",
"model": "Xiaomi Mi Box S",
"os_version": "11",
"app_version": "2.0.0",
"license_key": "ADCAST-XXXX-YYYY"
}
Response (200)
{
"device_id": 1,
"pairing_code": "4A7X2B",
"paired": false,
"device_name": null,
"is_locked": false,
"lock_pin": null,
"license_activated": false
}
POST
/api/device/heartbeat
Send periodic heartbeat with device status. Returns pending commands, emergency alerts, and app updates.
Request Body
{
"uuid": "unique-device-id-abc123",
"ip_address": "192.168.1.100",
"wifi_signal": -45,
"storage_total_mb": 16000,
"storage_used_mb": 2400,
"storage_free_mb": 13600,
"screen_on": true,
"volume": 80,
"uptime_seconds": 86400,
"current_content": "Summer Promo"
}
Response (200)
{
"status": "ok",
"has_update": true,
"is_locked": false,
"lock_pin": null,
"has_pending_commands": false,
"pending_commands": [],
"emergency_alerts": [],
"app_update": null
}
GET
/api/device/playlist?uuid={uuid}
Get the active playlist for the device based on current schedule. Includes content download URLs and cleanup instructions.
Response (200)
{
"playlist": {
"id": 1, "name": "Lobby Playlist", "transition": "fade",
"items": [
{
"id": 1, "content_id": 5, "name": "Summer Promo",
"type": "video", "download_url": "https://...",
"duration": 30, "file_hash": "abc123", "order": 1
}
]
},
"content_to_download": [ ... ],
"content_to_delete": [3, 7],
"show_watermark": false
}
GET
/api/device/content/{id}/download?uuid={uuid}
Download a content file for local caching. Returns binary file data or redirects to URL.
Response
Binary file download or 302 redirect to source URL.