Xtream-Masters Admin API
Full administrative control over your Xtream-Masters panel. Manage lines, devices, resellers, streams, servers, security, and system configuration through a comprehensive REST-style API.
Authentication
All API requests require your api_key parameter. Include it as a query parameter or POST field on every request.
Base URL
All requests are made to the following base URL format:
Replace {server-dns}, {stream-port}, and {api-access-code} with your server details.
Quick Start
2. Note your server DNS, streaming port, and API access code.
3. Make your first request to
user_info to verify connectivity.
curl "http://your-server:port/access-code/admin/index.php?api_key=YOUR_KEY&action=user_info"
Global Parameters
These parameters are available on all or most endpoints.
| Parameter | Type | Required | Description |
|---|---|---|---|
| api_key | string | Required | Your unique admin API key for authentication |
| action | string | Required | The API action to perform |
| start | int | Optional | Pagination offset for list endpoints (default: 0) |
| limit | int | Optional | Number of records to return (default: 50) |
| show_columns | string | Optional | Comma-separated list of column names to include in the response |
| hide_columns | string | Optional | Comma-separated list of column names to exclude from the response |
Warnings
A call that cannot do everything you asked still succeeds, and says what it skipped. Nothing is dropped in silence. Each entry names the parameter, why it was ignored, and — where a panel setting is the cause — the exact path that would make it work.
{
"status": "STATUS_SUCCESS",
"ticket_status": "closed",
"changed": 1,
"ids": [4],
"warnings": [
{ "code": "ticket_not_found", "field": "id", "message": "No ticket with id 999999999." }
]
}Failures carry error_code, and where one field is at fault,
field and a one-sentence hint. The status string is unchanged, so
existing clients keep working.
What’s New
Everything additive. A request that sends none of the new parameters behaves exactly as it always did.
- Add a TV series and its episodes with
create_seriesandcreate_episode, the same way the Watch Folder does. Send a TMDB id and the title, cover, plot, cast and seasons are filled in; each episode gets its own title, still image, plot and air date. See Adding movies and series from a script. create_moviewith just a TMDB id now fills name, poster, backdrop, plot, cast, genre, runtime, rating and year.- Encode starts by itself. A new movie or episode is encoded right after it is added when Watch Folder › Settings › Auto Encode is on, or when you send
encode=1.start_movie,stop_movie,start_episodeandstop_episodenow work (they answered “not served by this core yet”). - Safe to run again. The same movie source, the same series, or an episode number the series already has is refused with
error_code: "duplicate"and the existing id, so a script can re-run without making copies. - The next episode goes where the others are.
create_episodewithout a server uses the servers of the series’ other episodes. - Fixed: episodes added through the API had no plot, image or runtime in the apps; the container was stored as
mkvinstead of["mkv"]; a movie added withbouquetswas missing from the m3u playlist (it went into a listget.phpdoes not read); an episode added withbouquetswas put into the bouquet’s series list by its stream id; andcreate_series&dry_run=1created a real series.
- Support tickets — the whole queue: list, read with its conversation, open, reply, close, reopen, edit and delete. The panel has had Tickets for years and no API touched it.
- Activation codes on the admin API — all eight actions. They existed on the reseller API only, so an operator could give a reseller code management and have none themselves. An admin sees every code.
- ASN blocking —
get_blocked_asns,add_blocked_asn,edit_blocked_asn,delete_blocked_asn. Usually the largest security table on an install; page it withlimit. - MAG claims — the viewer reports raised from a set-top box.
- Content and catalogue writes — create, edit and delete for live channels, movies, series, episodes, radio stations, categories, bouquets, packages, groups and servers.
- Connection control — kill a live connection; list servers.
get_providers/create_provider/edit_provider/delete_provider. They read and wrote a table calledproviders, which does not exist — the query failed and the action answered with an empty body. The panel keeps providers instreams_providers. They now serve the table the panel uses. Noteprovider_idis the key, notid.get_blocked_uas/add_blocked_ua/delete_blocked_ua. Same fault: the table isblocked_user_agents, notblocked_uas.get_blocked_uasreturned the ISP list, and every block silently blocked nothing. The parameter isuser_agent; the documenteduais still accepted.edit_settings. Every call that named a real settings column failed outright. A call naming no real column appeared to succeed, which made it look intermittent.create_mag/create_enigma/create_line/create_activecode. Refused withSTATUS_INSUFFICIENT_CREDITSagainst an admin key. The admin was being priced with the reseller’s rules — but an admin has no credit balance: the panel routes them to a different page that has no pricing at all. An admin is no longer charged, and cannot be refused for a balance. Resellers are charged exactly as before.create_user/edit_user. Refused with “Sub-reseller creation is not enabled for your group” against an admin key. That is the reseller’s rule (create_sub_resellersplus Sub-Reseller Setup); the admin’s own page requires neither and offers every group. An admin may now create a reseller in any group, seed it withcredits, and name any owner.create_user/edit_usertakeapi_access=0|1— the Allow API Access switch (Reseller Members → Edit). Off removes the account’s key and cascades to every sub-reseller below it, as the panel does. A key whose account switch is off is refused withInvalid API key.(T-0000182)adjust_credits. An admin’s adjustment was debited from the admin’s ownreg_usersbalance — a number the panel never shows and never refills, so the action worked until that hidden balance hit zero and then refused. An admin now grants: the reseller is credited, nobody is debited, and the movement is recorded incredits_logagainst the admin.- Bouquets, categories and episodes were written without the rows that make them mean something.
A bouquet had no
categoriesblob, so it produced no catalogue; a new category was never counted, so player_api hid it; an episode was never filed intoseries_episodes, so its series reported no seasons; and movies and radio went into columnsget.phpdoes not read. Content created through the API now reaches customers — verified end to end againstplayer_api.phpandget.phpwith a real line. - Category item counts are maintained again. The count that decides whether a category is visible at all had not been recomputed since this core took over the panel’s cron work, so any category created since — in the panel as much as through the API — was invisible to every client. It is recomputed whenever content changes.
- A stream can no longer be created with no server behind it. The panel refuses that save
(“Select at least one server.”) and writes the binding; the API did not, so a stream created without
the panel’s
server_tree_datawas listed in every playlist and in player_api with nothing to play. Sendserver_id=3,server_ids=3,4,5, or the panel’sserver_tree_data;parent_idnames the server the others take their feed from andon_demandmarks the on-demand ones. An edit that does not mention servers keeps the ones the stream has — but no save may leave a stream with none. - Deleting a stream now removes its server binding. It did not, so every deleted stream left rows behind — and stream ids are reused, so a later stream could inherit a dead binding nobody gave it. Deleting a series now removes its episodes too, instead of leaving them as orphaned rows playable through no series. A series with a locked episode is refused rather than silently skipped.
- Reseller actions are logged the way the panel logs them. Every purchase, extension and deletion now
writes the reseller’s history row (Reg User Log) as well as the credit row, in the panel’s own
wording —
New M3U User: <user> - LineID: <id> - Pack-ID: <pkg>and its balance line. Sales made through the API used to be missing from that screen entirely while the credits still left the balance. A deletion by a reseller whose group has refunds switched off is now logged too; it used to leave no trace at all. - Audit rows say when the API did it. Every credit line the API writes ends with
Via api, so the ledger distinguishes a charge made in the panel from one made by an integration. The amount cell is also signed correctly now — a top-up read--1instead of+1. close_ticketreply shape. Its reply carriedstatustwice — once for the request outcome and once for the ticket — and a JSON parser keeps the last. The ticket’s state isticket_status.
- Dry runs.
dry_run=1on any write validates it and answers with the record it would have created — without writing. - Idempotent creates.
request_id=<your id>makes a retried create safe. - Bulk.
ids=1,2,3on delete / disable / enable / close, with a per-item result. - Pagination and filters on every list —
total,start,limit,returned,has_more, plussearch,order_by,order_dirand column filters. - Delta sync.
since/until, so a client can poll for what changed. - Machine-readable errors —
error_code,field,hint. - Refusals name the setting. A refusal caused by a permission carries the exact panel path and the permission key, in the reply and in the log, so the operator can fix it without guessing.
- Every action is permission-checked. The published API declared its permission list empty, so every check inside it passed and any valid key could do anything. All 182 actions now map to the Manage Groups permission the equivalent panel page requires.
General
Retrieve admin account information and package details.
Returns your admin account details including server info and account settings.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=user_info"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"status": 1,
"server_name": "Main Server",
"total_lines": 1250,
"total_resellers": 34,
"created_at": "2024-01-01 00:00:00"
}
}
Returns all packages configured in the system.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_packages"
{
"status": "STATUS_SUCCESS",
"data": [
{
"id": 1,
"package_name": "1 Month",
"credits": 5.00,
"duration_months": 1,
"is_trial": 0,
"is_official": 1,
"groups": [1, 3, 5]
}
]
}
Retrieve details of a single package by its ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Package ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_package&id=1"
Line Management
Create, manage, and control M3U lines. Admin creates lines with direct parameters (exp_date, bouquets, max_connections) rather than packages.
Creates a new M3U line with direct parameter control. Username and password are auto-generated if not provided.
| Parameter | Type | Required | Description |
|---|---|---|---|
| exp_date | string | Required | Expiration date (YYYY-MM-DD format) |
| username | string | Optional | Custom username (auto-generated if empty) |
| password | string | Optional | Custom password (auto-generated if empty) |
| bouquets_selected | json | Optional | JSON array of bouquet IDs, e.g. [1,2,3] |
| max_connections | int | Optional | Maximum simultaneous connections (default: 1) |
| member_id | int | Optional | Assign to a specific reseller by ID |
| is_restreamer | int | Optional | 0 = normal, 1 = restreamer account |
| is_trial | int | Optional | 0 = regular, 1 = trial |
| is_isplock | int | Optional | 0 = disabled, 1 = enable ISP lock |
| allowed_ips[] | array | Optional | Array of allowed IP addresses |
| allowed_ua[] | array | Optional | Array of allowed User-Agent strings |
| admin_notes | string | Optional | Admin-only notes |
| reseller_notes | string | Optional | Notes visible to reseller |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_line" \ -d "exp_date=2026-12-31" \ -d "username=customer1" \ -d "password=securepass" \ -d "max_connections=2" \ -d "bouquets_selected=[1,2,5]" \ -d "admin_notes=VIP customer"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 4521,
"username": "customer1",
"password": "securepass",
"exp_date": "2026-12-31",
"max_connections": 2,
"is_trial": 0,
"status": 1,
"admin_notes": "VIP customer",
"created_at": "2026-03-15 14:30:00"
}
}
Edit an existing line's properties. Only provided parameters are updated.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Line ID to edit |
| exp_date | string | Optional | New expiration date (YYYY-MM-DD) |
| username | string | Optional | New username |
| password | string | Optional | New password |
| bouquets_selected | json | Optional | JSON array of bouquet IDs |
| max_connections | int | Optional | Max simultaneous connections |
| member_id | int | Optional | Reassign to a reseller |
| is_restreamer | int | Optional | 0 or 1 |
| is_trial | int | Optional | 0 or 1 |
| is_isplock | int | Optional | 0 or 1 |
| allowed_ips[] | array | Optional | Allowed IPs |
| allowed_ua[] | array | Optional | Allowed User-Agents |
| admin_notes | string | Optional | Admin notes |
| reseller_notes | string | Optional | Reseller notes |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_line" \ -d "id=4521" \ -d "exp_date=2027-06-30" \ -d "max_connections=3"
Extend a line's expiry only — all other properties (bouquets, max connections, username, password) are preserved. The duration is added to the line's current expiry, or from now if already expired. Provide exactly ONE of: package, months, days, or an absolute exp_date. No credits are charged (admin action).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Line ID to extend |
| package | int | Optional | Package ID — adds its official duration |
| months | int | Optional | Number of months to add |
| days | int | Optional | Number of days to add |
| exp_date | string | Optional | Absolute new expiry (YYYY-MM-DD) |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=extend_line" \ -d "id=4521" \ -d "package=2"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 4521,
"exp_date": "2028-01-31 00:00:00"
}
}
Retrieve details of a single M3U line by its ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Line ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_line&id=4521"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 4521,
"username": "customer1",
"password": "securepass",
"exp_date": "2026-12-31",
"max_connections": 2,
"is_trial": 0,
"is_isplock": 0,
"is_restreamer": 0,
"enabled": 1,
"admin_enabled": 1,
"allowed_ips": [],
"allowed_ua": [],
"admin_notes": "VIP customer",
"reseller_notes": "",
"bouquets": [1, 2, 5],
"member_id": 0,
"created_at": "2026-03-15 14:30:00"
}
}
Retrieve a paginated list of all M3U lines. Supports search and status filtering.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset (default: 0) |
| limit | int | Optional | Records per page (default: 50) |
| search[value] | string | Optional | Search by username or other fields |
| filter | int | Optional | 1=Active, 2=Disabled, 3=Banned, 4=Expired, 5=Trial |
| line_username | string | Optional | One line by its exact username. username= is ignored on this listing (third-party panels send it with every call, and the PHP API ignored it too). |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_lines&start=0&limit=25&filter=1"
Permanently delete a line. This action cannot be undone.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Line ID to delete |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_line" \ -d "id=4521"
Temporarily disable a line (sets enabled=0). The line can be re-enabled later.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Line ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=disable_line" \ -d "id=4521"
Re-enable a previously disabled line (sets enabled=1).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Line ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=enable_line" \ -d "id=4521"
Admin-ban a line (sets admin_enabled=0). Unlike disable, banned lines cannot be re-enabled by resellers.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Line ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=ban_line" \ -d "id=4521"
Remove admin ban from a line (sets admin_enabled=1).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Line ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=unban_line" \ -d "id=4521"
MAG Device Management
Create and manage MAG device subscriptions with direct parameter control.
Register a new MAG device with its MAC address.
| Parameter | Type | Required | Description |
|---|---|---|---|
| mac | string | Required | MAC address (format: 00:1A:79:XX:XX:XX) |
| exp_date | string | Optional | Expiration date (YYYY-MM-DD) |
| bouquets_selected | json | Optional | JSON array of bouquet IDs |
| max_connections | int | Optional | Max connections (default: 1) |
| member_id | int | Optional | Assign to reseller by ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_mag" \ -d "mac=00:1A:79:AB:CD:EF" \ -d "exp_date=2026-12-31" \ -d "bouquets_selected=[1,2,5]"
Edit a MAG device's properties.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | MAG device ID |
| mac | string | Optional | New MAC address |
| exp_date | string | Optional | New expiration date |
| bouquets_selected | json | Optional | JSON array of bouquet IDs |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_mag" \ -d "id=301" \ -d "exp_date=2027-06-30"
Retrieve details of a single MAG device.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | MAG device ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_mag&id=301"
Retrieve a paginated list of all MAG devices.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
| filter | int | Optional | 1=Active, 2=Disabled, 3=Banned, 4=Expired |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_mags&start=0&limit=25"
Permanently delete a MAG device entry.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | MAG device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_mag" \ -d "id=301"
Temporarily disable a MAG device (sets enabled=0).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | MAG device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=disable_mag" \ -d "id=301"
Re-enable a previously disabled MAG device (sets enabled=1).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | MAG device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=enable_mag" \ -d "id=301"
Admin-ban a MAG device (sets admin_enabled=0).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | MAG device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=ban_mag" \ -d "id=301"
Remove admin ban from a MAG device (sets admin_enabled=1).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | MAG device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=unban_mag" \ -d "id=301"
Convert a MAG device subscription to an M3U line. Returns the newly created line with username and password.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | MAG device ID to convert |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=convert_mag" \ -d "id=301"
MAG Claims
Viewer reports raised from a MAG box — Panel → MAG Claims. A claim names the stream, the device and when it was reported, and is how a set-top user tells you a channel is down. New in this core: previously panel-only.
Page the claim list, newest ids last.
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | int | Optional | Rows to return |
| start | int | Optional | Offset |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=get_mag_claims" \ -d "limit=50"
One claim.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Claim ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=get_mag_claim" \ -d "id=1"
Remove a claim once it has been dealt with.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Claim ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_mag_claim" \ -d "id=1"
Enigma2 Device Management
Create and manage Enigma2 device subscriptions.
Register a new Enigma2 device with its MAC address.
| Parameter | Type | Required | Description |
|---|---|---|---|
| mac | string | Required | Device MAC address |
| exp_date | string | Optional | Expiration date (YYYY-MM-DD) |
| bouquets_selected | json | Optional | JSON array of bouquet IDs |
| max_connections | int | Optional | Max connections |
| member_id | int | Optional | Assign to reseller |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_enigma" \ -d "mac=AA:BB:CC:DD:EE:FF" \ -d "exp_date=2026-12-31"
Edit an Enigma2 device's properties.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Enigma2 device ID |
| mac | string | Optional | New MAC address |
| exp_date | string | Optional | New expiration date |
| bouquets_selected | json | Optional | JSON array of bouquet IDs |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_enigma" \ -d "id=501" \ -d "exp_date=2027-06-30"
Retrieve details of a single Enigma2 device.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Enigma2 device ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_enigma&id=501"
Retrieve a paginated list of all Enigma2 devices.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
| filter | int | Optional | 1=Active, 2=Disabled, 3=Banned, 4=Expired |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_enigmas&start=0&limit=25"
Permanently delete an Enigma2 device.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Enigma2 device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_enigma" \ -d "id=501"
Temporarily disable an Enigma2 device.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Enigma2 device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=disable_enigma" \ -d "id=501"
Re-enable a previously disabled Enigma2 device.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Enigma2 device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=enable_enigma" \ -d "id=501"
Admin-ban an Enigma2 device (sets admin_enabled=0).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Enigma2 device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=ban_enigma" \ -d "id=501"
Remove admin ban from an Enigma2 device (sets admin_enabled=1).
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Enigma2 device ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=unban_enigma" \ -d "id=501"
Convert an Enigma2 device subscription to an M3U line.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Enigma2 device ID to convert |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=convert_enigma" \ -d "id=501"
Sub-Reseller Management
Create and manage reseller accounts and their credits.
Create a new reseller account.
api_access=0|1— Allow API Access for the account, the T-0000182 switch. Not sent = on, like the admin form. An admin may always set it.
| Parameter | Type | Required | Description |
|---|---|---|---|
| username | string | Optional | Username (auto-generated if empty) |
| password | string | Optional | Password (auto-generated if empty) |
| string | Optional | Email address | |
| member_group_id | int | Optional | Member group to assign |
| notes | string | Optional | Internal notes |
| api_access | 0 | 1 | Optional | Allow API Access for the new account (the switch on Reseller Members → Edit). Not sent = 1, the same as the admin’s form. 0 creates the account without an API key and the API page blocked for it. The account still needs its group’s Can Use Reseller API to actually use the API. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_user" \ -d "username=reseller1" \ -d "password=strongpass123" \ -d "email=reseller@example.com" \ -d "member_group_id=3" \ -d "api_access=1"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 88,
"username": "reseller1",
"email": "reseller@example.com",
"member_group_id": 3,
"credits": 0,
"api_access": 1,
"status": 1,
"created_at": "2026-03-15 14:30:00"
}
}Edit a reseller account's properties.
api_access=0|1— Allow API Access for the account, the T-0000182 switch. Off removes the key at once and cascades to every sub-reseller below the account.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Reseller ID |
| username | string | Optional | New username |
| password | string | Optional | New password |
| string | Optional | New email | |
| member_group_id | int | Optional | New group ID |
| notes | string | Optional | Internal notes |
| api_access | 0 | 1 | Optional | Allow API Access. Not sent = unchanged. 0 removes the account’s API key at once and turns API access off for every sub-reseller below it, at every level, removing their keys too, exactly as the panel does. Turning it back on does not turn the sub-resellers back on; each has to be allowed again. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_user" \ -d "id=88" \ -d "email=new@example.com"
Retrieve details of a single reseller account.
- The row carries
api_access(1= the account may use the reseller API,0= blocked), the Allow API Access switch. Also onget_users. (T-0000182)
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Reseller ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_user&id=88"
Retrieve a paginated list of all reseller accounts.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
| reseller_username | string | Optional | One sub-reseller by its exact username. username= is ignored on this listing. |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_users&start=0&limit=25"
Permanently delete a reseller account.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Reseller ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_user" \ -d "id=88"
Temporarily disable a reseller account.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Reseller ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=disable_user" \ -d "id=88"
Re-enable a previously disabled reseller account.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Reseller ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=enable_user" \ -d "id=88"
Add or subtract credits from a reseller account. Use positive values to add and negative values to subtract.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Reseller ID |
| credits | float | Required | Credits to adjust (positive = add, negative = subtract) |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=adjust_credits" \ -d "id=88" \ -d "credits=100"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 88,
"credits_before": 50.00,
"credits_after": 150.00,
"adjusted": 100
}
}Streams & Content
Manage live streams, channels, movies, series, and radio stations.
Retrieve list of all live streams.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_streams"
Retrieve details of a single stream by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Stream ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_stream&id=10"
Retrieve list of all created channels.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_channels"
Retrieve details of a single channel.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Channel ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_channel&id=5"
Retrieve list of all radio stations.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_stations"
Retrieve list of all movies.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_movies"
Retrieve details of a single movie.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Movie ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_movie&id=100"
Retrieve list of all TV series.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_series_list"
Retrieve details of a single series.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Series ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_series&id=50"
Retrieve list of all episodes.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_episodes"
Retrieve details of a single episode.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Episode ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_episode&id=200"
Adding movies and series from a script
These endpoints add content the same way the panel’s Watch Folder does: the details come from TMDB, the item is placed on its server, the encode is started, and the apps show it with poster, plot and seasons. A script only needs the file location and, ideally, the TMDB id.
Movie: create_movie (tmdb_id + stream_source + category_id + server_id)
|-> details from TMDB, poster, runtime, rating
|-> placed on the server, added to the bouquets you name
'-> encode started (reply: "encode")
Series: create_series (tmdb_id + category_id) -> data.id = SERIES_ID
|-> title, cover, plot, cast, seasons from TMDB
'-> for every file:
create_episode (series_id=SERIES_ID + season_num + episode_num + stream_source)
|-> name "Show (2022) - S01E02 - Episode title", still, plot, air date
|-> same server(s) as the other episodes when none is named
|-> series seasons refreshed
'-> encode started- stream_source is a URL (
http://host/file.mkv) or a file on a server:s:<server_id>:<full path>, e.g.s:3:/media/shows/Show/S01/E01.mkv. - tmdb_id needs a TMDB API key in Settings. Without a key the id is stored and a
warningsline says no details were fetched. Anything you send yourself (name, plot, image, …) always wins over TMDB. - Safe to re-run. A movie whose
stream_sourceis already a movie in the same category, a series with the same TMDB id or title in the same category, and an episode number the series already has are refused witherror_code: "duplicate"and the existing id indata.id. Keep that id and move on, or sendallow_duplicate=1. - Look up before you add:
get_series_list&search=<title>andget_episodes&search=<title>page through what exists; use them instead ofmysql_querypolling. - Container (
target_container) defaults to the file extension of the source,mp4when it has none, and is stored as the panel stores it:["mkv"]. - Encode. See the
encodeparameter.start_movie/start_episodestart it again at any time.
Add a movie. With tmdb_id the name (“Title (Year)”), poster, backdrop, plot, cast, director, genre, runtime, rating, year and trailer are filled from TMDB.
| Parameter | Type | Required | Description |
|---|---|---|---|
| stream_source | string | Required | URL of the file, or s:<server_id>:<path> for a file on a server. |
| tmdb_id | int | Optional | TMDB movie id. Fills everything below that you do not send. |
| stream_display_name | string | Required* | Movie name. *Not needed when tmdb_id is sent. |
| category_id | int | Required | Movie category id (get_categories). Without one the movie is in no list. |
| server_id | int | Required | Which streaming server(s) carry it. server_id=3, server_ids=3,4 or the panel’s server_tree_data. parent_id makes the others take their feed from that server, on_demand=3,4 marks on-demand ones. List them with get_servers. |
| bouquets | list | Optional | Bouquet ids, e.g. 1,4. The movie is added to them. |
| stream_icon | string | Optional | Poster shown in lists. Default: the TMDB poster / movie_image. |
| target_container | string | Optional | mp4, mkv, … Default: the source’s extension, else mp4. |
| plot | string | Optional | Description. |
| movie_image | string | Optional | Poster / still image URL. Also becomes stream_icon when that is not sent. |
| backdrop_path | string | Optional | Backdrop image URL. |
| cast | string | Optional | Comma-separated actors. |
| director | string | Optional | Director(s). |
| genre | string | Optional | Genre text, e.g. Drama, Crime. |
| country | string | Optional | Country. |
| release_date | string | Optional | YYYY-MM-DD. |
| episode_run_time | int | Optional | Runtime in minutes (sets duration and duration_secs). |
| rating | number | Optional | Rating, e.g. 7.4. |
| youtube_trailer | string | Optional | YouTube video id. |
| movie_propeties | JSON | Optional | The whole properties object, written exactly as sent. Use it only if you build the object yourself; the fields above are merged for you. |
| direct_source | 0|1 | Optional | 1 = players get the source URL directly; nothing is encoded. |
| encode | 0|1 | Optional | 1 starts the encode on every server right after the save, 0 never. Not sent: follows the panel setting Watch Folder › Settings › Auto Encode, the same switch the watch folder uses. A direct_source=1 item is never encoded. The reply says what happened in encode. |
| allow_duplicate | 0|1 | Optional | Send 1 to add it even when the same item already exists (see the duplicate check above). |
| dry_run | 0|1 | Optional | 1 checks everything and shows the record it would write, without writing it. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_movie" \ -d "tmdb_id=27205" \ --data-urlencode "stream_source=s:3:/media/movies/Inception.2010.mkv" \ -d "category_id=9" \ -d "server_id=3" \ -d "bouquets=1"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 991421,
"type": 2,
"category_id": 9,
"stream_display_name": "Inception (2010)",
"stream_source": ["s:3:/media/movies/Inception.2010.mkv"],
"stream_icon": "https://image.tmdb.org/t/p/w600_and_h900_bestv2/....jpg",
"target_container": ["mkv"],
"movie_propeties": {
"tmdb_id": 27205, "name": "Inception", "releasedate": "2010-07-15",
"duration": "02:28:00", "duration_secs": 8880, "rating": 8.37,
"genre": "Action, Science Fiction, Adventure", "plot": "...",
"movie_image": "https://image.tmdb.org/...", "backdrop_path": ["https://image.tmdb.org/..."]
},
"year": "2010"
},
"encode": { "started": true, "reason": "watch folder setting Auto Encode", "servers": [3] }
}{
"status": "STATUS_EXISTS_SOURCE",
"data": { "id": 991421 },
"error": "This source is already a movie in this category (id 991421).",
"error_code": "duplicate",
"field": "id"
}Change a movie. Only the fields you send change. Property fields (plot, rating, …) are merged into the existing properties; tmdb_id re-reads TMDB.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Movie id. |
| ... | Optional | Any field of create_movie. | |
| encode | 0|1 | Optional | 1 re-starts the encode after the save. Not sent: no encode on an edit. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_movie" \ -d "id=991421" \ --data-urlencode "plot=New description" \ -d "rating=8.1"
Delete a movie, its server binding and its encoded file.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Movie id. ids=1,2,3 deletes several. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_movie" \ -d "id=991421"
Add a TV series (the show itself; episodes are added with create_episode). With tmdb_id the title (“Name (Year)”), cover, backdrop, plot, cast, genre, rating, first air date, runtime, trailer and the seasons list are filled from TMDB.
| Parameter | Type | Required | Description |
|---|---|---|---|
| tmdb_id | int | Optional | TMDB TV id. Fills everything below that you do not send. |
| title | string | Required* | Series name. *Not needed when tmdb_id is sent. |
| category_id | int | Required | Series category id (get_categories, type series). |
| bouquets | list | Optional | Bouquet ids. The series is added to them. |
| cover | string | Optional | Cover image URL. |
| backdrop_path | string | Optional | Backdrop image URL. |
| plot | string | Optional | Description. |
| cast | string | Optional | Actors. |
| director | string | Optional | Director(s). |
| genre | string | Optional | Genre text. |
| rating | number | Optional | Rating. |
| releaseDate | string | Optional | First air date YYYY-MM-DD. |
| episode_run_time | int | Optional | Episode runtime in minutes. |
| youtube_trailer | string | Optional | YouTube video id. |
| allow_duplicate | 0|1 | Optional | Send 1 to add it even when the same item already exists (see the duplicate check above). |
| dry_run | 0|1 | Optional | 1 checks everything and shows the record it would write, without writing it. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_series" \ -d "tmdb_id=202010" \ -d "category_id=7" \ -d "bouquets=1"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 9967,
"title": "Kus Ucusu (2022)",
"category_id": 7,
"cover": "https://image.tmdb.org/t/p/w600_and_h900_bestv2/....jpg",
"genre": "Drama",
"rating": 7,
"releaseDate": "2022-06-03",
"tmdb_id": 202010,
"seasons": [
{ "season_number": 1, "name": "Season 1", "episode_count": 8, "air_date": "2022-06-03", "cover": "https://image.tmdb.org/..." },
{ "season_number": 2, "name": "Season 2", "episode_count": 8, "air_date": "2023-12-14", "cover": "https://image.tmdb.org/..." }
],
"episode_run_time": 45
}
}{
"status": "STATUS_EXISTS_NAME",
"data": { "id": 9967 },
"error": "This series already exists in this category (id 9967). Add episodes to it with create_episode&series_id=9967.",
"error_code": "duplicate",
"field": "id"
}Change a series. Only the fields you send change; tmdb_id re-reads TMDB and refreshes the seasons.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Series id. |
| ... | Optional | Any field of create_series. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_series" \ -d "id=9967" \ --data-urlencode "cover=https://example.com/cover.jpg"
Delete a series and all its episodes. A series with a locked episode is refused.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Series id. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_series" \ -d "id=9967"
Add one episode to a series. When the series has a TMDB id, the episode title, still image, plot, air date and runtime come from TMDB for that season and episode number. The series’ seasons are refreshed after the save.
| Parameter | Type | Required | Description |
|---|---|---|---|
| series_id | int | Required | The series (from create_series / get_series_list). series is accepted too. |
| season_num | int | Required | Season number. season is accepted too. |
| episode_num | int | Required | Episode number (1 or more). episode is accepted too. |
| stream_source | string | Required | URL of the file, or s:<server_id>:<path>. |
| server_id | int | Required* | Which streaming server(s) carry it. server_id=3, server_ids=3,4 or the panel’s server_tree_data. parent_id makes the others take their feed from that server, on_demand=3,4 marks on-demand ones. List them with get_servers. *Not needed when the series already has episodes: the new one goes on the same server(s), and warnings says so. |
| stream_display_name | string | Optional | Default: <series title> - S01E02 plus - <episode title> when TMDB knows it. |
| target_container | string | Optional | Default: the source’s extension, else mp4. |
| tmdb_id | int | Optional | TMDB id of the episode, stored in its properties. |
| plot | string | Optional | Description. |
| movie_image | string | Optional | Poster / still image URL. Also becomes stream_icon when that is not sent. |
| release_date | string | Optional | YYYY-MM-DD. |
| episode_run_time | int | Optional | Runtime in minutes (sets duration and duration_secs). |
| rating | number | Optional | Rating, e.g. 7.4. |
| movie_propeties | JSON | Optional | The whole properties object, written exactly as sent. Use it only if you build the object yourself; the fields above are merged for you. |
| direct_source | 0|1 | Optional | 1 = players get the source URL directly; nothing is encoded. |
| encode | 0|1 | Optional | 1 starts the encode on every server right after the save, 0 never. Not sent: follows the panel setting Watch Folder › Settings › Auto Encode, the same switch the watch folder uses. A direct_source=1 item is never encoded. The reply says what happened in encode. |
| allow_duplicate | 0|1 | Optional | Send 1 to add it even when the same item already exists (see the duplicate check above). |
| dry_run | 0|1 | Optional | 1 checks everything and shows the record it would write, without writing it. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_episode" \ -d "series_id=9967" \ -d "season_num=1" \ -d "episode_num=2" \ --data-urlencode "stream_source=s:3:/media/shows/Kus Ucusu/S01/E02.mp4"
{
"status": "STATUS_SUCCESS",
"data": {
"id": 991420,
"type": 5,
"stream_display_name": "Kus Ucusu (2022) - S01E02 - Episode 2",
"stream_source": ["s:3:/media/shows/Kus Ucusu/S01/E02.mp4"],
"stream_icon": "https://image.tmdb.org/t/p/w600_and_h900_bestv2/....jpg",
"target_container": ["mp4"],
"series_no": 9967,
"movie_propeties": {
"name": "Kus Ucusu (2022) - S01E02 - Episode 2", "season": 1, "episode": 2,
"tmdb_id": 3721893, "plot": "...", "release_date": "2022-06-03",
"duration": "00:41:00", "duration_secs": 2460, "movie_image": "https://image.tmdb.org/..."
}
},
"encode": { "started": true, "reason": "watch folder setting Auto Encode", "servers": [3] },
"warnings": ["no server was named; used the servers of the series' other episodes (3)"]
}{
"status": "STATUS_EXISTS_SOURCE",
"data": { "id": 991420 },
"error": "Series 9967 already has S01E02 (stream id 991420). Use edit_episode to change it, or send allow_duplicate=1.",
"error_code": "duplicate",
"field": "id"
}{ "status": "STATUS_INVALID_INPUT", "error": "Series 99999 does not exist.", "error_code": "not_found", "field": "series_id" }
{ "status": "STATUS_INVALID_INPUT", "error": "season_num is required and must be a number.", "error_code": "field_required", "field": "season_num" }
{ "status": "STATUS_INVALID_INPUT", "error": "Select at least one server. ...", "error_code": "server_required", "field": "server_id" }Change an episode. Only the fields you send change; property fields are merged. Sending series_id / season_num / episode_num moves it.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Episode id. |
| ... | Optional | Any field of create_episode. | |
| encode | 0|1 | Optional | 1 re-starts the encode after the save. Not sent: no encode on an edit. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_episode" \ -d "id=991420" \ --data-urlencode "plot=New description"
Delete an episode, its server binding and its encoded file.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Episode id. ids=1,2,3 deletes several. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_episode" \ -d "id=991420"
Start a live stream.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Stream ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=start_stream" \ -d "id=10"
Stop a live stream.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Stream ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=stop_stream" \ -d "id=10"
Start a channel.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Channel ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=start_channel" \ -d "id=5"
Stop a channel.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Channel ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=stop_channel" \ -d "id=5"
Start (or re-start) the encode of a movie on every server it is on, or on server_id only. Answers {"id":100,"started":true,"servers":[3]}.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Movie ID |
| server_id | int | Optional | One server only. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=start_movie" \ -d "id=100"
Stop the encode of a movie. Answers {"id":100,"stopped":true,"servers":[3]}.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Movie ID |
| server_id | int | Optional | One server only. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=stop_movie" \ -d "id=100"
Start (or re-start) the encode of an episode on every server it is on, or on server_id only.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Episode id. |
| server_id | int | Optional | One server only. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=start_episode" \ -d "id=991420"
{ "status": "STATUS_SUCCESS", "data": { "id": 991420, "started": true, "servers": [3] } }Stop the encode of an episode.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Episode id. |
| server_id | int | Optional | One server only. |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=stop_episode" \ -d "id=991420"
Configuration
Manage bouquets, groups, categories, access codes, EPGs, and transcode profiles.
Bouquets
CRUD operations for bouquet management.
A bouquet carries a categories blob (the four category lists and their counts) and a
type, and the catalogue builder takes each bouquet’s category order from that blob. The API
wrote neither, so every bouquet it created or edited produced no catalogue at all — the line
authenticated and the customer saw an empty app, whatever the id lists said. Both are now written, and
recomputed from the final lists on every save.
Two ways to say what a bouquet holds, and you may use either:
- By category —
live_categories,vod_categories,series_categories,radio_categories, each a JSON array or comma-separated list of category ids. The channel and series lists are DERIVED from them, which is what the panel’s own screen does. This wins if both forms are sent. - By id —
bouquet_data, a JSON object withstream,movies,radiosandseriesarrays. Unchanged, and still supported.
Note the storage: live channels, created channels, radio AND movies all live in
bouquet_channels; only series are separate. That is what the panel writes and what
get.php reads — filing movies into bouquet_movies by name left them out of every
playlist while they still showed in player_api.
Retrieve all bouquets.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_bouquets"
Retrieve a single bouquet by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Bouquet ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_bouquet&id=1"
Create a new bouquet.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_bouquet" \ -d "bouquet_name=Premium Sports"
Edit an existing bouquet.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Bouquet ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_bouquet" \ -d "id=1" \ -d "bouquet_name=Premium Sports HD"
Delete a bouquet.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Bouquet ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_bouquet" \ -d "id=1"
Groups
CRUD operations for member group management.
List all member groups.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_groups"
Get single group by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Group ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_group&id=1"
Create a new member group.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_group" \ -d "group_name=Premium Resellers"
Edit a member group.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Group ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_group" \ -d "id=1"
Delete a member group.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Group ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_group" \ -d "id=1"
Categories
CRUD operations for stream categories.
List all categories.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_categories"
Get single category by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Category ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_category&id=1"
Create a new category.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_category" \ -d "category_name=Sports"
Edit a category.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Category ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_category" \ -d "id=1"
Delete a category.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Category ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_category" \ -d "id=1"
Access Codes
CRUD operations for API access code management.
List all access codes.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_access_codes"
Get single access code.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Access Code ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_access_code&id=1"
Create a new access code.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_access_code"
Edit an access code.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Access Code ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_access_code" \ -d "id=1"
Delete an access code.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Access Code ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_access_code" \ -d "id=1"
EPG
Manage Electronic Program Guide sources.
List all EPG sources.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_epgs"
Get single EPG source.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | EPG ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_epg&id=1"
Add a new EPG source.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_epg"
Edit an EPG source.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | EPG ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_epg" \ -d "id=1"
Delete an EPG source.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | EPG ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_epg" \ -d "id=1"
Force reload EPG data from all sources.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=reload_epg"
Transcode Profiles
Manage transcoding profiles for streams.
List all transcode profiles.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_transcode_profiles"
Get single transcode profile.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Profile ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_transcode_profile&id=1"
Create a new transcode profile.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_transcode_profile"
Edit a transcode profile.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Profile ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_transcode_profile" \ -d "id=1"
Delete a transcode profile.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Profile ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_transcode_profile" \ -d "id=1"
Security
Manage IP blocking, User-Agent blocking, ISP blocking, and RTMP IP management.
IP Blocking
Block and manage blocked IP addresses.
Retrieve all blocked IP addresses.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_blocked_ips"
Add an IP address to the blocklist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| ip | string | Required | IP address to block |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=add_blocked_ip" \ -d "ip=192.168.1.100"
Remove an IP address from the blocklist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Blocked IP entry ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_blocked_ip" \ -d "id=15"
Remove all IP addresses from the blocklist.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=flush_blocked_ips"
User-Agent Blocking
Block specific User-Agent strings — Panel → User Agents.
These three actions never worked. They read and wrote a table called blocked_uas, which does not exist on any install — the panel keeps blocked agents in blocked_user_agents. get_blocked_uas answered with the ISP list instead, and every add_blocked_ua silently blocked nothing. They now read and write the table the panel uses.
The parameter is user_agent, matching the column. ua, which the old documentation named, is still accepted.
Retrieve all blocked User-Agent strings.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_blocked_uas"
Add a User-Agent string to the blocklist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| user_agent | string | Required | User-Agent string to block (ua also accepted) |
| exact_match | int | Optional | 1 to match the whole string rather than a substring |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=add_blocked_ua" \ -d "user_agent=BadBot/1.0"
Remove a User-Agent string from the blocklist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Blocked UA entry ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_blocked_ua" \ -d "id=5"
ASN Blocking
The autonomous-system blocklist behind Panel → Blocked ASNs, gated by the block_asns group permission. It is usually the largest security table on an install — tens of thousands of rows — so always page it with limit. New in this core: the panel has had this screen for years and the API had no action for it at all.
Page the ASN blocklist. Supports the standard start, limit, search, order_by and order_dir parameters.
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | int | Optional | Rows to return — use it, the table is large |
| start | int | Optional | Offset |
| search | string | Optional | Match against the ISP, domain or country |
< s p a n c l a s s = " h l - c m d " > c u r l < / s p a n > < s p a n c l a s s = " h l - f l a g " > - X P O S T < / s p a n > < s p a n c l a s s = " h l - s t r " > " h t t p : / / d n s : p o r t / a c c e s s / a d m i n / i n d e x . p h p " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a p i _ k e y = Y O U R _ K E Y " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a c t i o n = g e t _ b l o c k e d _ a s n s " < / s p a n > < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " l i m i t = 5 0 " < / s p a n >
One ASN record.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Row ID |
< s p a n c l a s s = " h l - c m d " > c u r l < / s p a n > < s p a n c l a s s = " h l - f l a g " > - X P O S T < / s p a n > < s p a n c l a s s = " h l - s t r " > " h t t p : / / d n s : p o r t / a c c e s s / a d m i n / i n d e x . p h p " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a p i _ k e y = Y O U R _ K E Y " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a c t i o n = g e t _ b l o c k e d _ a s n " < / s p a n > < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " i d = 1 " < / s p a n >
Add an ASN to the blocklist. blocked=1 enforces it; exclude_restreamer=1 lets restreamer lines through it.
| Parameter | Type | Required | Description |
|---|---|---|---|
| asn | int | Required | Autonomous system number |
| isp | string | Optional | ISP name, as shown in the panel |
| domain | string | Optional | ISP domain |
| country | string | Optional | ISO country code |
| blocked | int | Optional | 1 to enforce the block |
| exclude_restreamer | int | Optional | 1 to exempt restreamer lines |
< s p a n c l a s s = " h l - c m d " > c u r l < / s p a n > < s p a n c l a s s = " h l - f l a g " > - X P O S T < / s p a n > < s p a n c l a s s = " h l - s t r " > " h t t p : / / d n s : p o r t / a c c e s s / a d m i n / i n d e x . p h p " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a p i _ k e y = Y O U R _ K E Y " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a c t i o n = a d d _ b l o c k e d _ a s n " < / s p a n > < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a s n = 6 4 5 1 2 " < / s p a n > < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " i s p = E x a m p l e H o s t i n g " < / s p a n > < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " b l o c k e d = 1 " < / s p a n >
Change an ASN record — typically to toggle blocked.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Row ID |
| blocked | int | Optional | 1 or 0 |
< s p a n c l a s s = " h l - c m d " > c u r l < / s p a n > < s p a n c l a s s = " h l - f l a g " > - X P O S T < / s p a n > < s p a n c l a s s = " h l - s t r " > " h t t p : / / d n s : p o r t / a c c e s s / a d m i n / i n d e x . p h p " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a p i _ k e y = Y O U R _ K E Y " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a c t i o n = e d i t _ b l o c k e d _ a s n " < / s p a n > < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " i d = 1 " < / s p a n > < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " b l o c k e d = 0 " < / s p a n >
Remove an ASN from the blocklist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Row ID |
< s p a n c l a s s = " h l - c m d " > c u r l < / s p a n > < s p a n c l a s s = " h l - f l a g " > - X P O S T < / s p a n > < s p a n c l a s s = " h l - s t r " > " h t t p : / / d n s : p o r t / a c c e s s / a d m i n / i n d e x . p h p " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a p i _ k e y = Y O U R _ K E Y " < / s p a n > \ < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " a c t i o n = d e l e t e _ b l o c k e d _ a s n " < / s p a n > < s p a n c l a s s = " h l - f l a g " > - d < / s p a n > < s p a n c l a s s = " h l - s t r " > " i d = 1 " < / s p a n >
ISP Blocking
Block connections from specific ISPs.
Retrieve all blocked ISPs.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_blocked_isps"
Add an ISP to the blocklist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| isp | string | Required | ISP name to block |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=add_blocked_isp" \ -d "isp=SomeVPN Provider"
Remove an ISP from the blocklist.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Blocked ISP entry ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_blocked_isp" \ -d "id=3"
RTMP IP Management
Manage allowed RTMP IP addresses.
List all allowed RTMP IPs.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_rtmp_ips"
Add a new allowed RTMP IP.
| Parameter | Type | Required | Description |
|---|---|---|---|
| ip | string | Required | RTMP IP address |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_rtmp_ip" \ -d "ip=10.0.0.50"
Edit an RTMP IP entry.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | RTMP IP entry ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_rtmp_ip" \ -d "id=1"
Delete an RTMP IP entry.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | RTMP IP entry ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_rtmp_ip" \ -d "id=1"
Support Tickets
The ticket queue behind Panel → Tickets. Two tables sit under it: the ticket itself (subject, member, state, unread flags) and its replies. New in this core — neither API exposed any of it before, so an integration could sell a customer a line and never see them ask for help.
status is 1 for open and 0 for closed. An admin reply reopens a closed ticket; a member’s reply does not. Every reply marks the ticket read for the side that wrote it and unread for the other. reply_ticket tells you when it has reopened one, in warnings.
Page the queue. Filter on status for open or closed, or on admin_read=0 for the ones waiting on you.
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | int | Optional | Rows to return |
| start | int | Optional | Offset |
| status | int | Optional | 1 open, 0 closed |
| admin_read | int | Optional | 0 for tickets you have not read |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=get_tickets" \ -d "status=1" \ -d "admin_read=0"
The ticket row plus every reply, oldest first, in replies, with reply_count. Reading marks it read for the admin, exactly as opening the panel view does — pass keep_unread=1 to leave the flag alone.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Ticket ID |
| keep_unread | int | Optional | 1 to leave the ticket unread |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=get_ticket" \ -d "id=2"
Raise a ticket against a reseller account.
| Parameter | Type | Required | Description |
|---|---|---|---|
| member_id | int | Required | reg_users id the ticket belongs to |
| title | string | Required | Subject |
| status | int | Optional | 1 open (default in the panel) |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_ticket" \ -d "member_id=6" \ -d "title=Payment not credited" \ -d "status=1"
Append an admin message. If the ticket was closed this reopens it, which is what the panel does; the reply carries reopened: true and a warning saying so.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Ticket ID |
| message | string | Required | The reply body |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=reply_ticket" \ -d "id=2" \ -d "message=Credited now, sorry for the wait."
Close one ticket with id, or many with ids. The reply reports ticket_status, changed and the ids it changed; ids that do not exist come back in warnings rather than failing the call.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Optional | Ticket ID |
| ids | string | Optional | Comma-separated ticket IDs |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=close_ticket" \ -d "ids=2,3,4"
The same, in the other direction.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Optional | Ticket ID |
| ids | string | Optional | Comma-separated ticket IDs |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=open_ticket" \ -d "id=2"
Change a ticket row — its title or the read flags.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Ticket ID |
| title | string | Optional | New subject |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_ticket" \ -d "id=2" \ -d "title=Billing query"
Remove a ticket. Its replies are left in place, as in the panel.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Ticket ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_ticket" \ -d "id=2"
Activation Codes
The activation-code screens — Panel → Activation Codes, gated by users to view and add_user / edit_user to change. New on the admin API: all eight actions existed on the reseller API and none on this one, so an operator could hand a reseller code management and have none themselves. An admin sees every code, not just their own, and is never charged for one.
Every code on the install, paged.
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | int | Optional | Rows to return |
| start | int | Optional | Offset |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=get_activecodes" \ -d "limit=50"
One code.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Code ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=get_activecode" \ -d "id=1"
Generate one or more codes against a package. count=N generates N.
| Parameter | Type | Required | Description |
|---|---|---|---|
| package | int | Required | Package ID the code activates |
| count | int | Optional | How many to generate |
| notes | string | Optional | Free-text note |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=create_activecode" \ -d "package=1" \ -d "count=5"
Change a code row.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Code ID |
| notes | string | Optional | Free-text note |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_activecode" \ -d "id=1" \ -d "notes=reissued"
Allow a code to be redeemed.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Code ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=enable_activecode" \ -d "id=1"
Stop a code being redeemed.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Code ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=disable_activecode" \ -d "id=1"
Generate a new random activation code, replacing the existing one. Returns both the old and new codes. The device pairing is kept. To free the code from its device instead, use clear_activecode_device.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Code ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=reset_activecode" \ -d "id=1"
Remove the device (and app) the activation code is paired to. The code, package, expiry and bouquets stay the same. The next device that logs in with the code is paired to it. Permission: edit_user.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Code ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=clear_activecode_device" \ -d "id=1"
{
"status": "STATUS_SUCCESS",
"data": { "id": 1, "code": "1940000195", "old_device_id": "00:1A:79:19:40:0A" }
}Remove a code.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Code ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=delete_activecode" \ -d "id=1"
Server Management
Manage servers, view statistics, and perform system operations.
Retrieve a list of all configured servers.
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_servers"
Retrieve details of a single server.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Server ID |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_server&id=1"
Edit server settings and configuration.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Server ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_server" \ -d "id=1"
Edit proxy server settings.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | int | Required | Proxy server ID |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=edit_proxy" \ -d "id=1"
Retrieve server statistics including CPU, memory, disk usage, and connection counts.
| Parameter | Type | Required | Description |
|---|---|---|---|
| server_id | int | Optional | Specific server ID (returns all if omitted) |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=get_server_stats&server_id=1"
{
"status": "STATUS_SUCCESS",
"data": {
"server_id": 1,
"cpu_usage": 23.5,
"mem_usage": 62.1,
"disk_usage": 45.8,
"uptime": "45 days",
"active_connections": 342,
"total_streams": 128
}
}Reload the nginx configuration on the server.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=reload_nginx"
Reload the system cache.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=reload_cache"
Clear temporary files from the server.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=clear_temp"
Clear the stream cache on the server.
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=clear_streams"
Terminate an active user connection by its activity ID. Use live_connections to get active activity IDs.
| Parameter | Type | Required | Description |
|---|---|---|---|
| activity_id | int | Required | The activity ID of the connection to terminate |
| server_id | int | Optional | Server ID (defaults to main server) |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=kill_connection" \ -d "activity_id=12345"
{
"status": "STATUS_SUCCESS"
}Terminate a running process on the server by its PID. Useful for killing stuck stream processes.
| Parameter | Type | Required | Description |
|---|---|---|---|
| pid | int | Required | The process ID to terminate |
| server_id | int | Optional | Server ID (defaults to main server) |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=kill_pid" \ -d "pid=54321"
{
"status": "STATUS_SUCCESS"
}Logs & Monitoring
Monitor activity, connections, credits, and system events.
Retrieve user activity logs with pagination support.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=activity_logs&start=0&limit=50"
View currently active/live connections across all lines and devices.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=live_connections&start=0&limit=50"
Retrieve credit transaction logs across all resellers.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=credit_logs&start=0&limit=50"
Retrieve reseller action logs and audit trail.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=user_logs&start=0&limit=50"
Retrieve login history for all users.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=login_logs&start=0&limit=50"
Retrieve client connection logs and history.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=client_logs&start=0&limit=50"
Retrieve MAG device event logs.
| Parameter | Type | Required | Description |
|---|---|---|---|
| start | int | Optional | Pagination offset |
| limit | int | Optional | Records per page |
| search[value] | string | Optional | Search term |
curl -X GET "http://dns:port/access_code/admin/index.php?api_key=YOUR_KEY&action=mag_events&start=0&limit=50"
Response Format
All API responses follow a consistent JSON structure.
{
"status": "STATUS_SUCCESS" | "STATUS_FAILURE",
"data": { // Object or Array depending on the endpoint }
}
status field before processing the data field. On failure, the data field may contain an error message or be empty.
Status Codes
All possible status values returned by the API.
STATUS_SUCCESSSTATUS_FAILURESTATUS_EXISTS_USERNAMESTATUS_EXISTS_MACSTATUS_INVALID_MACSTATUS_INVALID_DATESTATUS_INVALID_INPUTSTATUS_INSUFFICIENT_CREDITSSTATUS_INVALID_PACKAGESTATUS_NO_PERMISSIONSAdvanced
Advanced administrative operations. Use with extreme caution.
Execute a raw SQL query against the database. Returns the query result set for SELECT queries, or affected row count for INSERT/UPDATE/DELETE.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | Required | The SQL query to execute |
curl -X POST "http://dns:port/access_code/admin/index.php" \ -d "api_key=YOUR_KEY" \ -d "action=mysql_query" \ --data-urlencode "query=SELECT id, username, exp_date FROM lines WHERE member_id = 88 LIMIT 10"
{
"status": "STATUS_SUCCESS",
"data": [
{
"id": 4521,
"username": "customer1",
"exp_date": "2026-12-31"
},
{
"id": 4522,
"username": "customer2",
"exp_date": "2027-03-15"
}
]
}