# The Subtitle DB > A subtitle archive with a JSON API. Look a title up by TMDB id, IMDb id, > torrent infohash, release name or name, and get back the subtitle files for > it. No key, no account and no quota on any route below except search. API base: https://api.thesubtitledb.org Reference: https://thesubtitledb.org/developer/api Site: https://thesubtitledb.org This file is the API reference in plain text, written for a program reading the site rather than for a person. Every response below was captured from the live API. The one edit is the subtitle_languages map, cut to a few entries so this file stays readable; the real one lists every language a title has. ## How it works Pick the lookup route for the id you already have. They all answer the same two keys: title what the subtitles belong to subtitles one page of files: total, limit, offset, items A TV lookup with no season in the path adds a third: seasons the season and episode tree There is no seasons key anywhere else. A movie does not have one, and neither does a lookup drilled to a single episode. Three routes add one key of their own: by-title and by-releasename add match, by-subid adds subtitle, by-infohash adds torrent. Take download_url off an item and follow it. It answers 302 to a short-lived URL for the file itself. ## Rules - No key, no Authorization header and no account on every route except /v1/by-search. - lang takes one language code. lang=en, not lang=en,fr. - Downloads are rate limited to 50 per hour per IP. Ask the API from the client that wants the file. Proxying every user through one address spends that budget on the first few of them. - Ids are integers and they do not move. A subtitle id is that file's address for good. ## Filters Query parameters. Every lookup route takes them. lang one ISO 639-1 code, such as en, pt, zh format srt, ass, ssa, sub or vtt sort added (default) or downloads limit 1 to 100, default 20 offset default 0 ## GET /v1/by-tmdb/{tmdb-id} Also /v1/by-tmdb/{tmdb-id}/season/{season} and /v1/by-tmdb/{tmdb-id}/season/{season}/episode/{episode} The first-class lookup. The id is TMDB's, and TMDB numbers films and shows separately, so media_type in the answer tells you which one you asked for. GET https://api.thesubtitledb.org/v1/by-tmdb/496243?limit=1 { "title": { "imdb": "tt6751668", "tmdb_id": 496243, "media_type": "movie", "name": "Parasite", "year": 2019, "subtitle_count": 477, "subtitle_languages": { "en": 61, "es": 31, "ar": 24 } }, "subtitles": { "total": 477, "limit": 1, "offset": 0, "items": [ { "id": 8105574, "language": "af", "format": "srt", "cues": 1652, "duration_s": 7690, "bytes": 114360, "encoding": "utf-8", "release_name": "Parasite.2019.1080p.HDRip.X264.AC3-EVO", "hearing_impaired": false, "fps": null, "added_at": "2020-02-24T12:01:02Z", "download_url": "https://api.thesubtitledb.org/get/8105574" } ] } } ## GET /v1/by-imdb/{imdb-id} Also /v1/by-imdb/{imdb-id}/season/{season} and /v1/by-imdb/{imdb-id}/season/{season}/episode/{episode} The same lookup, keyed on the IMDb id with its tt prefix. Naming a season and an episode narrows subtitles to that episode and sends no seasons key, because you have already picked. GET https://api.thesubtitledb.org/v1/by-imdb/tt0944947/season/4/episode/2?limit=1 { "title": { "imdb": "tt0944947", "tmdb_id": 1399, "media_type": "tv", "name": "Game of Thrones", "year": 2011, "subtitle_count": 16365, "subtitle_languages": { "en": 3650, "fa": 2585, "ar": 2215 } }, "subtitles": { "total": 364, "limit": 1, "offset": 0, "items": [ { "id": 7994336, "language": "ar", "format": "srt", "cues": 761, "duration_s": 3208, "bytes": 54682, "encoding": "utf-8-sig", "release_name": "Game of Thrones S04E02 - The Lion and the Rose", "hearing_impaired": false, "fps": 23.976, "added_at": "2019-11-25T23:26:42Z", "download_url": "https://api.thesubtitledb.org/get/7994336" } ] } } ## The season and episode tree Ask for a series without naming a season and the seasons key is there, holding a list. Each season carries its episodes and a page of its own loose files, and each episode carries its own page, so one request is enough to draw a whole series. GET https://api.thesubtitledb.org/v1/by-tmdb/1434?lang=en&limit=1 "seasons": [ { "season": 1, "subtitle_count": 715, "episodes": [ { "season": 1, "episode": 1, "imdb": "tt0576927", "name": "Death Has a Shadow", "subtitle_count": 95, "subtitles": { "total": 95, "limit": 1, "offset": 0, "items": [ { "id": 9167359, "language": "fa", "format": "srt", "cues": 434, "duration_s": 1379, "bytes": 43877, "encoding": "utf-8-sig", "release_name": "Family Guy - S01E01 - Death Has A Shadow [480p DVD x265][MP3 2.0]", "hearing_impaired": false, "fps": null, "added_at": "2022-07-12T17:06:44Z", "download_url": "https://api.thesubtitledb.org/get/9167359" } ] } } ], "subtitles": { "total": 25, "limit": 1, "offset": 0, "items": [ ... ] }, "name": "Season 1", "poster_path": "/5E4yhF7TVrr1l8aq7GM6IdLTsrP.jpg", "air_date": "1999-01-31", "episode_count": 7 } ] ## GET /v1/by-infohash/{infohash} For a client that has a torrent and nothing else. The infohash is 40 hex characters. The answer adds torrent, which is what the hash was matched to. GET https://api.thesubtitledb.org/v1/by-infohash/dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c?lang=en&limit=1 { "torrent": { "infohash": "dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c", "name": "Big Buck Bunny" }, "title": { "imdb": "tt1254207", "tmdb_id": 10378, "media_type": "movie", "name": "Big Buck Bunny", "year": 2008, "subtitle_count": 2, "subtitle_languages": { "en": 1, "id": 1 } }, "subtitles": { "total": 1, "limit": 1, "offset": 0, "items": [ { "id": 5833874, "language": "en", "format": "srt", "cues": 2, "duration_s": 59, "bytes": 129, "encoding": "utf-8", "release_name": "big_buck_bunny", "hearing_impaired": false, "fps": 24, "added_at": "2014-09-24T14:43:45Z", "download_url": "https://api.thesubtitledb.org/get/5833874" } ] } } A hash nothing is filed under answers 404: { "error": "not_found", "message": "no title mapped to that infohash" } ## GET /v1/by-releasename?release={release-name} For a client that has a filename. Pass the release name as it is, dots and all. match says what it landed on and how sure it is: score is 0 to 1, and shared_tokens is how many parts of the name agreed. GET https://api.thesubtitledb.org/v1/by-releasename?release=parasite-2019-1080p-bluray-x264-yts&limit=1 { "match": { "sub_id": 8147329, "release_name": "parasite-2019-1080p-bluray-x264-yts", "score": 1, "shared_tokens": 6 }, "title": { "imdb": "tt6751668", "tmdb_id": 496243, "media_type": "movie", "name": "Parasite", "year": 2019, "subtitle_count": 477, "subtitle_languages": { "en": 61, "es": 31, "ar": 24 } }, "subtitles": { "total": 477, "limit": 1, "offset": 0, "items": [ ... ] } } ## GET /v1/by-title?q={name} The last resort, for a client that has only a name. It resolves one title and returns its subtitles, so it is a lookup and not a search: one answer, not a result list. match carries the name it settled on. GET https://api.thesubtitledb.org/v1/by-title?q=Parasite&limit=1 { "match": { "name": "Parasite", "imdb": "tt6751668", "score": 1 }, "title": { "imdb": "tt6751668", "tmdb_id": 496243, "media_type": "movie", "name": "Parasite", "year": 2019, "subtitle_count": 477, "subtitle_languages": { "en": 61, "es": 31, "ar": 24 } }, "subtitles": { "total": 477, "limit": 1, "offset": 0, "items": [ ... ] } } ## GET /v1/by-subid/{sub-id} One file, and the title it belongs to. subtitle is the file that was asked for; subtitles is still the title's full page, so a client can offer the rest. GET https://api.thesubtitledb.org/v1/by-subid/8147329 { "subtitle": { "id": 8147329, "language": "en", "format": "srt", "cues": 1664, "duration_s": 7743, "bytes": 111048, "encoding": "utf-8-sig", "release_name": "parasite-2019-1080p-bluray-x264-yts", "hearing_impaired": false, "fps": 23.976, "added_at": "2020-03-28T09:30:27Z", "download_url": "https://api.thesubtitledb.org/get/8147329" }, "title": { "imdb": "tt6751668", "tmdb_id": 496243, "media_type": "movie", "name": "Parasite", "year": 2019, "subtitle_count": 477, "subtitle_languages": { "en": 61, "es": 31, "ar": 24 } }, "subtitles": { "total": 477, "limit": 20, "offset": 0, "items": [ ... ] } } ## GET /v1/by-search?q={query} The one route that needs a key. It searches the whole corpus rather than resolving one title, which is the expensive thing to do, so it is the one thing behind an account. The key is free: https://thesubtitledb.org/account/signup Without one: { "error": "key_required", "message": "the search API needs a key. Create a free one at /account/signup" } ## GET /get/{sub-id} The file. Answers 302 with a Location header pointing at a short-lived URL, and Cache-Control: no-store, so follow the redirect rather than storing the link. This is the route the 50 per hour per IP limit is on. GET https://api.thesubtitledb.org/get/8147329 302 Found ## Errors Every error is JSON with the same two keys, and the HTTP status carries the same meaning. { "error": "not_found", "message": "no title mapped to tmdb id 999999999" } 400 the request is malformed, such as more than one lang code 401 the route needs a key and none was sent 404 nothing is filed under that id 429 rate limited ## More /developer the developer landing page /developer/api this reference, on the site /developer/plugins plugins for video players /developer/integrations apps that already read their subtitles from here /about what the archive is /copyright takedown policy and the form