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
| Language | Code | Example tag |
|---|---|---|
| English | en | en-US |
| Russian | ru | ru-RU |
| Ukrainian | uk | uk-UA |
| Belarusian | be | be-BY |
| Chinese | zh | zh-CN |
| Portuguese | pt | pt-BR |
| Bulgarian | bg | bg-BG |
| Hebrew | he | he-IL |
| Czech | cs | cs-CZ |
| Romanian | ro | ro-RO |
| French | fr | fr-FR |
| Polish | pl | pl-PL |
| Italian | it | it-IT |
| Spanish | es | es-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
| Endpoint | Localized 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/list | Genre names for filters and menus |
GET /3/movie/{movie_id}/translations | Every language of a title in one reply |
GET /3/movie/{movie_id}/images | Posters tagged by language, filtered with include_image_language |
GET /3/movie/{movie_id}/videos | Videos tagged by iso_639_1, all languages in one reply |
Start in 3 steps
- Choose a plan on pricing. Language count does not change with the plan, only the request rate does.
- Create a key in your account dashboard.
- Call any endpoint with a
languagetag, and send the key asapi_keyor 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.
{
"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:
- Request the language you display.
- If a field is empty, request
en-USfor the same id, or read the English entry from the translations list. - If the title is empty, show
original_title. - 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.
| Field | Meaning |
|---|---|
iso_639_1, iso_3166_1 | Language and country codes |
english_name | Language name in English |
data.title (movies) or data.name (TV), data.overview, data.tagline | Localized text, the title can be empty |
data.homepage, data.runtime | Optional 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.
| Parameter | Used on | Example |
|---|---|---|
include_image_language | Image endpoints | ru,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"anddir="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-startinstead of left and right.
How it compares
| Capability | Scrape pages yourself | English-only dataset | amodb |
|---|---|---|---|
| Languages | One site locale per request | English | 14 languages with language |
| Same id across languages | Different urls per locale | Not applicable | Same numeric id everywhere |
| All translations of a title | Fetch each locale page | Not applicable | One translations call |
| Localized posters | Per-locale image urls | Check their docs | include_image_language filter |
| Original title | Parse from page text | Check their docs | original_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.