Skip to content

Live TV API

Channel management, stream playback, EPG, DVR, and HDHomeRun emulation.

Channels

List channels

http
GET /api/livetv/channels
Authorization: Bearer <token>

Response:

json
[
  {
    "id": 1,
    "name": "Movies",
    "number": 1,
    "sourceType": "virtual",
    "scheduleMode": "shuffle",
    "alwaysOn": false,
    "category": "Movies",
    "logoUrl": "/artwork/channels/1/logo.jpg",
    "enabled": true
  }
]

Create channel

http
POST /api/livetv/channels
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "name": "Action Movies",
  "number": 5,
  "sourceType": "virtual",
  "scheduleMode": "shuffle",
  "category": "Movies",
  "programs": [
    { "filePath": "/data/movies/Die Hard (1988)/Die Hard (1988).mkv", "title": "Die Hard" },
    { "filePath": "/data/movies/Mad Max Fury Road (2015)/Mad Max Fury Road (2015).mkv", "title": "Mad Max: Fury Road" }
  ]
}

Update channel

http
PUT /api/livetv/channels/:id
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "name": "Action & Thriller",
  "scheduleMode": "sequential"
}

Delete channel

http
DELETE /api/livetv/channels/:id
Authorization: Bearer <admin-token>

Stream playback

Watch a channel

http
GET /api/livetv/watch/:channelId
Authorization: Bearer <token>

Returns an HLS stream URL. For pre-warmed channels, this resolves immediately. For cold-start channels, the server starts the stream and long-polls until ready (up to 5 seconds).

Response: Redirects to live.m3u8.

HLS manifest

http
GET /api/livetv/watch/:channelId/live.m3u8
Authorization: Bearer <token>

HLS manifest with 6-second segments and a 3-segment sliding window.

Stream token auth

For external IPTV clients that can't use Bearer auth:

GET /api/livetv/watch/:channelId/live.m3u8?token=abc123def456

Warm channels

http
POST /api/livetv/warm
Authorization: Bearer <token>
Content-Type: application/json

{
  "channelIds": [1, 2, 3]
}

Pre-starts streams for the specified channels. Called by the web UI on page load for instant playback.

Proxy external streams

http
GET /api/livetv/watch/:channelId/relay.m3u8
Authorization: Bearer <token>

Proxies an external IPTV stream through the OmniLux server (for VPN egress or CORS bypass).

EPG

Get EPG data

http
GET /api/livetv/epg
Authorization: Bearer <token>

Query parameters:

ParameterTypeDescription
startstringISO 8601 start time
endstringISO 8601 end time
channelIdsstringComma-separated channel IDs

Response:

json
{
  "channels": [
    {
      "id": 1,
      "name": "Movies",
      "programs": [
        {
          "title": "Die Hard",
          "start": "2024-01-01T20:00:00Z",
          "end": "2024-01-01T22:11:00Z",
          "description": "An NYPD officer...",
          "posterUrl": "/artwork/movies/562/poster.jpg"
        }
      ]
    }
  ]
}

IPTV sources

List sources

http
GET /api/livetv/iptv-sources
Authorization: Bearer <admin-token>

Add source

http
POST /api/livetv/iptv-sources
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "name": "My IPTV Provider",
  "sourceUrl": "https://example.com/playlist.m3u",
  "epgUrl": "https://example.com/epg.xml"
}

DVR

List recordings

http
GET /api/livetv/recordings
Authorization: Bearer <token>

Record now

http
POST /api/livetv/recordings
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "channelId": 1,
  "duration": 3600
}

Schedule recording

http
POST /api/livetv/recordings
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "channelId": 1,
  "startAt": "2024-01-02T20:00:00Z",
  "duration": 7200,
  "name": "Movie Night Recording"
}

Delete recording

http
DELETE /api/livetv/recordings/:id
Authorization: Bearer <admin-token>

Export

M3U playlist

http
GET /api/livetv/m3u

Returns an M3U playlist of all enabled channels. For use with external IPTV clients. Requires stream token for authentication.

XMLTV EPG

http
GET /api/livetv/xmltv

Returns XMLTV-formatted EPG data for a 48-hour window.

HDHomeRun emulation

Device discovery

http
GET /discover.json

Response:

json
{
  "FriendlyName": "OmniLux",
  "Manufacturer": "OmniLux",
  "ModelNumber": "HDHR-OL",
  "FirmwareName": "omnilux",
  "TunerCount": 4,
  "DeviceID": "OMNILUX",
  "DeviceAuth": "omnilux",
  "BaseURL": "http://your-server-ip:4000",
  "LineupURL": "http://your-server-ip:4000/lineup.json"
}

Channel lineup

http
GET /lineup.json

Response:

json
[
  {
    "GuideNumber": "1",
    "GuideName": "Movies",
    "URL": "http://your-server-ip:4000/api/livetv/watch/1/live.m3u8?token=..."
  }
]

Settings

Get settings

http
GET /api/livetv/settings
Authorization: Bearer <admin-token>

Update settings

http
PUT /api/livetv/settings
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "hdhrEnabled": true,
  "hdhrTunerCount": 4,
  "epgRefreshIntervalHours": 12
}

Use OmniLux, run your own server, or build on the platform.