Keyless, self-hostable movie & TV metadata, artwork, scores, credits and where-to-watch API — runs on Cloudflare Pages Functions, Vercel, Railway, Render or any Docker host. Catalogues, search, full poster/backdrop/logo sets, episode stills, critic & audience ratings, cast & crew, person bios, similar titles, streaming availability and rich facts from Wikidata, Wikipedia, Rotten Tomatoes, Metacritic, JustWatch, TVmaze and AniList.
https://api.streamx.qzz.io
No API keys. No sign-up. No secrets. Everything is read from public endpoints and cached at the edge. Version 1.3.0.
Use it hosted — or fork it and run your own. → Self-hosting & forks · Using an AI agent? → For AI agents
Made by @imzyrix · part of @zyrixdevs
- Why StreamX API
- Feature overview
- Data sources
- Architecture & project layout
- Quick start (local)
- Deploy
- For AI agents
- Self-hosting & forks
- Configuration
- API reference
- The image system
- The enrichment layers
- Response field reference
- Caching, headers & errors
- Usage recipes
- Limitations
- Comparison with alternatives
- Gap analysis — what StreamX is missing
- Roadmap to #1
- Extending the API
- Attribution & licensing
Most movie/TV APIs make you register, hand over an email, manage an API key, throttle your requests, and pay once you go commercial. StreamX API takes the opposite approach:
- Zero credentials — clone, deploy, call. Nothing to configure.
- One endpoint, many sources — a single
/metacall returns the title, cast, episodes, artwork, budget/box office, Wikipedia plot and external IDs. A single/scorescall returns IMDb, Rotten Tomatoes and Metacritic side by side. - Self-hosted and private — it runs in your Cloudflare account; no third-party gateway sees your traffic.
- Edge-cached and free — JSON is cached for hours/days, images for 30 days, so upstream is hit rarely and the free tier is plenty.
StreamX API is the data layer behind the StreamX web app and is designed to be embedded in anything: web, mobile, TV, bots or CLIs.
- Top movies and series, with genre filters and
skippagination. - Title search across movies and series.
- IMDb search with high-resolution posters, year, type and top cast.
- Anime search via AniList with scores, genres and artwork.
- Full metadata: name, description, cast, director, writer, genres, year, release, runtime, IMDb rating, awards, country, trailers, and episode lists for series.
- Wikidata: budget, box office, runtime, MPA certification, official website, production companies, countries, languages, directors, composers, series, and external IDs (TMDb, TVDB, Rotten Tomatoes, Metacritic).
- Wikipedia synopsis.
?enrich=0fast path to skip the enrichment network calls.
- IMDb rating (via Cinemeta) with the canonical IMDb URL.
- Rotten Tomatoes Tomatometer and Popcornmeter: score, average rating, review count, sentiment and certified-fresh flag.
- Metacritic Metascore, review count and content rating.
- All returned together, with per-source availability flags.
- Cast & crew with roles, photos and Wikidata/IMDb ids (
/credits). - Person bios with image, birth/death, social ids and a Wikipedia summary (
/person). - Similar titles — sequels and other works by the same director (
/similar). - Trending titles (
/trending).
- JustWatch streaming availability by country: subscription, free, rent and buy.
- Per-provider deep links and a canonical JustWatch URL.
- Poster, backdrop and logo, each in four sizes (
small,medium,large,original). - Episode stills at every width bucket (
w92…original) plus friendly aliases. - One manifest endpoint returning the whole artwork set, proxied or direct.
- TVmaze show info: network, country, status, schedule dates, rating, genres, official site, imagery and external IDs.
- AniList anime search with average score, popularity, format and cover art.
- Keyless, CORS-open, edge-cached, self-hostable, fail-soft, no build step.
| Service | Used for | Auth | Notes |
|---|---|---|---|
Cinemeta (v3-cinemeta.strem.io) |
Catalogues, search, titles, cast, ratings, episodes | none | Community Stremio metadata addon |
MetaHub (images.metahub.space) |
Posters, backdrops, logos | none | One artwork per kind per title |
MetaHub episodes (episodes.metahub.space) |
Episode stills | none | Resolves to image.tmdb.org |
Wikidata (query.wikidata.org) |
Budget, box office, companies, external IDs | none | SPARQL |
Wikipedia (*.wikipedia.org/api/rest_v1) |
Synopsis | none | REST summary |
IMDb suggestion (v2.sg.media-imdb.com) |
Search suggestions, Amazon posters, top cast | none | Public suggestion endpoint |
Rotten Tomatoes (rottentomatoes.com) |
Tomatometer & Popcornmeter | none | Public page data |
Metacritic (metacritic.com) |
Metascore | none | JSON-LD on the page |
JustWatch (apis.justwatch.com) |
Streaming availability | none | Public GraphQL |
TVmaze (api.tvmaze.com) |
TV show info | none | Official keyless API |
AniList (graphql.anilist.co) |
Anime search & scores | none | Public GraphQL |
The original key-based TMDb implementation is preserved (unrouted) under
_preserved/tmdb-functions/and is not deployed.
Cloudflare Pages Functions with file-based routing. functions/ is the API,
public/ is the static site, and there is no build step.
api/
├── functions/
│ ├── _lib/
│ │ ├── upstream.js # Cinemeta/MetaHub fetch + edge cache + json()/fail()/CORS
│ │ ├── images.js # artwork kinds/sizes, still sizes, manifest & URL builders
│ │ ├── enrich.js # Wikidata SPARQL, Wikipedia summary, IMDb suggestion
│ │ ├── scrape.js # cached fetch helpers, browser UA, HTML stripping
│ │ ├── people.js # cast/crew, person bio, similar titles (Wikidata)
│ │ ├── scores.js # Rotten Tomatoes + Metacritic parsing
│ │ ├── watch.js # JustWatch offers (GraphQL)
│ │ └── tvmaze.js # TVmaze show lookup + AniList search
│ ├── _middleware.js # CORS, OPTIONS, method guard, error handling
│ ├── health.js # /health
│ ├── search.js # /search
│ ├── imdb/search.js # /imdb/search
│ ├── anime/search.js # /anime/search
│ ├── catalog/[type]/[catalog].js # /catalog/:type/:catalog
│ ├── meta/[type]/[id].js # /meta/:type/:id
│ ├── scores/[type]/[id].js # /scores/:type/:id
│ ├── credits/[type]/[id].js # /credits/:type/:id
│ ├── person/[id].js # /person/:id
│ ├── similar/[type]/[id].js # /similar/:type/:id
│ ├── trending/[type].js # /trending/:type
│ ├── streaming/[type]/[id].js # /streaming/:type/:id
│ ├── tv/[id].js # /tv/:id
│ ├── images/[type]/[id].js # /images/:type/:id
│ ├── img/[[path]].js # /img/... artwork + stills proxy
│ └── cinemeta/[[path]].js # /cinemeta/... raw passthrough
├── server/ # portable Node server (Docker / Railway / Render / Fly)
│ ├── app.js # URL → handler dispatcher, shared by every runtime
│ └── index.js # plain node:http server
├── api/index.js # Vercel serverless entry (reuses server/app.js)
├── skill/ # AI agent skill (SKILL.md + reference.md)
├── mcp/ # zero-dependency MCP server exposing the API as tools
├── docs/SELF-HOST.md # fork & self-host guide
├── llms.txt · llms-full.txt # AI discovery docs
├── public/ # landing / quick reference page
├── _preserved/tmdb-functions/ # old key-based implementation (not deployed)
├── Dockerfile · vercel.json · railway.json · render.yaml · fly.toml · wrangler.toml
├── LICENSE · LICENSE-DOCS # MIT (code) · CC BY 4.0 (docs)
└── package.json
The same route handlers power Cloudflare Pages Functions and the portable Node
server — server/app.js maps every URL to the matching functions/** handler.
Underscore-prefixed files/folders (_lib, _middleware.js) are not routed.
cd api
npm install
npm run dev # http://localhost:8788curl http://localhost:8788/health
curl http://localhost:8788/catalog/movie/top
curl http://localhost:8788/meta/movie/tt0133093
curl http://localhost:8788/scores/movie/tt0133093Under
wrangler pages devthe edge cache reportsMISSevery time; that is expected locally.
One-click buttons (also at the top of this README):
Wrangler CLI
cd api
npm install
npx wrangler login
npx wrangler pages deployWrangler creates the project and prints https://<project>.pages.dev.
Git integration — Cloudflare dashboard → Workers & Pages → Create → Pages →
Connect to Git. Root directory /, build command (empty), build output public.
No environment variables required.
Direct upload — npx wrangler pages deploy public.
Custom domain — Pages project → Custom domains. Use a proxied CNAME to
<project>.pages.dev; stray A records cause 522/523.
Cloudflare is the only target with the full edge cache. It is the recommended host.
vercel.json rewrites all traffic to api/index.js, which reuses the same
server/app.js dispatcher. Import the repo, no build command needed, optional
CACHE_TTL env var.
railway.json runs node server/index.js. Deploy from the repo; Railway uses Nixpacks
and needs no configuration.
- Render: Blueprint from
render.yaml(health check/health). - Fly.io:
fly launch --no-deploy(reusesfly.toml) thenfly deploy. - Any Docker host:
docker build -t streamx-api . && docker run -d -p 8788:8788 streamx-api
On non-Cloudflare hosts the caches API is absent, so the edge cache no-ops and each
request hits upstreams live — ideal to put a CDN/reverse-proxy cache in front.
StreamX ships first-class, downloadable agent assets so Claude, Codex, Cursor, or any other agent can use the API without hand-holding:
| Asset | What it is |
|---|---|
skill/SKILL.md |
A drop-in AgentSkill (front-matter name/description + full instructions). Clone the repo or copy this file into your agent's skills directory. |
skill/reference.md |
Complete endpoint/param/field reference for agents. |
llms.txt · llms-full.txt |
The llms.txt discovery standard — point any LLM tooling here. |
AGENTS.md |
Repo conventions for coding agents working on the API. |
mcp/server.mjs |
A zero-dependency MCP server exposing the API as tools over stdio. |
Use the hosted API from an agent — just give it the base URL:
"Use the keyless StreamX API at
https://api.streamx.qzz.io. Search with/search?q=…, then call/meta,/scores,/credits,/streaming,/similarby IMDb id. Readskill/SKILL.mdfor the full reference."
Or run the MCP server:
STREAMX_API_BASE=https://api.streamx.qzz.io node mcp/server.mjsTools exposed: streamx_search, streamx_meta, streamx_scores,
streamx_streaming, streamx_credits, streamx_similar, streamx_person,
streamx_trending, streamx_images, streamx_catalog.
Prefer your own URL? Fork the repo and deploy anywhere (see Deploy). The code is completely runtime-portable and stays keyless:
- Same handlers everywhere —
functions/**run on Cloudflare and drive the Node server (server/), Vercel (api/index.js) and Docker. - Make it yours — rename the
serviceinfunctions/health.js, rebrandpublic/index.html, and setCACHE_TTL. No rebuild needed. - Point apps/agents at your URL — set
API_BASEin the web app'sWeb/config.js, andSTREAMX_API_BASEfor the MCP server. - Swap data sources — every upstream is one file in
functions/_lib/; add a keyless source and wire it into a route (seeAGENTS.md).
Full walkthrough, fork checklist and per-platform steps: docs/SELF-HOST.md.
Everything is optional:
| Variable | Default | Description |
|---|---|---|
CACHE_TTL |
86400 |
Default JSON edge-cache TTL, in seconds |
Set values in wrangler.toml under [vars], or locally in .dev.vars
(see .dev.vars.example). No secrets are required.
Base URL: https://api.streamx.qzz.io (or your own *.pages.dev).
All routes accept GET and HEAD; OPTIONS returns 204. Responses are JSON unless
noted. :type is movie or series (aliases tv, show, tvshow, … normalise to
series).
| Route | Description |
|---|---|
GET /catalog/:type/:catalog?genre=&skip=&search= |
Catalogue listing (:catalog defaults to top). |
GET /search?q=<term>&type=movie|series&skip= |
Title search. |
GET /imdb/search?q=<term> |
IMDb suggestions (posters, year, top cast). |
GET /anime/search?q=<term> |
AniList anime search. |
/catalog and /search add query and count to the upstream payload.
curl "https://api.streamx.qzz.io/catalog/movie/top?genre=Action&skip=0"
curl "https://api.streamx.qzz.io/catalog/series/top?genre=Drama"
curl "https://api.streamx.qzz.io/search?q=dune&type=movie"
curl "https://api.streamx.qzz.io/imdb/search?q=dune"
curl "https://api.streamx.qzz.io/anime/search?q=frieren"| Route | Description |
|---|---|
GET /meta/movie/<imdb_id>?enrich=0 |
Movie details + images + enrichment. |
GET /meta/series/<imdb_id>?enrich=0 |
Series details + episodes + enrichment. |
curl "https://api.streamx.qzz.io/meta/movie/tt0133093"
curl "https://api.streamx.qzz.io/meta/series/tt0944947"
curl "https://api.streamx.qzz.io/meta/movie/tt0133093?enrich=0"| Route | Description |
|---|---|
GET /scores/:type/:id |
IMDb + Rotten Tomatoes + Metacritic in one response. |
curl "https://api.streamx.qzz.io/scores/movie/tt0133093"
curl "https://api.streamx.qzz.io/scores/series/tt0944947"{
"ok": true,
"type": "movie",
"id": "tt0133093",
"title": "The Matrix",
"year": 1999,
"imdb": { "rating": 8.7, "url": "https://www.imdb.com/title/tt0133093/" },
"rottenTomatoes": {
"url": "https://www.rottentomatoes.com/m/matrix",
"critics": { "title": "Tomatometer", "score": 83, "averageRating": 7.9, "reviewCount": 209, "sentiment": "POSITIVE", "certified": true },
"audience": { "title": "Popcornmeter", "score": 85, "averageRating": 3.6, "reviewCount": 1307885, "sentiment": "POSITIVE" }
},
"metacritic": {
"url": "https://www.metacritic.com/movie/the-matrix/",
"critics": { "title": "Metascore", "score": 73, "reviewCount": 36, "bestRating": 100 },
"contentRating": "R"
},
"sources": { "imdb": true, "rottenTomatoes": true, "metacritic": true },
"generatedAt": "2026-01-01T00:00:00.000Z"
}| Route | Description |
|---|---|
GET /credits/:type/:id |
Cast & crew for a title (Wikidata). |
GET /person/:id |
Person bio by IMDb nm… or Wikidata Q… id. |
GET /similar/:type/:id |
Sequels / same-director titles. |
curl "https://api.streamx.qzz.io/credits/movie/tt0133093"
curl "https://api.streamx.qzz.io/person/nm0000206"
curl "https://api.streamx.qzz.io/similar/movie/tt0133093"/credits returns cast[], crew[] and directors[]; each person carries id
(IMDb nm… or Wikidata Q…), name, role (cast | director | writer |
composer | producer), image and description:
{
"ok": true,
"id": "tt0133093",
"type": "movie",
"cast": [
{ "id": "nm0000206", "wikidataId": "Q43416", "name": "Keanu Reeves", "role": "cast", "image": "https://commons.wikimedia.org/...", "description": "Canadian actor" }
],
"crew": [ { "id": "nm0905154", "wikidataId": "Q26720231", "name": "Lana Wachowski", "role": "director", "image": null } ],
"directors": [ { "name": "Lana Wachowski", "role": "director" } ],
"source": "wikidata"
}/person returns name, description, image, born, died, externalIds
(imdb, tmdb, twitter, instagram) and a Wikipedia wiki summary.
/similar returns the same metas[] shape as a catalogue.
| Route | Description |
|---|---|
GET /trending/:type?limit= |
Popularity-ordered titles (Cinemeta top catalogue). |
curl "https://api.streamx.qzz.io/trending/movie?limit=20"| Route | Description |
|---|---|
GET /streaming/:type/:id?country=US |
Streaming/rent/buy providers via JustWatch. |
curl "https://api.streamx.qzz.io/streaming/movie/tt0133093?country=US"
curl "https://api.streamx.qzz.io/streaming/series/tt0944947?country=GB"providers[] entries have name, types (subscription, free, rent, buy),
quality (SD, HD, _4K) and a webUrl deep link. A justWatchUrl is included.
| Route | Description |
|---|---|
GET /tv/:id |
TVmaze show details by IMDb id (tt…) or TVmaze id. |
GET /anime/search?q=<term> |
AniList anime search. |
curl "https://api.streamx.qzz.io/tv/tt0944947"
curl "https://api.streamx.qzz.io/anime/search?q=attack%20on%20titan"| Route | Description |
|---|---|
GET /images/:type/:id?direct=1 |
Full artwork manifest (all kinds × sizes). |
GET /img/poster/<size>/<imdb_id>/img |
Poster. |
GET /img/background/<size>/<imdb_id>/img |
Backdrop. |
GET /img/logo/<size>/<imdb_id>/img |
Logo. |
GET /img/still/<imdb_id>/<season>/<episode>/<size> |
Episode still. |
curl "https://api.streamx.qzz.io/images/movie/tt0133093"
curl "https://api.streamx.qzz.io/img/poster/medium/tt0133093/img"
curl "https://api.streamx.qzz.io/img/still/tt0944947/1/1/w780"| Route | Description |
|---|---|
GET /cinemeta/<path> |
Raw Cinemeta response, edge-cached. |
curl "https://api.streamx.qzz.io/cinemeta/catalog/movie/top.json"| Route | Description |
|---|---|
GET /health |
Status, version, upstreams, endpoints and valid image sizes. |
{
"ok": true,
"service": "streamx-api",
"version": "1.3.0",
"requiresApiKey": false,
"upstreams": ["cinemeta","metahub","wikidata","wikipedia","imdb-suggestion","rottentomatoes","metacritic","justwatch","tvmaze","anilist"],
"imageKinds": ["poster","background","logo"],
"imageSizes": ["small","medium","large","original"],
"stillSizes": ["w92","w154","w185","w300","w342","w500","w780","original"]
}Artwork comes from MetaHub, which serves one artwork per kind per title, keyed by the IMDb id.
- Kinds —
poster,background(backdrop),logo. - Sizes —
small,medium,large,original. - Episode still sizes —
w92,w154,w185,w300,w342,w500,w780,original, with aliasessmall→w185,medium→w500,large→w780,xlarge→original, and unknown values falling back tow780.
Proxied vs direct — by default images are served through /img/... (uniform CORS,
edge-cached). Add ?direct=1 on the manifest to receive raw
https://images.metahub.space/... URLs instead.
All enrichment runs in parallel, is edge-cached (a week), and fails soft — a missing source simply omits its fields.
| Output field | Property |
|---|---|
budget |
P2130 |
boxOffice |
P2142 |
runtimeMinutes |
P2047 |
certification |
P1657 |
officialWebsite |
P856 |
countries |
P495 |
languages |
P364 |
productionCompanies |
P272 |
genres |
P136 |
directors |
P57 |
composers |
P86 |
partOfSeries |
P179 |
externalIds.rottenTomatoes |
P1258 |
externalIds.metacritic |
P1712 |
externalIds.tmdb |
P4947 / P4983 |
Resolved by the Wikidata RT/MC id when present, otherwise by searching the site, then
read from the public page (RT media-scorecard-json; Metacritic JSON-LD).
IMDb's public GraphQL endpoint returns 403; only the keyless suggestion endpoint is
used (search results + top cast). The IMDb rating on /scores comes from Cinemeta.
TVmaze lookup/shows?imdb= and shows/:id, plus AniList's public GraphQL search.
Fields added to meta on /meta:
| Field | Type | Description |
|---|---|---|
images |
object | poster/background/logo × small/medium/large/original. |
externalIds |
object | imdb, tmdb, tvdb, rottenTomatoes, metacritic. |
seasons |
number[] | Sorted season numbers (series). |
still |
object | { sizes, template } for episode stills (series). |
videos[].still |
string | Per-episode still URL (series). |
facts |
object | Wikidata fields (budget, boxOffice, runtimeMinutes, certification, officialWebsite, countries, languages, productionCompanies, genres, directors, composers, partOfSeries, externalIds). |
wiki |
object | { title, description, extract, url, thumbnail }. |
| Header | Meaning |
|---|---|
x-source |
Always streamx-api. |
x-cache |
HIT (edge cache) or MISS (freshly fetched). |
cache-control |
Per endpoint; images immutable for 30 days. |
access-control-allow-origin |
* |
| Endpoint | TTL |
|---|---|
/catalog, /search |
6 h |
/meta, /scores, /tv, /anime/search |
24 h (CACHE_TTL override) |
/streaming |
12 h |
/images, /img, /img/still |
30 d (images immutable) |
| Wikidata / Wikipedia / RT / MC / JustWatch / TVmaze / AniList | 24 h – 7 d |
Errors are JSON with ok: false:
{ "ok": false, "error": "Missing search term. Add ?q=<query>.", "detail": null }| Status | When |
|---|---|
400 |
Missing/invalid parameters. |
404 |
No such title/image. |
405 |
Method other than GET/HEAD/OPTIONS. |
502 |
Upstream unreachable or malformed. |
500 |
Unexpected internal error. |
const BASE = "https://api.streamx.qzz.io";
const id = "tt0133093";
const [{ meta }, scores, streaming] = await Promise.all([
fetch(`${BASE}/meta/movie/${id}`).then(r => r.json()),
fetch(`${BASE}/scores/movie/${id}`).then(r => r.json()),
fetch(`${BASE}/streaming/movie/${id}?country=US`).then(r => r.json()),
]);
console.log(meta.images.poster.large);
console.log(scores.rottenTomatoes?.critics.score, scores.metacritic?.critics.score);
console.log(streaming.providers.map(p => p.name));const { metas } = await fetch(`${BASE}/catalog/movie/top?genre=Sci-Fi`).then(r => r.json());
const posters = metas.map(m => m.poster);const { meta } = await fetch(`${BASE}/meta/series/tt0944947`).then(r => r.json());
for (const ep of meta.videos.slice(0, 5)) {
console.log(`S${ep.season}E${ep.number}`, ep.name, ep.still);
}- One artwork per kind. Cinemeta/MetaHub expose a single poster, backdrop and logo
per title; the "sizes" are renditions. Alternate poster designs require TMDb's
/imagesendpoint (key). - IMDb detail is not publicly available. Only suggestions (search) are keyless; IMDb ratings arrive via Cinemeta.
- Rotten Tomatoes & Metacritic are read from public pages. They are keyless and
cached, but are not official APIs and may change; requests fail soft to
null. - Community upstreams (Cinemeta, MetaHub, JustWatch) have no uptime SLA.
- English-centric. Metadata and enrichment are English-first.
How StreamX compares to the established options (2026):
| Capability | StreamX API | TMDb | OMDb | TVmaze | Watchmode | Trakt |
|---|---|---|---|---|---|---|
| API key required | No | Yes | Yes | No | Yes | Yes |
| Free for commercial use | Yes (self-hosted) | No ($149/mo < $1M ARR) |
No (CC BY-NC) | Yes | Metered | Limited |
| Free-tier limit | Edge cache (effectively unbounded) | ~40 req/10s | 1,000/day | 20 req/10s | 1,000/mo | 1,000/day |
| Movies and TV | Yes | Yes | Movies-first | TV-only | Yes | Yes |
| Catalogues + search | Yes | Yes | Search only | TV only | Yes | Search/lists |
| Multiple artwork sizes | 4 / kind | Many | Poster | TV images | Yes | No images |
| Episode stills | Yes | Yes | — | Yes | Yes | — |
| Aggregated ratings (IMDb/RT/MC) | Yes, 1 call | Partial | Yes | TV rating | Partial | User ratings |
| Critic + audience scores | Yes (RT + MC) | — | RT/MC only | — | Critic scores | — |
| Where-to-watch | Yes (JustWatch) | Yes (JustWatch) | — | — | Yes (core) | — |
| Budget / box office | Yes (Wikidata) | Revenue only | — | — | — | — |
| Wikipedia plot | Yes | Overview | Plot | Summary | — | — |
| CORS-open, no gateway | Yes | Yes | Yes | Yes | Yes | Yes |
| Self-hostable | Yes | No | No | No | No | No |
| OpenAPI / SDKs | No | Yes (v3.1) | Partial | Partial | Yes | Partial |
Where StreamX already wins: it is the only option that is simultaneously keyless, self-hostable, movie + TV, and returns metadata, artwork, critic scores, where-to-watch and Wikipedia plot from one deployment — ideal for prototypes, side projects, bots, and privacy-conscious apps that cannot register for keys.
Where the competition still leads: TMDb's breadth (people, credits, trending, recommendations, collections, keywords, translations, multiple images, ~150 endpoints), OMDb's simple IMDb-id lookup, Watchmode's availability depth (200+ services, 50+ countries, episode-level), and everyone's documentation, SDKs and SLAs.
Ranked by impact toward being #1:
Data breadth
- People & credits — no
/personendpoint, no full cast/crew with roles and characters, no filmography. (TMDb has this.) - Recommendations / similar / collections — no related-title or boxset graph.
- Trending & time-boxed lists — no
trending/day|week,now_playing,upcoming. - Multiple images — only one poster/backdrop/logo per title; no gallery.
- Localisation — English-only; no translations or
language=parameter. - Keywords / tags, alternative titles, certifications per country, release dates per country.
Search depth 7. Advanced search — no filters for year, genre, person, rating range, or sort. 8. People/anime/company search; anime↔IMDb mapping (search only today).
Reliability & trust 9. No SLA, status page, or uptime monitoring. 10. Scraped sources (Rotten Tomatoes, Metacritic) can change and carry ToS/legal ambiguity; no licensing clarity for artwork. 11. No tests in CI guarding the aggregators against upstream drift.
Developer experience
12. No OpenAPI/Swagger spec, no GraphQL option, no typed SDKs or Postman
collection.
13. Pagination is skip-only — no cursors, total, or "has more" flags.
14. No conditional requests (ETag/If-None-Match) or webhooks.
Depth of watch data 15. Streaming is single-country per request with no provider icons or bulk catalog; no episode-level availability.
A concrete plan to become the default keyless entertainment API.
Phase 1 — Close the breadth gap (0–1 mo)
-
/person/:id— bio, image, birth/death, external ids, Wikipedia summary. (v1.3) -
/credits/:type/:id— cast, crew and directors with roles & photos. (v1.3) -
/similar/:type/:id— sequels and same-director titles. (v1.3) -
/trending/:type— popularity-ordered titles. (v1.3) -
/recommendations/:type/:id,/collection/:id. -
/now-playing,/upcoming; awindow=day|weekoption on trending. - Multi-image gallery +
language=on/meta.
Phase 2 — Search & anime (1–2 mo)
/discoverwith year/genre/person/rating filters and sorting./anime/:id(episodes, characters) and a title↔AniList/IMDb resolver.
Phase 3 — Developer experience (2–3 mo)
- OpenAPI 3.1 spec + generated clients (JS/TS, Python, Go).
- Postman collection, a docs site, and copy-paste recipes for React/Next/Expo.
- Cursor pagination with
totalandhasMore;ETagcaching.
Phase 4 — Trust & scale (3–4 mo)
- Status page + uptime history; automated canary tests for every upstream in CI.
- Multi-provider fallback for ratings (e.g. a second keyless source) so a single
scraper drift cannot break
/scores. - Published rate-limit & release policy; versioned responses.
Phase 5 — Distribution (ongoing)
- README badges, a public benchmark (p50/p95 latency, cache hit-ratio).
- Listings in awesome-lists and API directories; an official "keyless by design" position; integrations (StreamX web app, Stremio addon, bots).
North star: the only API a developer needs for movies & TV — zero keys, one call, everything, with the breadth of TMDb and the openness of TVmaze.
- Swap/add a data source in
functions/_lib/upstream.js. - Tune the artwork matrix in
functions/_lib/images.js. - Add enrichment in
functions/_lib/enrich.jsand people data infunctions/_lib/people.js; scrapers/GraphQL inscrape.js,scores.js,watch.js,tvmaze.js. - Add a route by creating a file under
functions/(e.g.functions/person/[id].js→/person/:id). Underscore-prefixed files are not routed. Then register it inserver/app.jsso the portable Node/Vercel server serves it too, and add it tofunctions/health.js.
Project. StreamX API is made by @imzyrix and is part of @zyrixdevs. It is released under two licenses, one for each kind of material:
| Material | License | File |
|---|---|---|
Source code (functions/, server/, api/, mcp/, configs, Dockerfile, …) |
MIT | LICENSE |
Documentation & written content (README.md, docs/, skill/, llms*.txt, …) |
CC BY 4.0 | LICENSE-DOCS |
In short: use, fork, rebrand and self-host the code freely (keep the copyright notice); reuse the docs freely with attribution to StreamX API / @imzyrix / @zyrixdevs.
Upstream data. Metadata and artwork are read from public sources: Cinemeta, MetaHub, Wikidata, Wikipedia, IMDb (suggestions), Rotten Tomatoes, Metacritic, JustWatch, TVmaze and AniList. StreamX API only proxies and caches them and is not affiliated with any of them.
Posters and imagery remain the property of their respective rights holders — review the
terms of each upstream before commercial use. For guaranteed, licensed, commercial-grade
data, replace the layer in functions/_lib/upstream.js with a paid provider.