Multilingual movie metadata API

This multilingual movie metadata API serves titles, overviews, taglines, genre names and biographies in 14 languages: English, Russian, Ukrainian, Belarusian, Chinese, Portuguese, Bulgarian, Hebrew, Czech, Romanian, French, Polish, Italian and Spanish. Pass a TMDB tag such as ru-RU in the language parameter.

Get movie data in 14 languages

GET /3/movie/{movie_id}?language=ru-RU returns the title, overview, tagline and genre names in Russian. The language parameter takes TMDB tags such as ru-RU or pt-BR and works on every endpoint that returns text. Ids stay the same in every language, so one row in your database serves all of them.

You get 14 languages on one key, the original_title of every movie, a translations endpoint that lists all languages of a title, and localized genre names. The full list is on languages.

The 14 served languages

LanguageCodeExample tag
Englishenen-US
Russianruru-RU
Ukrainianukuk-UA
Belarusianbebe-BY
Chinesezhzh-CN
Portugueseptpt-BR
Bulgarianbgbg-BG
Hebrewhehe-IL
Czechcscs-CZ
Romanianroro-RO
Frenchfrfr-FR
Polishplpl-PL
Italianitit-IT
Spanisheses-ES

Any other tag falls back to en. Japanese and Korean are not served as interface languages. Their original titles still come back in original_title for movies and original_name for TV series.

What data you get

EndpointLocalized content
GET /3/movie/{movie_id}title, overview, tagline, genre names
GET /3/tv/{tv_id}name, overview, tagline, genre names
GET /3/tv/{tv_id}/season/{season_number}Season and episode name and overview
GET /3/person/{person_id}biography
GET /3/genre/movie/listGenre names for filters and menus
GET /3/movie/{movie_id}/translationsEvery language of a title in one reply
GET /3/movie/{movie_id}/imagesPosters tagged by language, filtered with include_image_language
GET /3/movie/{movie_id}/videosVideos tagged by iso_639_1, all languages in one reply

Start in 3 steps

  1. Choose a plan on pricing. Language count does not change with the plan, only the request rate does.
  2. Create a key in your account dashboard.
  3. Call any endpoint with a language tag, and send the key as api_key or as a Bearer header.

Example request

The bash sample prints the title of Fight Club (id 550) in three languages. It uses jq to print one field. The PHP sample requests Belarusian and falls back to English when the overview is blank.

for lang in en-US ru-RU he-IL; do
  curl -s "https://api.amodb.dev/3/movie/550?language=$lang" \
    -H "Authorization: Bearer $AMODB_KEY" | jq -r '.title'
done
<?php
function amodb(string $path, array $query = []): array
{
    $url = 'https://api.amodb.dev/3' . $path . '?' . http_build_query($query);
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
    ]);
    $body = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($status !== 200) {
        throw new RuntimeException("amodb returned $status");
    }
    return json_decode($body, true);
}

function localizedMovie(int $id, string $lang): array
{
    $movie = amodb("/movie/$id", ['language' => $lang]);
    $movie['text_language'] = $lang;
    if (trim($movie['overview'] ?? '') === '') {
        $fallback = amodb("/movie/$id", ['language' => 'en-US']);
        $movie['overview'] = $fallback['overview'] ?? '';
        $movie['text_language'] = 'en-US';
    }
    return $movie;
}

$movie = localizedMovie(550, 'be-BY');
echo $movie['title'], ' (', $movie['original_title'], ')', PHP_EOL;
echo '[', $movie['text_language'], '] ', $movie['overview'], PHP_EOL;

Response for language=ru-RU, trimmed to a few fields. The key text_language in the PHP sample is added by your code, not by the API.

JSON
{
  "genres": [
    {
      "id": 18,
      "name": "драма"
    },
    {
      "id": 53,
      "name": "триллер"
    }
  ],
  "id": 550,
  "original_language": "en",
  "original_title": "Fight Club",
  "overview": "Сотрудник страховой компании страдает хронической бессонницей и отчаянно пытается вырваться из мучительно скучной жизни. Однажды в очередной командировке он...",
  "poster_path": "/66RvLrRJTm4J8l3uHXWF09AICol.jpg",
  "tagline": "«Интриги. Хаос. Мыло»",
  "title": "Бойцовский клуб"
}

Fallback when a field is empty

Not every title has text in every language. An overview can come back empty when no translation exists, and a title or tagline can come back in English. The API does not invent text. Use a fixed order so the page always shows something:

  1. Request the language you display.
  2. If a field is empty, request en-US for the same id, or read the English entry from the translations list.
  3. If the title is empty, show original_title.
  4. Store which language each field came from, so you can retry later.

The edge cache holds one copy per language for each cached path, so the English fallback for a popular title is usually served from cache.

List every translation of a title

GET /3/movie/{movie_id}/translations returns a translations array, one entry per language that has data. The list can be longer than the 14 served languages: Fight Club has 50 entries. Use it to build a language switcher, or to store all texts of a title in one row.

FieldMeaning
iso_639_1, iso_3166_1Language and country codes
english_nameLanguage name in English
data.title (movies) or data.name (TV), data.overview, data.taglineLocalized text, the title can be empty
data.homepage, data.runtimeOptional values for that translation

The same endpoint exists for TV series and episodes. TV entries carry data.name and no runtime, and episode entries carry only name and overview. Seasons answer with an empty list, and people and collections have no translations endpoint. Details are on translations. One translations call replaces up to 14 detail calls when you want all languages at once.

Posters and videos by language

Pictures and videos carry their own language tags in iso_639_1. On the image endpoints, pass a comma separated list and add null for items with no language, such as textless posters. The reply holds the matching items, so rank them in your code.

ParameterUsed onExample
include_image_languageImage endpointsru,en,null

The video endpoints return every language in one reply and ignore include_video_language, so filter on iso_639_1 yourself. See images for sizes and the CDN.

Hebrew and right-to-left text

Hebrew is the only right-to-left language of the 14. Handle it in the page, not in the data:

  • Set lang="he" and dir="rtl" on the element that holds the text.
  • Wrap Latin titles inside Hebrew text in a <bdi> element so punctuation does not jump to the wrong side.
  • Use logical CSS properties such as margin-inline-start instead of left and right.

How it compares

CapabilityScrape pages yourselfEnglish-only datasetamodb
LanguagesOne site locale per requestEnglish14 languages with language
Same id across languagesDifferent urls per localeNot applicableSame numeric id everywhere
All translations of a titleFetch each locale pageNot applicableOne translations call
Localized postersPer-locale image urlsCheck their docsinclude_image_language filter
Original titleParse from page textCheck their docsoriginal_title, original_name

Pricing

The language set is the same on every plan, so you pay for rate and period only. Buy 1, 3, 6, 12 or 24 months prepaid, with 0, 10, 20, 30 or 40 percent off the longer ones and no automatic renewal. The 20, 40 and 120 requests per minute plans all include every language and every endpoint. A site in five languages needs up to five detail calls per title, and repeat requests are served from the edge cache for 6 hours. No free tier. See pricing.

Questions and answers

Which languages does the API serve?

Fourteen: English, Russian, Ukrainian, Belarusian, Chinese, Portuguese, Bulgarian, Hebrew, Czech, Romanian, French, Polish, Italian and Spanish, with the codes en ru uk be zh pt bg he cs ro fr pl it es.

What happens if I send a language tag that is not served?

The reply falls back to English. A tag such as ja-JP returns English text, while the original Japanese title still arrives in original_title for movies and original_name for TV series.

Can I get every translation of a title in one request?

Yes. GET /3/movie/{movie_id}/translations lists one entry per language that has data, each with title, overview, tagline, homepage and runtime. TV series and episodes have the same endpoint, with name in place of title. Seasons, people and collections have no translations.

How do I handle a missing overview in the chosen language?

Check for an empty string, then request the same id with en-US, or read the English entry from the translations list. Show original_title as the last fallback and mark the text as English. Titles and taglines can already come back in English.

Are posters localized as well?

Posters carry a language tag. Ask for them with include_image_language, for example ru,en,null, and rank the matches in your code. The image files come from img.amodb.dev and need no key.