Wyzie Subs
Directly Fetching Wyzie Subs#
If you have decided against using the NPM package, then let's get started. I will only be going over API parameters and data returned by the API. How you request the API is entirely up to you.
Example#
{
"id": "1955024019",
"url": "https://sub.wyzie.io/c/198e0c4d/id/1955024019?format=srt&encoding=UTF-8&tok=...",
"flagUrl": "https://flagsapi.com/US/flat/24.png",
"format": "srt",
"encoding": "UTF-8",
"display": "English",
"language": "en",
"media": "The Martian",
"isHearingImpaired": false,
"source": "charlie",
"release": "The.Martian.2015.1080p.WEB-DL",
"releases": ["The.Martian.2015.1080p.WEB-DL"],
"fileName": "the.martian.2015.1080p.web-dl.srt",
"downloadCount": 48213,
"origin": "WEB-DL",
"matchedRelease": "The.Martian.2015.1080p.WEB-DL",
"matchedFilter": "martian",
"ai": false
}Parameters#
| Parameter | Example | Description |
|---|---|---|
| id | /search?id=tt3659388 or /search?id=286217 | TMDB or IMDB ID of the show or movie (required). |
| season & episode | /search?id=tt0121955&season=1&episode=1 | Season and episode for TV searches. Both must be present together. |
| language | /search?id=tt3659388&language=en,es | Language filter (ISO 639-1 codes). Multiple values are comma-separated. |
| format | /search?id=tt3659388&format=srt,ass | Subtitle formats to return. Multiple values allowed. |
| hi | /search?id=tt3659388&hi=true | When true, returns only hearing-impaired subtitles (it is a filter, not a preference). Sources that do not flag hearing-impaired subtitles return nothing. |
| encoding | /search?id=tt3659388&encoding=utf-8,latin-1 | Character encoding filter. |
| source | /search?id=tt3659388&source=charlie,lima | Subtitle providers to query (all queries every source your key can use; default charlie). |
| release | /search?id=tt3659388&release=martian,1080p | Release or scene name filters (comma-separated). |
| file/fileName | /search?id=tt3659388&file=proper | Filename filters (aliases: file, filename, fileName). |
| origin | /search?id=tt3659388&origin=WEB,BLURAY | Content origin filter, comma-separated (e.g., WEB, BLURAY, DVD). |
| key | /search?id=tt3659388&key=YOUR_KEY | Your API key (required). Get one free at store.wyzie.io/redeem. |
| refresh | /search?id=tt3659388&refresh=true | Bypass cache and fetch fresh results. Use when sources may have updated. |
| page | /search?id=tt3659388&limit=50&page=2 | Page to return, starting at 1. Only used together with limit. |
| limit | /search?id=tt3659388&limit=50 | Results per page (1 to 200). Without it, every result comes back in one response. |
| sort | /search?id=tt3659388&sort=downloads | Set to downloads to list the most downloaded subtitles first. Results without a download count go last. Works with page and limit, and costs the same 1 request. |
Data Returned#
| Object | Description |
|---|---|
| id | The ID of the subtitle file. |
| url | Download link on https://sub.wyzie.io/c/... carrying an encrypted tok parameter. Each download costs 1 request; see Downloading Subtitles below. |
| flagUrl | URL to the flag of the language's locale. |
| format | The format of the subtitle file. |
| encoding | The character encoding of the subtitle file. |
| display | The language of the subtitle, capitalized. |
| language | The ISO 639-1 code of the language. |
| media | The name of the media that the subtitles are for. |
| isHearingImpaired | Boolean representing if the subtitle is hearing impaired accessible. |
| source | Which source the subtitle was scraped from. |
| release | Primary release name. |
| releases | Other release names compatible with the subtitle. |
| fileName | Original filename when available. |
| downloadCount | Number of downloads on the source platform (if available). |
| origin | Content origin (e.g., WEB, BluRay, DVD). |
| matchedRelease | Release value that matched your filter (if provided). |
| matchedFilter | The user-supplied filter that matched (if provided). |
| ai | true if the entry is an AI-translated subtitle, false for normal scraped subtitles. Use it as a client-side filter when you only want one or the other. |
Downloading Subtitles#
Every url in a /search response points to https://sub.wyzie.io/c/... and carries a tok query parameter. tok is encrypted, so it does not reveal your API key, and it stays valid for 60 days. Each link has its own tok that opens only that file, so use the URL as-is (adding download options is fine). A search costs 1 request and each download costs 1 more, billed to the key that ran the search. When that key cannot pay for a download, the link is refused:
| Status | Cause |
|---|---|
| 402 | The Pro balance is exhausted. The JSON includes a topup link. |
| 429 | A free key is over its daily cap of 1,000 requests. The JSON includes reset_at, plus a Retry-After header. |
| 403 | The key is invalid, or it is on hold (see API Keys). Also "Paid feature": a Pro-only download option on a free key (not billed). |
| 401 | The tok parameter is missing or expired. |
| 400 | A download option has an invalid value, or dual is used on a link without the title id (search again). Not billed. |
| 422 | Download options were used on a file with no timed lines (an image-based subtitle or plain text). |
Download Options#
Add these to a download URL to change what it returns. They work on every download, cached or not, and cost nothing extra (except dual, below). The X-Subtitle-Transforms response header lists what was applied, with counts.
| Parameter | Example | Plan | Description |
|---|---|---|---|
| to | &to=vtt | All | Output format: srt or vtt. vtt plays directly in a browser <track> element. Default: the file's own format. |
| offset | &offset=-1.5 | All | Shift every line by this many seconds (negative is earlier). |
| fps | &fps=25:23.976 | All | Fix drift from a subtitle made for another release: SUBTITLE_FPS:VIDEO_FPS, e.g. 25:23.976 for a PAL subtitle on a film-rate video. |
| plain | &plain=1 | All | Plain, tidy lines: styling codes such as {\an8} and <font> removed, empty and repeated lines dropped, lines in time order, small overlaps trimmed. |
| sdh | &sdh=strip | Pro | Remove hearing-impaired text: [DOOR SLAMS], (sighs), JOHN: speaker labels and ♪ lyrics. |
| clean | &clean=1 | Pro | Mask strong profanity, keeping the first letter (f***). English files only. |
| dual | &dual=ja | Pro | Add a second language (ISO 639-1 code) under each line, lined up with this file's timing. Costs 1 extra request, only when a match is found; otherwise the file comes back alone with X-Dual: unavailable. |
Options combine, e.g. &to=vtt&sdh=strip&offset=-1.5. Links already carry format, encoding, id and (for episodes) season and episode: leave those as they are. autoUnzip=false returns an archive as-is.
X-Ads-Removed (true if a provider ad cue was stripped) and X-Cache (HIT or MISS).One-Call Download#
With an API key, GET /download returns the subtitle file itself in one call: it searches with your key and the same parameters as /search (language defaults to en), picks the best match and serves it. That costs 2 requests, the same as a search plus a download. Download options such as to and offset apply to the file.
curl -o subtitle.vtt "https://sub.wyzie.io/download?id=tt0111161&language=en&to=vtt&key=YOUR_KEY"The best match is the first search result, preferring SRT, WebVTT and ASS files unless you set format, and files without hearing-impaired text unless you set hi=true. Narrow it with release, filename, source or origin. The X-Subtitle-Release, X-Subtitle-Source, X-Subtitle-Language and X-Subtitle-Url response headers say which file was picked. Errors are the same as for /search and download links.
Pagination and Headers#
Every /search response includes an X-Total-Count header with the total number of results. When you pass limit, it also includes:
X-Page: the page returned.X-Per-Page: the limit in effect.X-Total-Pages: the total number of pages.
Responses also carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. Treat them as approximate: usage is settled with billing in short batches, so they can trail your real usage slightly.
Errors#
Errors are returned as JSON with the matching HTTP status:
{
"code": 401,
"message": "API key required",
"details": "Include a valid API key as the `key` query parameter. Claim a free key at https://store.wyzie.io/redeem",
"notice": "https://sub.wyzie.io/notice"
}| Status | Message | Cause |
|---|---|---|
| 400 | No subtitles found | The search completed but nothing matched your parameters. |
| 400 | No matching release found | Subtitles exist for the title, but none matched your release, file, or origin filters. |
| 400 | Invalid source | A source value is not a known codename or all. |
| 400 | Invalid language format | language must be ISO 639-1 codes (two letters, e.g. en,es). |
| 400 | Both season and episode are required | Only one of season and episode was sent. |
| 401 | API key required | The key parameter is missing. |
| 402 | Pro key request balance exhausted | The Pro key has no requests left. The JSON includes a topup link. |
| 403 | Invalid API key | The key parameter was sent but the key is not recognized. |
| 403 | Provider not available on free plan | Every source you asked for is Pro-only. Free keys can use charlie and lima. |
| 403 | Key on hold | The key was paused for very high datacenter traffic. The JSON includes reinstate and support links; see API Keys. |
| 429 | Daily request limit reached | A free key is over its daily cap of 1,000 requests. The JSON includes reset_at and upgrade, plus a Retry-After header. |
| 503 | Service temporarily unavailable | Key verification is briefly unavailable. Retry in a moment. |
| 503 | Source temporarily offline | Every source you named is paused by its health checks (not billed). See Sources; use a live source or source=all. |
