# 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](https://amodb.dev/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

1. Choose a plan on [pricing](https://amodb.dev/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.

```bash
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
<?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.

| 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](https://amodb.dev/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](https://amodb.dev/images-api/) 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

| 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](https://amodb.dev/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.

## Related pages

- [Languages](https://amodb.dev/languages/): amodb serves titles, overviews and names in 14 languages. Pass a TMDB style tag such as ru-RU or pt-BR in language; any other tag falls back to English.
- [Translations API](https://amodb.dev/translations/): Movie translations API with TMDB v3 paths: read every stored title, overview and tagline of a movie, series or episode in all its languages at once.
- [Movie details API](https://amodb.dev/movies/): Movie details API with the same paths and JSON as TMDB v3. Get one movie by id, add credits, ratings and moods with append_to_response, in 14 languages.
- [TV series API](https://amodb.dev/tv-series/): TV series API with the same paths and JSON as TMDB v3. Get a show by id with seasons, networks and the next episode, plus content ratings and watch providers.
- [Images API and image host](https://amodb.dev/images-api/): Movie images API with TMDB v3 paths: list posters, backdrops, logos and stills per title, then load them from img.amodb.dev in 10 sizes with no key.
- [Quickstart](https://amodb.dev/quickstart/): Make your first amodb call: get a key, request movie details in curl, JavaScript, Python, PHP or Go, then load the poster from img.amodb.dev. Under 2 minutes.

Updated: 2026-10-18. Source: https://amodb.dev/multilingual-movie-metadata-api/
