Panel REST API Reference¶
The DAZN DRM Panel exposes a JSON REST API at /api for headless
automation, external integrations, and scripting. All responses use
Content-Type: application/json; charset=utf-8.
Interactive API Explorer
Use the built-in API Explorer (Swagger UI) to browse endpoints, view schemas, and send test requests directly from the panel.
Base URL¶
The nginx rewrite rule maps /api to /api.php, so both
/api?action=... and /api.php?action=... work.
Authentication¶
Every request must include a Bearer token in the Authorization header.
Two token types are accepted:
- User API keys (recommended) — generated in Profile → API Keys.
Each key is prefixed with
dazn_and shown once on creation. - Legacy xaccel-codec token — the token configured in Global Config → xaccel-codec Token (still accepted for backward compatibility).
Error Response (401)¶
nginx Note¶
nginx does not forward the Authorization header to PHP-FPM by
default. The site config includes:
The API also falls back to getallheaders() if the standard
$_SERVER['HTTP_AUTHORIZATION'] is empty.
Request Format¶
- GET endpoints use query-string parameters.
- POST endpoints accept a JSON body (
Content-Type: application/json). POST endpoints that require no body can be called with an empty body or{}.
Error Handling¶
Method Not Allowed (405)¶
Returned when the wrong HTTP method is used.
Bad Request (400)¶
Returned for missing/invalid parameters or an unknown action.
Unknown Action (400)¶
Lists all available actions.
{
"error": "Unknown action",
"message": "Action 'foo' is not recognized.",
"available_actions": {
"GET": ["status", "schedule", "log", "streams", "card", "epg"],
"POST": [
"make_schedule", "build_epg", "start_channel", "stop_channel",
"reset_status", "refresh", "truncate_schedule", "truncate_log"
]
}
}
Internal Error (500)¶
GET Endpoints¶
health — System Health Check¶
Returns system health status, component checks (database, EPG file), and the same dashboard statistics shown at the top of the panel UI.
Response:
{
"status": "ok",
"checks": {
"database": "ok",
"epg_file": "ok"
},
"stats": {
"today_events": 8,
"total_scheduled": 42,
"active_streams": 2,
"competitions": 5,
"sports": 3,
"schedule_days": 5
}
}
| Field | Type | Description |
|---|---|---|
status |
string | "ok" if all checks pass, "degraded" if any fail. |
checks.database |
string | "ok" or "error". |
checks.epg_file |
string | "ok" or "missing". |
stats.today_events |
int | Events scheduled for today. |
stats.total_scheduled |
int | Total events in the schedule window. |
stats.active_streams |
int | Channels currently streaming. |
stats.competitions |
int | Active competitions. |
stats.sports |
int | Active sports. |
stats.schedule_days |
int | Number of days the EPG is built for (1–14, default 5). |
status — Schedule Status Overview¶
Returns a summary of scheduled events, active streams with computed stop times, and xaccel-codec stream statistics.
Response:
{
"date_range": {
"from": "2026-03-22",
"to": "2026-03-27"
},
"total_events": 42,
"active_streams": 2,
"active_channels": [
{
"channel_name": "DAZN_1",
"title": "Serie A: Milan vs Inter",
"start_time": "2026-03-22 20:45:00",
"stop_time": "2026-03-22 23:45:00",
"asset_id": "abc123def456"
}
],
"xaccel_streams": { }
}
| Field | Type | Description |
|---|---|---|
date_range.from |
string | Start of the schedule window (today). |
date_range.to |
string | End of the schedule window (schedule_days setting). |
total_events |
int | Total number of events in the window. |
active_streams |
int | Number of channels currently streaming (status = 1). |
active_channels[] |
array | Detail for each active stream. |
active_channels[].channel_name |
string | Channel identifier (e.g. DAZN_1). |
active_channels[].title |
string | Event title. |
active_channels[].start_time |
string | Event start (Y-m-d H:i:s). |
active_channels[].stop_time |
string | Computed stop time (start + stop_hour minutes from the competition table; defaults to 180 min if unset). |
active_channels[].asset_id |
string | DAZN asset identifier. |
xaccel_streams |
object | Raw stats from the xaccel-codec stream API. |
schedule — Full Schedule Listing¶
Returns all scheduled events within the configured date window, or events for a specific date.
# All events in the schedule window
curl -H "Authorization: Bearer $TOKEN" \
"https://dazn.xctv.stream/api?action=schedule"
# Events for a specific date
curl -H "Authorization: Bearer $TOKEN" \
"https://dazn.xctv.stream/api?action=schedule&date=2026-03-23"
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
date |
No | Filter to a single date (YYYY-MM-DD). |
Response:
{
"count": 12,
"events": [
{
"id": 1,
"date": "2026-03-22",
"start_time": "2026-03-22 15:00:00",
"title": "Serie A: Napoli vs Juventus",
"description": "Match description",
"asset_id": "abc123",
"competition_id": "serie_a",
"competition_title": "Serie A",
"sport_id": "soccer",
"channel_name": "DAZN_1",
"status": 0,
"verify_age": 0,
"image": "image-id-hash",
"image_url": "https://image.discovery.indazn.com/eu/v3/eu/none/image-id-hash/fill/none/top/none/85/334/187/webp/image"
}
]
}
| Field | Type | Description |
|---|---|---|
count |
int | Number of events returned. |
events[].id |
int | Database row ID. |
events[].date |
string | Event date (YYYY-MM-DD). |
events[].start_time |
string | Start time (Y-m-d H:i:s). |
events[].title |
string | Event title. |
events[].description |
string | Event description text. |
events[].asset_id |
string | DAZN asset identifier. |
events[].competition_id |
string | Competition identifier. |
events[].competition_title |
string | Competition display name. |
events[].sport_id |
string | Sport identifier. |
events[].channel_name |
string | Assigned channel name. |
events[].status |
int | 0 = inactive, 1 = streaming. |
events[].verify_age |
int | 1 if age verification is required. |
events[].image |
string | DAZN image identifier. |
events[].image_url |
string | Full CDN image URL (334×187 WebP). |
log — Operation Log¶
Returns the most recent log entries, newest first.
# Default: last 100 entries
curl -H "Authorization: Bearer $TOKEN" \
"https://dazn.xctv.stream/api?action=log"
# Last 20 entries
curl -H "Authorization: Bearer $TOKEN" \
"https://dazn.xctv.stream/api?action=log&limit=20"
Query Parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
limit |
No | 100 |
Number of entries to return (clamped to 1–1000). |
Response:
{
"count": 3,
"entries": [
{
"datetime": "2026-03-22 20:45:12",
"channel_name": "DAZN_1",
"message": "API START CHANNEL (rc=0)"
}
]
}
| Field | Type | Description |
|---|---|---|
count |
int | Number of entries returned. |
entries[].datetime |
string | Timestamp (Y-m-d H:i:s). |
entries[].channel_name |
string | Channel the entry relates to. |
entries[].message |
string | Log message text. |
streams — xaccel-codec Stream Stats¶
Returns current xaccel-codec stream statistics and category list.
Response:
| Field | Type | Description |
|---|---|---|
stats |
object | Stream statistics from xaccel-codec API. |
categories |
array | Category list from xaccel-codec API. |
card — Schedule Card Data¶
Returns the schedule grouped by day, formatted for visual card display.
This is the JSON equivalent of card.php.
Response:
{
"days": [
{
"date": "2026-03-22",
"label": "Sunday, 22 March 2026",
"events": [
{
"title": "Serie A: Milan vs Inter",
"channel_name": "DAZN 1",
"start_time": "2026-03-22 20:45:00",
"time_12h": "8:45 PM",
"image_url": "https://image.discovery.indazn.com/...",
"status": 1,
"asset_id": "abc123"
}
]
}
]
}
| Field | Type | Description |
|---|---|---|
days[] |
array | One entry per date with events. |
days[].date |
string | Date (YYYY-MM-DD). |
days[].label |
string | Human-readable date label. |
days[].events[].title |
string | Event title. |
days[].events[].channel_name |
string | Channel name (underscores replaced with spaces). |
days[].events[].start_time |
string | Start time (Y-m-d H:i:s). |
days[].events[].time_12h |
string | 12-hour formatted time (e.g. 8:45 PM). |
days[].events[].image_url |
string | Full CDN image URL. |
days[].events[].status |
int | 0 = inactive, 1 = streaming. |
days[].events[].asset_id |
string | DAZN asset identifier. |
epg — EPG Metadata¶
Returns information about the EPG XML file, channel definitions from the competition table, and today's programme count.
Response:
{
"epg_file": "xctv-dazn-epg.xml",
"exists": true,
"last_modified": "2026-03-22 03:58:01",
"size_bytes": 45230,
"channels": [
{
"channel_name": "DAZN_1",
"num_channels": 2,
"competition": "Serie A",
"competition_id": "serie_a",
"active": true
}
],
"today_programmes": 12
}
| Field | Type | Description |
|---|---|---|
epg_file |
string | EPG XML filename (from settings). |
exists |
bool | Whether the EPG file exists on disk. |
last_modified |
string|null | File modification timestamp, or null if missing. |
size_bytes |
int | File size in bytes. |
channels[] |
array | Channel definitions from the competition table. |
channels[].channel_name |
string | Channel base name. |
channels[].num_channels |
int | Number of resolution sub-channels. |
channels[].competition |
string | Competition display name. |
channels[].competition_id |
string | Competition identifier. |
channels[].active |
bool | Whether the competition is enabled. |
today_programmes |
int | Number of events scheduled for today. |
competition_groups — List Competition Groups¶
Returns all competition groups with their member competitions.
Response:
[
{
"id": 1,
"name": "FIFA World Cup Qualifiers",
"channel_name": "FIFA_WCQ",
"num_ch": 10,
"stop_hour": 180,
"channel_logo": "",
"epg_template_id": null,
"competitions": [
{
"id": 12,
"name": "WCQ Africa",
"competition_id": "abc123",
"active": true
},
{
"id": 15,
"name": "WCQ Europe",
"competition_id": "def456",
"active": true
}
]
}
]
| Field | Type | Description |
|---|---|---|
id |
int | Group ID. |
name |
string | Display name of the group. |
channel_name |
string | Shared channel base name (uppercase). |
num_ch |
int | Max channels for the group. |
stop_hour |
int | Stop-after duration in minutes. |
channel_logo |
string | Channel logo URL (may be empty). |
epg_template_id |
int|null | Associated EPG template, or null. |
competitions[] |
array | Competitions assigned to this group. |
competitions[].id |
int | Competition local DB ID. |
competitions[].name |
string | Competition display name. |
competitions[].competition_id |
string | DAZN competition identifier. |
competitions[].active |
bool | Whether the competition is enabled. |
POST Endpoints¶
All POST endpoints require Content-Type: application/json. Endpoints
that take no body parameters can be called with an empty body or {}.
make_schedule — Rebuild Schedule¶
Fetches the DAZN EPG and rebuilds the schedule table. Equivalent to running the nightly cron schedule job manually.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"https://dazn.xctv.stream/api?action=make_schedule"
Body: None required.
Response:
build_epg — Regenerate EPG XML¶
Rebuilds the EPG XML file from the current schedule data using per-competition templates.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"https://dazn.xctv.stream/api?action=build_epg"
Body: None required.
Response:
start_channel — Start a Channel¶
Starts a channel by invoking get.php with the given asset and channel
name. This triggers the full stream-acquisition flow: DAZN playback
request, Widevine key retrieval, and xaccel-codec stream start.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"asset_id": "abc123def456", "channel_name": "DAZN_1"}' \
"https://dazn.xctv.stream/api?action=start_channel"
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_id |
string | Yes | DAZN asset identifier (alphanumeric, hyphens, underscores). |
channel_name |
string | Yes | Target channel name (alphanumeric, hyphens, underscores, spaces). |
Response:
{
"ok": true,
"channel_name": "DAZN_1",
"asset_id": "abc123def456",
"exit_code": 0,
"output": ["line1", "line2"]
}
| Field | Type | Description |
|---|---|---|
ok |
bool | true if get.php exited with code 0. |
channel_name |
string | The channel that was started. |
asset_id |
string | The asset identifier used. |
exit_code |
int | Exit code from the get.php process. |
output |
array | Stdout/stderr lines from get.php. |
Validation: asset_id is sanitized to [a-zA-Z0-9_-] and
channel_name to [a-zA-Z0-9_- ]. Returns 400 if either is empty
after sanitization.
stop_channel — Stop a Channel¶
Stops all resolution sub-channels for the given channel name on xaccel-codec.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel_name": "DAZN_1"}' \
"https://dazn.xctv.stream/api?action=stop_channel"
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
channel_name |
string | Yes | Channel to stop. |
Response:
reset_status — Reset Channel Status¶
Sets the schedule status back to 0 (inactive) for all events matching
the given channel name, without stopping the xaccel-codec stream.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel_name": "DAZN_1"}' \
"https://dazn.xctv.stream/api?action=reset_status"
Body Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
channel_name |
string | Yes | Channel whose status to reset. |
Response:
refresh — Full Refresh¶
Performs a complete refresh cycle:
- Re-initializes API endpoints (clears cached URLs).
- Rebuilds the schedule from DAZN EPG.
- Regenerates the EPG XML file.
- Sends a schedule notification via Apprise (if enabled).
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"https://dazn.xctv.stream/api?action=refresh"
Body: None required.
Response:
truncate_schedule — Clear Schedule Table¶
Deletes all rows from the schedule table. Use with caution — this removes the entire schedule and active event tracking.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"https://dazn.xctv.stream/api?action=truncate_schedule"
Body: None required.
Response:
truncate_log — Clear Log Table¶
Deletes all rows from the log table.
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
"https://dazn.xctv.stream/api?action=truncate_log"
Body: None required.
Response:
Quick Reference¶
GET Endpoints¶
| Action | Parameters | Description |
|---|---|---|
health |
— | System health check + dashboard stats |
status |
— | Active streams, event counts, xaccel-codec stats, stop times |
schedule |
?date=YYYY-MM-DD |
Schedule listing (optional date filter) |
log |
?limit=N (1–1000, default 100) |
Recent log entries |
streams |
— | xaccel-codec stream stats and categories |
card |
— | Schedule card data grouped by day |
epg |
— | EPG file metadata, channels, programme count |
competition_groups |
— | Competition groups with member competitions |
POST Endpoints¶
| Action | Body | Description |
|---|---|---|
make_schedule |
— | Rebuild schedule from DAZN EPG |
build_epg |
— | Regenerate EPG XML |
start_channel |
{asset_id, channel_name} |
Start a channel |
stop_channel |
{channel_name} |
Stop a channel |
reset_status |
{channel_name} |
Reset channel status to inactive |
refresh |
— | Full refresh (endpoints + schedule + EPG + notification) |
truncate_schedule |
— | Clear schedule table |
truncate_log |
— | Clear log table |