All posts
7 min readEPGMaster.ai

One login. Your player gets the cleaned playlist and the EPG. Industry first.

Open any IPTV player’s setup screen — TiviMate, IPTV Smarters Pro, OTT Navigator — and you’ll see the same two options for adding a playlist:

  1. M3U + EPG URLs. You paste two URLs (one for the channel list, one for the programme guide). The player polls them on its own schedule.
  2. Xtream Codes.You enter a server URL, a username, and a password. The player talks to the server’s API directly — channels, EPG, VOD, series, everything in one connection.

Every EPG service we’ve ever seen makes you use option 1. Two URLs, paste them in, hope you remember to update them when something changes. We thought option 2 was a better idea.

So we built it. EPGMaster.ai is itself an Xtream Codes server. Point any Xtream-compatible player at https://epgmaster.ai, give it your email and a device password, and you’re live. One credential. Cleaned playlist, matched EPG, VOD library, all of it.

As far as we can tell, no other consumer EPG service does this.

Why this is a big deal in practice

The setup difference is small in description but huge in lived experience.

Old way.Sign up for an EPG service. Download an M3U file (or copy a URL). Paste it into your player. Get an XMLTV URL from somewhere. Paste that into the same player as the EPG source. Cross your fingers that the player parses both correctly. When you change anything — rename a channel, hide a group — remember to push the update to the EPG service, and remember that your player needs to refresh.

New way. In your player, choose “Xtream Codes.” Type https://epgmaster.ai. Type your email. Type the device password from your EPGMaster settings. Done. Channels, EPG, movies, series — one stream of data. When you edit your playlist in our browser editor, your player picks up the changes on next refresh. No re-uploading. No URL juggling.

What we built, in technical detail

The Xtream Codes protocol isn’t complicated, but the compatibility surface is where every implementation lives or dies. The endpoints that matter:

  • /player_api.php— auth, live channel list, categories, short EPG, VOD, series. Dispatched by an ?action= query param.
  • /get.php— the M3U file. Standard Xtream entry point.
  • /xmltv.php— the XMLTV guide.

We expose all three at the bare epgmaster.ai domain via root rewrites in Next.js, so when a player constructs a URL like https://epgmaster.ai/player_api.php?username=...&password=...&action=get_live_streams, we handle it.

Per-playlist device passwords, not your account password

Xtream credentials get sent in URL query strings. They leak through Vercel logs, CDN logs, player crash dumps, and screenshots from confused users. Reusing the EPGMaster account password would collapse a leak-prone read-only credential into the credential that controls account deletion.

So every Xtream connection uses a device password— a 16-character base32 secret, bcrypt-hashed at rest, displayed exactly once when you generate it. You regenerate from settings; old credential dies, new one takes effect immediately, no knock-on to your login.

The “never return HTTP errors” invariant

This was the gnarliest part of building it. Xtream players misinterpret HTTP 4xx and 5xx as “the playlist is permanently broken.” Get a 401 from player_api.php and TiviMate will disable your playlist on the spot.

So every response from our Xtream surface is HTTP 200, even on auth failure. Bad credentials return { user_info: { auth: 0 } } at HTTP 200. Players understand that shape; they prompt the user to re-enter credentials instead of nuking the playlist.

This is undocumented in the official Xtream spec. We learned it the hard way, then wrote it into a code-level invariant.

Stream URLs that redirect to your provider

When you press play on a channel, your player hits a URL like /live/<username>/<password>/<stream_id>.ts. We respond with a 302to the upstream provider’s real stream URL. The video bytes never touch our infrastructure. We’re a control plane — signalling, auth, metadata, the EPG — not a streaming proxy.

That redirect is what lets us serve cleaned, edited playlists on top of someone else’s underlying IPTV service without becoming a bandwidth sink.

Per-player edge cases

Xtream “compatibility” turns out to mean “every player parses things slightly differently.” A few we hit:

  • IPTV Smarters Pro sends POST instead of GET on player_api.php. We accept both, ignore the body, read credentials from the query string per spec.
  • IPTV Smarters Pro rejects exp_date: null in the auth response. The Xtream convention is exp_date: '0'for “never expires.” We send the string.
  • IPTV Smarters constructs stream URLs with 31-bit truncated IDs. We map our internal UUIDs to a 31-bit numeric space and back, transparently.
  • Older TiviMate builds also send POST. Same handler.

Each of these was a debugging session where the player’s only error message was “authentication failed” with zero diagnostic information. Most services would hit one of these and conclude “Xtream is too hard, let’s just hand out URLs.”

Why nobody else does this

Three reasons, in increasing order of severity.

One: it’s engineering work that’s invisible from the marketing page.“We accept M3U URLs” and “we are an Xtream Codes server” both look like one bullet point on a feature grid. The second one represents months more work. EPG services optimise for landing-page bullets.

Two: per-user device password infrastructure is real product surface. You need a settings page for credential management. Regenerate flow with cache invalidation. Per-credential rate limits. Bcrypt verification with caching (TiviMate hammers player_api.php dozens of times per session; uncached bcrypt would burn your CPU budget). None of this exists for free.

Three: the protocol’s edge cases are field-discovered.The spec doesn’t mention the never-return-4xx invariant. Doesn’t mention exp_date: '0'. Doesn’t mention POST handlers. Doesn’t mention Smarters’ 31-bit truncation. Every one of these we found by pointing a real player at our server, watching it fail, and reading enough Wireshark dumps to figure out what it expected.

What this changes for you, in one sentence

Your IPTV player connects to one place: us. Your provider stays your provider; we sit in front of them, clean up the playlist, match the EPG, serve the VOD library, and speak Xtream Codes back to whatever player you’re using. One login. Zero URL juggling.

That’s the moat. Start your free 14-day trial and pair your TiviMate or Smarters in 30 seconds.

Try it free for 14 days

14 days of full access. No credit card required. Cancel anytime.

Start Free Trial