Streams
Playable links for a movie or episode — direct URLs, external apps, or torrent info-hashes.
The stream resource is what makes an add-on useful at playback time. When the user opens a movie or episode and taps the play button, wako asks every installed stream-capable add-on for sources in parallel and merges the results into a single list, with the user's preferred languages, qualities, and providers applied on top.
Endpoint
GET /stream/{type}/{id}.jsonFor movies and series tagged with IMDb IDs, the request shape is:
GET /stream/movie/tt0111161.json
GET /stream/series/tt0903747:1:1.jsonFor add-ons with custom IDs (returned in meta.videos), wako forwards the original video ID back unchanged.
Response
{
"streams": [
{
"url": "https://cdn.example.com/blade-runner-1080p.mp4",
"title": "1080p · H.264 · 2.1 GB\nEnglish",
"name": "My Add-on",
"behaviorHints": {
"bingeGroup": "my-addon-1080p",
"videoSize": 2254857830,
"filename": "blade.runner.1982.1080p.bluray.x264.mkv"
}
},
{
"infoHash": "08ada5a7a6183aae1e09d831df6748d566095a10",
"fileIdx": 1,
"title": "1080p · BluRay · 8.0 GB",
"sources": [
"tracker:udp://tracker.openbittorrent.com:80",
"dht:08ada5a7a6183aae1e09d831df6748d566095a10"
]
},
{
"externalUrl": "https://www.example.com/watch/blade-runner",
"title": "Watch on Example",
"name": "External"
}
]
}The response is wrapped in { "streams": [ … ] }. wako validates each entry and drops any item that has none of url, externalUrl, or infoHash — these are the three ways a stream can be playable.
Stream fields
At least one of: url, externalUrl, infoHash
| Field | Type | Description |
|---|---|---|
url | string | Direct HTTP(S) URL to a playable file. The wako player supports MP4, MKV, WebM, HLS (.m3u8), DASH (.mpd), and many other formats through the underlying media engine. The server should accept range requests for seeking. |
externalUrl | string | URL opened in the device's default browser or an external app. Use this when the playable resource lives behind a web player you cannot expose as a direct URL. |
infoHash | string | Torrent info-hash (40-character hex SHA1). wako forwards this to whichever cloud provider the user has configured to convert torrents into a streamable URL. |
fileIdx | number | For multi-file torrents, the index of the file to play. Omit to let the provider pick the largest file. |
sources | string[] | Additional sources for the info-hash. Each entry is a string with a protocol prefix:
|
Display
| Field | Type | Description |
|---|---|---|
name | string | The line shown in the small left-hand label of the stream entry — usually your add-on's short name. |
title | string | The main label of the stream entry. Multi-line is allowed — \n renders as a line break. wako uses this field to detect quality (1080p, 4K…), languages, audio codecs (DTS, AC3…), video codecs (HEVC, AV1…), and file size if you embed a string like 2.1 GB. Pack as much information as possible here. |
description | string | Optional longer text shown when the user expands the stream entry. |
Behavior hints
Behavior hints control how wako plays and remembers the stream. They are documented in full on the behavior hints reference page. The most important ones:
| Field | Type | Description |
|---|---|---|
bingeGroup | string | Identifies the variant — quality, language, codec — across episodes of the same series. When the user finishes an episode and the next one starts, wako auto-selects the stream with the same bingeGroup. Without this, every episode forces the user back to the stream list. |
videoSize | number | File size in bytes. wako displays it in the stream entry and uses it to detect season packs and pick the most efficient stream when the user has selected an automatic-quality mode. |
filename | string | Original filename (movie.1080p.bluray.x264.mkv). wako uses it for subtitle hashing and to match files inside a season pack. |
videoHash | string | OpenSubtitles-style hash (the first 64 KB + last 64 KB hashed together). When present, wako can request hash-matched subtitles from subtitle add-ons, which improves accuracy dramatically. |
notWebReady | boolean | Marks the stream as needing additional processing (e.g., custom HTTP headers or DRM). Use sparingly — most direct URLs do not need this flag. |
countryWhitelist | string[] | Restricts playback to viewers in the given ISO country codes. wako filters streams that include a whitelist not matching the user's region. |
proxyHeaders | object | Add custom HTTP headers when wako requests the URL. Each value is a string. See the behavior hints reference for the structure. |
Subtitles tied to a stream
A stream object can carry its own subtitles — useful when the source already ships a matching subtitle file. Each entry has url and lang.
{
"url": "https://cdn.example.com/movie.mp4",
"title": "1080p English",
"subtitles": [
{ "id": "en-1", "url": "https://cdn.example.com/movie.en.srt", "lang": "en" },
{ "id": "es-1", "url": "https://cdn.example.com/movie.es.srt", "lang": "es" }
]
}url, externalUrl, and infoHash. If your add-on is returning items and none of them show up in wako, this is the first thing to check.How wako enriches your streams
Once received, wako parses each stream's text fields and derives useful structured data:
- Quality. Detected from
2160p,4K,UHD,1080p,720p,480p,HD,SD. - File size. Either from
behaviorHints.videoSizeor parsed from a string like1.5 GB/800 MBinside the title. - Languages. Detected from common patterns (
FRE,VOSTFR,multi, full language names…) so wako can group by audio language. - Audio & video tags. HDR variants, codecs (HEVC, AV1), and audio formats (DTS, TrueHD…) are extracted into tags displayed as small chips on the stream entry.
- Season pack detection (series only). When the title looks like a complete season, wako tags the stream as a pack and tracks per-episode progress within it.
You do not need to do any of this yourself — but the more accurate the title, filename, and videoSize are, the better the enrichment.
Failure handling
If your add-on returns a non-200 status, an invalid JSON payload, or times out, wako shows a per-add-on error in the stream list ("{name} timed out", "Couldn't reach {name}", "{name} returned HTTP {status}"). Other add-ons keep working. Returning { "streams": [] } with a 200 is the explicit way to say "I have nothing for this item" without showing an error to the user.