A fully Xtream Codes-compatible mock API for testing the m3u-tv Flutter app (and any other Xtream-compatible IPTV client) without needing a real IPTV subscription.
Use it to:
- Test app features end-to-end with real API calls
- Provide store-review credentials to Apple TestFlight and Google Play reviewers
- Reproduce edge cases with predictable, controlled data
https://api-tester-fcn5.onrender.com
The free Render tier sleeps after 15 minutes of inactivity. The first request after sleep takes ~30-50s. Upgrade to a paid plan for always-on behaviour, or user UptimeRobot to monitor the
/healthendpoint of the public URL (the default/free 5min interval will work fine to keep the service warm).
| Username | Password | Purpose |
|---|---|---|
testuser |
testpass |
Apple / Google reviewer account |
demo |
demo |
General QA / development testing |
These credentials are intentionally public — this API serves mock data only and contains no real content or user information.
Use these settings when adding a server in the m3u-tv app (or any Xtream player):
| Field | Value |
|---|---|
| Server | https://api-tester-fcn5.onrender.com |
| Username | testuser |
| Password | testpass |
| Type | Count | Source |
|---|---|---|
| Live TV | 11 | 5 rotating HLS test streams (Apple, Mux, THEOplayer) |
| Movies | 15 | 11 Blender open movies (CC BY) and 4 public-domain classics, each playing its own film |
| Series | 3 | Blender Studio Shorts, Caminandes, Blender Open Movies |
Movies and series are listed newest first, and added follows the same order, so a "Recently Added" sort agrees with the default one.
Categories:
- Live: News, Sports, Entertainment, Movies, Kids, Documentary
- Movies: Animation, Classic Cinema, Action, Comedy, Sci-Fi, Horror, Short Films
- Series: Animation, Comedy, Collections
EPG: Generated from a looping schedule per channel, with variable-length programmes, so any date is populated. get_epg_batch returns a whole UTC day per call (date, default today) like m3u-editor. With details=1, the film channels (Open Movie Channel, Classic Cinema, Kids Zone) include artwork, category, year and season/episode numbers.
Detail pages: get_vod_info and get_series_info include a cast_list (with photos and characters) and related titles from the library, and tapping a cast member opens their filmography (get_actor_filmography).
Viewers and progress: Two fixed viewers (Demo, Kids). Progress is kept in memory, and each viewer starts with a few seeded entries so Continue Watching is populated on a fresh install. Restarting the server resets it.
Artwork: Posters (780x1170), backdrops (1920x1080), and title logos (clearlogo) are self-hosted under /assets/art/. See Artwork.
Live stream note: Live channels cycle across 5 distinct HLS test streams (Apple fMP4, Mux pts_shift, Mux x36xhzz, THEOplayer BBB, THEOplayer Elephants Dream) and use procedurally generated (not downloaded) channel logos - see app/icons.py.
VOD/series note: Every movie and episode streams its own film. Big Buck Bunny and Elephants Dream come from THEOplayer's official HLS mirrors, everything else as direct MP4 from Internet Archive. download.blender.org is behind a Cloudflare JS challenge that blocks plain HTTP clients, so it is not used.
The art under app/static/art/ is built once by tools/build_art.py and committed. The server never hotlinks a third party: hotlinking Wikimedia Commons from the app failed intermittently, because Commons answers bot-like clients with 429 Your bot is making too many requests, which left posters blank until a later reload.
The script pulls official posters from Commons, takes backdrops and episode stills from the films themselves (Commons renders a still from any second of a hosted video), composes posters for titles without one, and generates title logos in Plus Jakarta Sans (OFL, tools/fonts/).
.venv/bin/python tools/build_art.py # only builds what is missing
.venv/bin/python tools/build_art.py --force # rebuild everythingTo add a title, add it to FILMS in app/data.py and to TITLES in the build script, then run it.
All films and artwork are released under Creative Commons Attribution licenses or are in the public domain.
- Blender Foundation / Blender Studio (studio.blender.org), CC BY 3.0 / 4.0: Elephants Dream, Big Buck Bunny, Sintel, Tears of Steel, Cosmos Laundromat, Glass Half, Hero, Spring, Coffee Run, Sprite Fright, Charge, and Caminandes (Pablo Vazquez and the Blender Foundation).
- Public domain (United States): Nosferatu (1922), The General (1926), His Girl Friday (1940), Night of the Living Dead (1968).
- Posters, stills and logos via Wikimedia Commons; composed posters and title logos are derived from those films.
- Cast photos: public-domain portraits and film stills of the classic-film actors from Wikimedia Commons. The Blender films credit their characters, cropped from the films and their posters, rather than photos of the voice actors.
| Action | Supported |
|---|---|
panel / get_user_info / get_server_info |
✅ |
get_live_categories |
✅ |
get_vod_categories |
✅ |
get_series_categories |
✅ |
get_live_streams |
✅ (with category_id filter) |
get_vod_streams |
✅ (with category_id filter) |
get_series |
✅ (with category_id filter) |
get_series_info |
✅ |
get_vod_info |
✅ |
get_short_epg |
✅ |
get_epg_batch |
✅ (whole day per date, details=1 extras) |
get_viewers |
✅ (fixed demo viewers) |
get_actor_filmography |
✅ (cast members of this library) |
get_progress / get_series_progress / get_recently_watched / update_progress |
✅ (in memory, seeded) |
get_simple_data_table |
✅ |
m3u_plus |
✅ (redirects to /get.php) |
| DVR / recording | — (out of scope) |
Stream URL patterns (redirect to real media):
/live/{username}/{password}/{stream_id}.m3u8
/movie/{username}/{password}/{stream_id}.{mp4|m3u8}
/series/{username}/{password}/{episode_id}.m3u8
/get.php?username=…&password=…&type=m3u_plus
# Install dependencies
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# Start the server
uvicorn app.main:app --reload
# API is now at http://localhost:8000
# Interactive docs at http://localhost:8000/docspytest tests/ -v- Create a Render account (free).
- Click New → Web Service and connect this GitHub repo.
- Render detects
render.yamlautomatically — just click Deploy. - Once deployed, copy the Deploy Hook URL from
Settings → Deploy Hookin the Render dashboard. - Add it as a GitHub repository secret named
RENDER_DEPLOY_HOOK_URL:
GitHub repo → Settings → Secrets and variables → Actions → New secret.
After that, every push to main runs tests and — if they pass — triggers a Render deploy automatically.
| Variable | Default | Purpose |
|---|---|---|
BASE_URL |
Auto-detected from RENDER_EXTERNAL_URL |
Public base URL of this server |
SERVER_TIMEZONE |
UTC |
Timezone in server_info |
app/
├── config.py - credentials & server settings
├── data.py - mock live / VOD / series catalogue
├── epg.py - dynamic EPG generator (looping per-channel schedules)
├── progress.py - demo viewers and in-memory watch progress
├── icons.py - generated live-channel logos
├── main.py - FastAPI app, all routes
└── static/art/ - built posters, backdrops and logos
tools/
└── build_art.py - builds static/art from Wikimedia Commons
tests/
└── test_api.py - full API surface coverage
All content is static / in-memory — no database required.
Edit app/data.py:
- Live channels — add entries to
LIVE_STREAMS. Setdirect_sourceto any public HLS URL. - Movies - add an entry to
FILMS(and a stream id to_FILM_IDS), then build its art (see Artwork). - Series - add a
_series_payload(...)to_SERIES_DEFS. - EPG schedules — extend
_EPG_SCHEDULESin app/epg.py.
m3u-editor/ — Laravel backend (source of truth for the Xtream API spec)
m3u-proxy/ — Python streaming proxy
m3u-tv/ — Flutter TV app (this API's primary consumer)
m3u-api-tester/ — This repo: mock API for testing m3u-tv
m3u-editor-docs-v2/— Documentation site