Reseller API
For partner servers and panels to activate, renew and manage UTM Play TVs straight from their own system.
What it is
The reseller API lets your IPTV server's panel act on your customers' TVs in UTM Play: renew a MAC's license, push the playlist (M3U) to the TV, change the customer name, and look up devices, expiry dates and credits used.
Access is by token. Each token belongs to one partner server and is issued by the UTM Play team; the API does not create tokens.
Base URL
Routes live under /api/… on either address below; both answer the same way.
https://api2.utmplay.wtfhttps://utmplay.wtf
Use HTTPS. Every route allows CORS (Access-Control-Allow-Origin: *).
Authentication
Authorization: SEU_TOKEN
Send the token in the Authorization header, with no prefix. Routes also accept "Bearer YOUR_TOKEN" except get_device, which only accepts the bare token: always send the bare token.
/api/login checks the token and tells you which server it belongs to; it does not issue a new token and is not required before other calls.
Format
- POST bodies are JSON (Content-Type: application/json), except delete_mac, which takes the MAC in the URL.
- The MAC is matched exactly as stored: lowercase hex with colons, e.g. 00:1a:2b:3c:4d:5e.
- Successful responses carry JSON (some with Content-Type text/plain, inherited from the original API) or a short sentence of text. Errors are plain text, one line, with the HTTP error status.
- Expiry dates are YYYY-MM-DD; 9999-12-31 means lifetime.
Limits
- There is no general per-minute request limit. Please be gentle: run large batches sequentially, not in parallel.
- Wrong device code (device_key) on renew: after 5 failures on the same MAC, or 20 failures from the same server, within 1 hour, renewals are locked for 1 hour and answer 404 "Device not found", even with the right code.
- On a token with a platform list, routes that change a device refuse devices from other platforms (see below).
Allowed platforms per token
The UTM Play team can limit a token to some platforms (for example, only Samsung and LG). With no limit set, the token works for all of them, which is the default.
With a limit, the routes that change a device refuse a MAC whose recorded platform is not on the list, before writing anything or counting credits: 403 with the message below, ending with the device's platform (samsung, lg, roku, android, androidtv, firetv, ios…).
A device with no recorded platform is never refused. Lookups (get_device, device_expiration, count_credits, count_macs) and login are unchanged.
Platform not allowed for this token: roku
Affected routes: renew, add_playlist, update_client_name and delete_mac.
Errors common to every route with a token
On top of each route's own errors:
- 401Missing Authorization header.
Authorization token is required
- 403Unknown token.
Forbidden
- 405Wrong method (e.g. GET on a POST route). Empty body.
- 500Internal failure; try again later.
Internal Server Error
/api/loginLookupCheck the token
Checks that the token is valid and returns the server it belongs to. No Authorization header needed.
Parameters
tokenstring · JSON- Required: yesYour token.
Example
curl -X POST https://api2.utmplay.wtf/api/login \
-H 'Content-Type: application/json' \
-d '{"token":"SEU_TOKEN"}'Success
- 200Valid token.
{"status":"success", "role":"client", "server":"MeuServidor"}
Errors
- 400No token, or a body that is not JSON.
Token is required
- 403Unknown token.
Invalid token or IP not allowed
/api/renewChanges the deviceActivate or renew a MAC
Renews the TV license and stores the renewal's credit on the device: semi-annual = 1, annual = 2, lifetime = 3 (count_credits sums this value over your devices). If the license is still valid the new period starts at the current expiry date; if it has expired, from today.
Needs the MAC and the device code (device_key, 6 digits shown on the TV). The MAC must already exist: the TV must have opened UTM Play at least once. The device then belongs to your server.
Parameters
mac_addressstring · JSON- Required: yesTV MAC.
device_keystring · JSON- Required: yesDevice code shown on the TV.
renew_typestring · JSON- Required: yessemi_annual (6 months), annual (1 year) or lifetime.
revenda_idint · JSON- Required: noReseller id in your system (number). Used by count_credits and get_device.
clientestring · JSON- Required: noCustomer name, only echoed in the response.
reseller_namestring · JSON- Required: noAccepted for compatibility; not stored.
Example
curl -X POST https://api2.utmplay.wtf/api/renew \
-H 'Authorization: SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"mac_address":"00:1a:2b:3c:4d:5e","device_key":"123456","renew_type":"annual","revenda_id":42,"cliente":"joao"}'Success
- 200Renewed. Updated device.
{"id":"66f1c2a9e4b0a1b2c3d4e5f6","is_trial":1,"credit_count":2,"mac_address":"00:1a:2b:3c:4d:5e","app_type":"samsung","device_key":"123456","expire_date":"2027-10-12","revenda_id":42,"server":"MeuServidor","cliente":"joao","updated_at":"2026-10-06T00:27:49.952547665+02:00"}
Errors
- 400Invalid body: the message comes from the JSON decoder, e.g. revenda_id sent as text.
json: cannot unmarshal string into Go struct field .revenda_id of type int
- 400Unknown renew_type.
Invalid renew_type
- 400The device is already lifetime.
Renewal not allowed. Device has lifetime license.
- 403Device platform not in the token's list.
Platform not allowed for this token: roku
- 404Unknown MAC, wrong code, or locked after wrong codes (see Limits).
Device not found
/api/add_playlistChanges the devicePush the playlist to the TV
Stores the playlist URL (M3U) on the TV: replaces the device's first playlist or creates one if there is none. The device then belongs to your server; the customer name is taken from the URL's username= when present.
The response tells whether the playlist was created (InsertedID) or replaced (MatchedCount).
Parameters
device_idstring · JSON- Required: yesTV MAC.
urlstring · JSON- Required: yesM3U playlist URL.
revenda_idint · JSON- Required: noReseller id in your system (number).
reseller_namestring · JSON- Required: noReseller name, stored with a newly created playlist.
Example
curl -X POST https://api2.utmplay.wtf/api/add_playlist \
-H 'Authorization: SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"device_id":"00:1a:2b:3c:4d:5e","url":"http://exemplo.com:8080/get.php?username=joao&password=1234&type=m3u_plus&output=ts","revenda_id":42,"reseller_name":"Revenda X"}'Success
- 200Playlist created.
{"InsertedID":"6ac42465ca34be2c60e18662"} - 200Existing playlist replaced.
{"MatchedCount":1,"ModifiedCount":1,"UpsertedCount":0,"UpsertedID":null}
Errors
- 400Invalid body (JSON decoder message, as in renew).
json: cannot unmarshal …
- 403Device platform not in the token's list.
Platform not allowed for this token: roku
- 404Unknown MAC.
Device not found
/api/get_deviceLookupList and search devices
Lists YOUR server's devices, with filters and paging. Each item carries the number of devices matching the filter (total). With no results the response is null.
This route requires the bare token in Authorization (no "Bearer").
Parameters
macstring · URL- Required: noMAC prefix (case-insensitive).
device_keystring · URL- Required: noDevice code prefix.
clientestring · URL- Required: noCustomer name prefix.
revenda_idint · URL- Required: noExact reseller.
app_typestring · URL- Required: noExact platform (samsung, lg, roku…).
statusstring · URL- Required: noactive (expires after today) or expired.
pageint · URL- Required: noPage, from 1 (default 1).
limitint · URL- Required: noItems per page (default 10).
Example
curl 'https://api2.utmplay.wtf/api/get_device?mac=00:1a&status=active&page=1&limit=10' \ -H 'Authorization: SEU_TOKEN'
Success
- 200Devices found (application/json).
[{"__v":0,"_id":"66f1c2a9e4b0a1b2c3d4e5f6","app_type":"samsung","cliente":"joao","credit_count":2,"device_key":"123456","expire_date":"2027-10-12","is_trial":1,"mac_address":"00:1a:2b:3c:4d:5e","revenda_id":42,"server":"MeuServidor","total":1,"updated_at":"2026-10-06T00:27:49.952+02:00"}] - 200No device.
null
Errors
- 401Missing Authorization header.
Authorization token is required
- 401Unknown token, or sent with "Bearer ".
Invalid token
- 404Invalid text filter (regular-expression special characters).
Failed to find devices
/api/device_expirationLookupExpiry date of a MAC
Returns the device's license expiry date.
Parameters
mac_addressstring · URL- Required: yesTV MAC.
Example
curl 'https://api2.utmplay.wtf/api/device_expiration?mac_address=00%3A1a%3A2b%3A3c%3A4d%3A5e' \ -H 'Authorization: SEU_TOKEN'
Success
- 200Device found.
{"expire_date":"2027-10-12"}
Errors
- 400Missing mac_address.
mac_address is required
- 404Unknown MAC.
Device not found
/api/count_creditsLookupCredits used
Sums the credit of the latest renewal of each of your server's devices (semi-annual = 1, annual = 2, lifetime = 3). Without revenda_id, one server total; with revenda_id=all, one total per reseller; with a number, only that reseller. With nothing to sum the response is null.
Parameters
daysint · URL- Required: noOnly devices changed in the last N days.
revenda_idint or "all" · URL- Required: noall = group by reseller; number = only that reseller.
Example
curl 'https://api2.utmplay.wtf/api/count_credits?days=30&revenda_id=all' \ -H 'Authorization: SEU_TOKEN'
Success
- 200Without revenda_id.
[{"_id":"MeuServidor","total_credits":2}] - 200With revenda_id=all or a number.
[{"_id":42,"total_credits":2}] - 200Nothing to sum.
null
Errors
- 400days is not a number.
Invalid days parameter
- 400revenda_id is neither a number nor all.
Invalid revenda_id parameter
/api/count_macsLookupNumber of devices
How many devices are linked to your server.
Parameters
No parameters.
Example
curl https://api2.utmplay.wtf/api/count_macs \ -H 'Authorization: SEU_TOKEN'
Success
- 200Server total.
{"mac_count":1}
Errors
—
/api/update_client_nameChanges the deviceChange the customer name or code
Changes the customer name and/or the device code (device_key). Send at least one of them. Changing the code changes what the TV needs to be renewed.
The response is the same when the MAC does not exist (nothing is changed).
Parameters
mac_addressstring · JSON- Required: yesTV MAC.
new_client_namestring · JSON- Required: noNew customer name.
device_keystring · JSON- Required: noNew device code, digits only.
Example
curl -X POST https://api2.utmplay.wtf/api/update_client_name \
-H 'Authorization: SEU_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"mac_address":"00:1a:2b:3c:4d:5e","new_client_name":"maria"}'Success
- 200Request accepted.
Client details updated successfully
Errors
- 400Body is not JSON.
Failed to parse request body
- 400device_key has non-digits.
Device key must be numeric
- 400Neither new_client_name nor device_key.
No fields provided for update
- 403Device platform not in the token's list.
Platform not allowed for this token: roku
/api/delete_macChanges the deviceRemove a MAC
Removes the device from your server. The MAC goes in the URL (?mac=), no body. Only removes devices linked to your server.
Parameters
macstring · URL- Required: yesTV MAC.
Example
curl -X POST 'https://api2.utmplay.wtf/api/delete_mac?mac=00%3A1a%3A2b%3A3c%3A4d%3A5e' \ -H 'Authorization: SEU_TOKEN'
Success
- 200Removed.
Device deleted successfully, but no associated playlist found.
Errors
- 400Missing mac parameter.
MAC address is required
- 403Device platform not in the token's list.
Platform not allowed for this token: roku
- 404Unknown MAC or one from another server.
No device or playlist found to delete