M3U or the Xtream API: which one should you actually use

The same provider will give you both, and they are not two formats for the same data. One is a photograph and the other is a conversation.

Your provider sent you an email with a username, a password and a host. The same email, or the same panel, will also give you a long URL that downloads a playlist file. Those are not 2 formats for the same information. They are not the same data twice, and picking the wrong one costs you features you will later assume the app does not have.

What each one actually is

An M3U export is a text file: channel names and URLs, generated at the moment you asked for it, with some attributes attached. It is a photograph of your line.

The Xtream API is one HTTP endpoint that answers questions. It is a conversation with your line, and the answers change as the line changes.

Concretely, the API is a single script that takes an action parameter rather than a set of resources:

player_api.php?username=U&password=P                        handshake
player_api.php?username=U&password=P&action=get_live_categories
player_api.php?username=U&password=P&action=get_live_streams
player_api.php?username=U&password=P&action=get_live_streams&category_id=12
player_api.php?username=U&password=P&action=get_vod_info&vod_id=884
player_api.php?username=U&password=P&action=get_series_info&series_id=41
player_api.php?username=U&password=P&action=get_short_epg&stream_id=1201

That is not a REST API and it does not pretend to be one. It is a panel endpoint, and the shape has consequences we will come back to.

The export lives on the same portal, on a different path. So an export and an API session are 2 views of 1 account rather than 2 products, which is why "which should I use" is a real question rather than a matter of which one your provider supports.

The three things only the API can express

Categories as data. An export carries a group-title attribute per entry, which is a string. The API has category objects with ids, and streams reference them. On a small playlist the distinction is academic. On a real one it is not: a production source in our own sample carried roughly 77,842 titles across about 444 categories, ranging from 8 entries to 3,655. A flat list of 77,842 things with a repeated string attached is a different data structure from a catalogue, and the browsing experience follows from which one you have.

The connection allowance. The API reports how many simultaneous connections your line permits. An export cannot say this, because a list of URLs has nowhere to put it.

This is not a decorative number. Multiview reads it and counts the budget before it assigns a tile, so asking for a 9 tile grid against a 2 connection line is refused in the picker rather than as 7 identical playback errors on the grid. Impossible without the API. Max connections covers the accounting.

The archive. A portal can report which channels keep a rewindable window and how deep it goes. That is the entire basis of catch-up, and again there is nowhere in an M3U line to express it.

How the client uses it matters: catch-up URLs are constructed from a channel, a start time and a duration rather than read per programme from anywhere. The portal tells us the window exists and we build the addresses ourselves. What catch-up and timeshift are covers the mechanism.

What a playlist still does better

Three things, and they are real rather than consolation.

It works when there is no portal. Plenty of sources are not Xtream panels at all. A community-maintained list of public streams, a local broadcaster's own file, a playlist you wrote yourself: none of these has an API, and an M3U is the universal format for them.

It is inspectable. Open it in a text editor and you see exactly what you have. When something is wrong, being able to read the input is worth a great deal, and an API response you cannot see is harder to reason about.

It survives. A file you downloaded still works while the panel is down for maintenance, at least until the URLs inside it expire.

One data point here is easy to over-read. In one measured corpus of 308 live entries, 303 ended in .m3u8, 5 had no extension, and none ended in .ts. That corpus is curated directory-style playlists rather than portal exports, so it says something about how public playlists are written and nothing about what your provider serves. We hold no measured corpus of portal live URLs.

The thing neither of them tells you

Neither an export nor the API tells a client what transport a channel actually uses. The live channel record in our catalogue has no container field, no transport field and no MIME field. There is nowhere for that information to live, because neither source provides it.

So transport can only ever be inferred from the URL string, and the client requests .ts for live channels with no branch and no setting. A portal is free to redirect that to an HLS manifest. Some do.

There is a Stream format control on an Xtream source, and it currently does nothing. It normalizes its value, saves it and reloads it, and when I went looking for the URL builder or playback code that reads it back, I could not find one, because there is none. It is on the list rather than being a switch you are failing to find. MPEG-TS or HLS covers what the two transports actually do differently and why the distinction matters less than it sounds.

What an export actually carries, measured

The case for an export is that the attributes on each line carry most of what a catalogue needs. That is true when they are present, and how often they are present varies.

Measured across 2,203 entries in our own corpus:

                   entries   tvg-id          group-title   tvg-chno
playlist_01.m3u        308   308  (100%)     283           0
playlist_02.m3u8     1,895   1,392 (73.5%)   1,895         1,355

Both files are curated directory-style playlists rather than panel exports, so read this as a demonstration of variance rather than as a prediction about your provider.

Three things in that table stand out.

Group titles are on every entry of both files. Grouping is the attribute providers get right, because it is the one that visibly breaks their own product if they omit it.

Channel numbers are absent from one file entirely and on 71 percent of the other. If you care about your channels appearing in broadcast order, that is a real difference between sources, and worth checking before you commit to one. Channel numbers in a playlist covers what the attribute does.

And 20 entries in the second file carry an identifier attribute that is present and empty. An empty identifier is not an identifier, and treating it as one would join those 20 channels to each other. That has to be handled explicitly rather than falling out of the code by luck.

Series and films: where the two diverge most

Live channels are where an export comes closest to adequate, because a live channel really is a name and a URL. On-demand content is where the gap opens.

A film in an export is one line: a title and a URL. A film through the API is an object with its own detail call, which is where the plot, the cast, the year, the rating and the container extension live.

That last one is not a nicety. The API reports the container extension for a film, and the client builds the URL from it:

live      portal/live/username/password/{stream_id}.ts
film      portal/movie/username/password/{vod_id}.{container_ext}

Live is a fixed .ts. Film is whatever the panel says it is, because films are stored files with real containers and a client that guessed would guess wrong.

Series are further along the same axis. An export flattens a series into a list of episode URLs with names that encode the season and episode if you are lucky. The API has a series object, a per-series detail call, and episodes grouped by season. A shows library that behaves like a shows library rather than a folder of files needs that structure to come from somewhere.

Combining providers, and where that work happens

Once you have more than one source, the obvious wish is one channel list rather than two, with the same channel from two providers appearing once and failing over between them.

That is supported, and the rule behind it explains the performance characteristics. The server stores the definition of an aggregated source and nothing else: resolution and materialisation always run on the device.

So the merging, the matching and the index all happen on the machine you are watching on. That keeps the service unaware of what is in your playlist, which is the same rule that keeps it from parsing your M3U in the first place. The cost is that the work is done once per device rather than once per account, which is part of why a first launch after adding a large source is slower than every launch after it.

Cross-source playback failover ships on top of that. A channel that exists in two sources can move to the other one when the first fails.

A third kind of portal

The M3U and panel API pair is not the whole world. A third family is Stalker and Ministra middleware, the ecosystem behind MAG set-top boxes, and it authenticates a device rather than an account. The credential is a MAC address rather than a username and password, so a provider's notion of how many devices you have is tied to that identity rather than to a login.

If your provider gave you a portal URL and a MAC address, that is what you have. It is neither option compared here.

Which to choose

If your provider gave you a host, a username and a password, use those. Add an Xtream source. You get the catalogue with real categories, the connection count that makes multiview honest, and catch-up where the provider offers it. The export gives you none of those and no compensating advantage.

If you have a playlist and nothing else, use the playlist. That is what it is for, and most of the app works identically.

If you have both and you are debugging something, the export is a useful diagnostic even when the API is what you run on. It is the one artefact you can read.

The one thing not to do is add both as separate sources and expect the app to work out that they are the same line. They are 2 sources, each consuming connections, and the connection accounting will be right about a situation you did not intend.

For getting either onto a console, adding an M3U playlist for Xbox and signing in with Xtream Codes for Xbox cover the same decision from the setup side. For what the attributes inside an export mean, M3U+ versus plain M3U.

What this article measured22 claims, each with the evidence behind it
ClaimEvidenceCounted
The panel API is one endpoint taking an action parameter, not a set of resources. Fifteen actions cover the whole catalogue: categories and streams for live, video and series, plus per-item info, a short guide and a data table.n = 15Aug 31, 2026
Stream URLs are constructed by the client from a template rather than read from the API response: live uses a .ts suffix and video on demand uses a container extension the API reports.n = 2Aug 31, 2026
The M3U export is served by the same portal on a different path, so an export and an API session are two views of one account rather than two products.n = 1Aug 31, 2026
The Stream format control offered on an Xtream source normalizes, saves and reloads its value and is read by no URL builder and no playback code.n = 1Aug 23, 2026
The live channel record carries no container, transport or MIME field, so transport can only ever be inferred from the URL rather than read from the catalogue.n = 1Aug 23, 2026
The connection allowance a portal reports is used rather than merely displayed: multiview counts it before assigning a tile and stops offering channels from an exhausted source.n = 1Aug 15, 2026
Catch-up URLs are built by the client from a channel, a start time and a duration, rather than being read per programme out of the guide.n = 1Aug 23, 2026
A production source in our own sample carried roughly 77,842 distinct titles across about 444 provider categories, with single categories ranging from 8 to 3,655 entries.n = 1Aug 31, 2026
Measured over 2,203 entries in our own playlist corpus: identifier coverage was 100 percent in one file and 73.5 percent in the other, channel numbers were absent from one file entirely and present on 1,355 entries of the other, and group titles were on every entry of both.n = 2203Aug 31, 2026
Combining several providers into one channel list is a client-side operation by design: the server stores the definition of an aggregated source and nothing else, and resolution and materialisation always run on the device.n = 1Aug 31, 2026
A third portal family is supported alongside playlists and the panel API: Stalker and Ministra middleware, which authenticates a device rather than an account.n = 1Aug 31, 2026
Thirteen kinds of account state sync between devices, and the playlist is not one of them: what travels is the source definition and your decisions about it.n = 13Sep 1, 2026
Per-source preferences are their own synced family, distinct from the source itself, which is how a setting made in one place reaches a device that offers no editor for it.n = 1Sep 1, 2026
Two override families exist and the distinction matters: presentation overrides are scoped to a source, while guide corrections are profile-level and source-free.n = 2Sep 1, 2026
An account holds at most 10 uploaded playlists, checked when an upload is initialised rather than when it completes.n = 1Sep 1, 2026
Whichever route you choose, the server does not parse it: a file import is stored encrypted, a URL import records metadata, and parsing happens on the device that will play it.n = 1Sep 1, 2026
A pasted address is accepted up to 2048 characters, comfortably covering the token-bearing URLs a portal issues.n = 1Sep 1, 2026
The connection allowance the API reports is acted on rather than shown: a layout counts it before assigning a tile and stops offering channels from an exhausted source.n = 1Aug 15, 2026
Failover between sources costs one extra connection during the overlap, so the planner refuses whenever that connection is not provably spare and falls back to an ordinary restart.n = 1Sep 1, 2026
Guide data is configured separately from the source in either case, with global mode accepting up to 15 URLs and per-country mode warning above 5 countries.n = 2Sep 1, 2026
Guide files are downloaded by your devices rather than by our servers, which is stated on the settings screen rather than left as an implementation detail.n = 1Sep 1, 2026
In one measured playlist corpus, 303 of 308 live paths ended in .m3u8, 5 had no extension, and none ended in .ts. That corpus is curated directory-style files rather than portal exports and says nothing about what a portal serves.n = 308Aug 23, 2026