# API перекладів

> Ендпоінти перекладів повертають усі мовні версії запису в одній відповіді: назву, опис, слоган і homepage для фільмів та серіалів, назву й опис для серій. Кожен рядок містить iso_639_1, iso_3166_1 та english_name. Використовуйте їх, щоб читати мови, яких не обслуговує параметр language, або будувати ланцюжок запасних мов.

## Ендпоінт

`GET /3/movie/{movie_id}/translations`

```bash
curl "https://api.amodb.dev/3/movie/550/translations" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Відповідь:

```json
{
  "id": 550,
  "translations": [
    {
      "iso_3166_1": "AR",
      "iso_639_1": "ar",
      "name": "العربية",
      "english_name": "Arabic",
      "data": {
        "title": "نادي القتال",
        "overview": "يعيش موظف مكتبي يعاني من الأرق والملل حياة روتينية فارغة، إلى أن يلتقي بالرجل الغامض تايلر ديردن، الذي يختلف عنه تمامًا ويؤمن بأن التحرر من قيود المجتمع يبدأ برفض الحياة التقليدية. تنشأ بينهما صداقة غريبة تقودهما إلى تأسيس نادٍ سري يتجمع في...",
        "homepage": "",
        "tagline": "نادي القتال هو نادي يوجد في العقل الباطن لكل واحد منا !",
        "runtime": 0
      }
    },
    {
      "iso_3166_1": "AZ",
      "iso_639_1": "az",
      "name": "Azərbaycan",
      "english_name": "Azerbaijani",
      "data": {
        "title": "Döyüş Klubu",
        "overview": "Xəyalları olmayan bir gənc yuxusuzluğa qarşı mübarizə aparır, bəlkə də boz və gündəlik həyatı ilə cansıxıcılığının nəticəsidir. Təyyarə gəzintisində o, çox xüsusi bir fəlsəfəyə sahib olan xarizmatik sabun satıcısı Tyler Durden ilə tanış olu...",
        "homepage": "",
        "tagline": "",
        "runtime": 0
      }
    },
    {
      "iso_3166_1": "BY",
      "iso_639_1": "be",
      "name": "Беларуская",
      "english_name": "Belarusian",
      "data": {
        "title": "Байцоўскі клуб",
        "overview": "A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground \"fight clubs\" forming in every town, until an eccentric gets in the wa...",
        "homepage": "",
        "tagline": "",
        "runtime": 0
      }
    }
  ]
}
```

## Отримання перекладів фільму

`GET /3/movie/{movie_id}/translations` повертає по одному рядку на кожну мову, для якої є текст фільму. Кожен рядок містить об'єкт `data` з перекладеними полями. Виклик не приймає параметра мови, бо головна ідея в тому, щоб побачити всі мови одразу.

Приклад знаходить російський рядок і виводить його назву та початок опису.

```bash
curl -s "https://api.amodb.dev/3/movie/550/translations" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```js
const url = 'https://api.amodb.dev/3/movie/550/translations';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { translations } = await res.json();
const ru = translations.find((t) => t.iso_639_1 === 'ru');
console.log(ru ? `${ru.data.title}: ${ru.data.overview.slice(0, 80)}` : 'no Russian row');
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/movie/550/translations",
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
ru = next((t for t in r.json()["translations"] if t["iso_639_1"] == "ru"), None)
print(f"{ru['data']['title']}: {ru['data']['overview'][:80]}" if ru else "no Russian row")
```

```php
<?php
$ch = curl_init('https://api.amodb.dev/3/movie/550/translations');
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");
}
foreach (json_decode($body, true)['translations'] as $t) {
    if ($t['iso_639_1'] === 'ru') {
        echo $t['data']['title'], ': ', mb_substr($t['data']['overview'], 0, 80), PHP_EOL;
        exit;
    }
}
echo 'no Russian row', PHP_EOL;
```

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

type Translations struct {
	Translations []struct {
		ISO6391 string `json:"iso_639_1"`
		Data    struct {
			Title    string `json:"title"`
			Overview string `json:"overview"`
		} `json:"data"`
	} `json:"translations"`
}

func main() {
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/movie/550/translations", nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	client := &http.Client{Timeout: 10 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic(res.Status)
	}
	var t Translations
	if err := json.NewDecoder(res.Body).Decode(&t); err != nil {
		panic(err)
	}
	for _, row := range t.Translations {
		if row.ISO6391 == "ru" {
			text := []rune(row.Data.Overview)
			if len(text) > 80 {
				text = text[:80]
			}
			fmt.Printf("%s: %s\n", row.Data.Title, string(text))
			return
		}
	}
	fmt.Println("no Russian row")
}
```

### Параметри

| Параметр   | Де    | Обов'язковий | Опис                                                                 |
| ---------- | ----- | ------------ | -------------------------------------------------------------------- |
| `movie_id` | шлях  | так          | Числовий id фільму, наприклад `550`.                                 |
| `api_key`  | query | один із двох | Ваш ключ. Використовуйте його або заголовок `Authorization: Bearer`. |

### Поля відповіді

| Поле                          | Тип        | Примітки                                                                                                                                        |
| ----------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                          | ціле число | ID фільму.                                                                                                                                      |
| `translations`                | масив      | Рядки по одному на мову, для якої є текст, відсортовані за кодом мови. Фільм 550 повертає 50 рядків.                                            |
| `translations[].iso_3166_1`   | рядок      | Код країни, що відповідає мові, наприклад `US` для `en` або `BR` для `pt`. Для мов поза 14 обслуговуваними повторює код мови великими літерами. |
| `translations[].iso_639_1`    | рядок      | Код мови, наприклад `ru` або `pt`. Унікальний у масиві.                                                                                         |
| `translations[].name`         | рядок      | Назва мови, записана цією мовою.                                                                                                                |
| `translations[].english_name` | рядок      | Назва мови англійською.                                                                                                                         |
| `translations[].data`         | об'єкт     | Перекладені поля. Ключі залежать від ресурсу, див. таблицю нижче.                                                                               |

### Приклад відповіді

Показано два з 50 рядків, описи скорочено.

```json
{
  "id": 550,
  "translations": [
    {
      "iso_3166_1": "US",
      "iso_639_1": "en",
      "name": "English",
      "english_name": "English",
      "data": {
        "title": "Fight Club",
        "overview": "A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy....",
        "homepage": "https://www.20thcenturystudios.com/movies/fight-club",
        "tagline": "Mischief. Mayhem. Soap.",
        "runtime": 0
      }
    },
    {
      "iso_3166_1": "RU",
      "iso_639_1": "ru",
      "name": "Русский",
      "english_name": "Russian",
      "data": {
        "title": "Бойцовский клуб",
        "overview": "Сотрудник страховой компании страдает хронической бессонницей и отчаянно пытается вырваться из мучительно скучной жизни. Однажд...",
        "homepage": "https://www.20thcenturystudios.com/movies/fight-club",
        "tagline": "«Интриги. Хаос. Мыло»",
        "runtime": 0
      }
    }
  ]
}
```

В amodb `runtime` у рядку перекладу завжди дорівнює 0. Читайте тривалість із запису [деталі фільму](https://amodb.dev/uk/movies/).

## Ендпоінти перекладів і ключі data

Усі шляхи мають спільну базу `https://api.amodb.dev/3`. Кожен повертає `id` та масив `translations` із рядками такої самої форми, як вище. Змінюються лише ключі всередині `data`.

| Метод і шлях                                                                       | Ключі `data`                                                     |
| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `GET /movie/{movie_id}/translations`                                               | `title`, `overview`, `homepage`, `tagline`, `runtime` (завжди 0) |
| `GET /tv/{series_id}/translations`                                                 | `name`, `overview`, `homepage`, `tagline`                        |
| `GET /tv/{series_id}/season/{season_number}/translations`                          | немає, масив завжди порожній                                     |
| `GET /tv/{series_id}/season/{season_number}/episode/{episode_number}/translations` | `name`, `overview`                                               |

Записи серіалів містять приблизно стільки ж мов, скільки й фільми. Рядки серій охоплюють лише ті обслуговувані мови, для яких є текст цієї серії, від 2 до 14 у перевірених зразках. Відсутній ключ сприймайте як порожнє значення, а невідомі ключі ігноруйте. Батьківські записи дивіться в розділі [серіали](https://amodb.dev/uk/tv-series/).

amodb не пропонує перекладів для персон чи колекцій. Біографія персони залежить від параметра `language` виклику деталей персони, а опис колекції повертається як збережений.

## Запасний варіант, коли тексту немає

Назва може існувати у 14 мовах і все одно мати порожній опис мовою, яку обрав користувач. Пройдіть ланцюжок мов, візьміть перше непорожнє значення й запам'ятайте, з якої мови воно прийшло.

```js
function pickText(translations, wanted, field) {
  for (const code of [...wanted, 'en']) {
    const row = translations.find((t) => t.iso_639_1 === code);
    const value = row?.data?.[field];
    if (value) return { code, value };
  }
  return null;
}

// Prefer Ukrainian, then Russian, then English.
// const hit = pickText(translations, ['uk', 'ru'], 'overview');
```

Для серіалу передайте `'name'` як поле замість `'title'`. Позначайте в інтерфейсі текст із запасної мови, щоб користувач розумів, чому українська сторінка показує англійський опис.

## Переклади чи параметр language

| Потреба                                                   | Що використати                              |
| --------------------------------------------------------- | ------------------------------------------- |
| Показати одну мову одному користувачеві                   | `language` у виклику деталей                |
| Вивести всі мови назви в редакторі                        | Цей ендпоінт                                |
| Прочитати мову, якої `language` не обслуговує, як-от `ja` | Цей ендпоінт, обирайте рядок за `iso_639_1` |
| Перевірити, для яких із 14 обслуговуваних мов є текст     | Цей ендпоінт, порівнюйте `iso_639_1`        |
| Побудувати посилання на альтернативні мови сторінки       | Цей ендпоінт, читайте наявні коди           |

Теги, які приймає `language`, дивіться в розділі [мови](https://amodb.dev/uk/languages/). Будь-який інший тег у виклику деталей повертається до англійської.

## Помилки

| HTTP | status_code | Коли                                                                                               |
| ---- | ----------- | -------------------------------------------------------------------------------------------------- |
| 401  | 7           | Ключ відсутній або хибний.                                                                         |
| 402  | 36          | Термін дії тарифу закінчився.                                                                      |
| 404  | 34          | Немає сезону чи серії з таким id або id не є числом.                                               |
| 405  | 37          | Ви використали метод запису на шляху перекладів.                                                   |
| 429  | 25          | Ви перевищили ліміт запитів на хвилину. Зачекайте стільки секунд, скільки вказано в `Retry-After`. |

Неіснуючий id фільму чи серіалу на цьому шляху не помилка: він відповідає 200 із `"translations": []`, тоді як шлях деталей відповідає 404. Докладніше про [помилки](https://amodb.dev/uk/errors/) та [ліміти запитів](https://amodb.dev/uk/rate-limits/).

## Практичні нотатки

- Один виклик замінює до 14 викликів деталей. Використовуйте його, коли потрібно більше двох мов однієї назви.
- Рядки відсортовано за кодом мови, а це не порядок пріоритету. Обирайте рядки за `iso_639_1`, ніколи за позицією в масиві.
- Виклики типу деталей кешуються на edge на 6 годин, тож клієнтський кеш такої самої тривалості нічого не коштує у свіжості.
- Оригінальні назви іншими писемностями, як-от японською чи корейською, завжди доступні в `original_title` та `original_name` запису деталей.
- Щоб додати переклади до виклику деталей, передайте `append_to_response=translations` і читайте той самий масив у відповіді. Це працює для фільмів, серіалів і серій. Доданий блок не має `id`.

## Запитання й відповіді

### Коли використовувати translations замість параметра language?

Використовуйте language, коли показуєте користувачеві одну мову. Використовуйте translations, коли потрібно кілька мов однієї назви одночасно, наприклад на екрані редактора, на сторінках альтернативних мов або для перевірки покриття. Він також повертає мови, яких language не обслуговує, як-от ja чи de.

### Чим відрізняються iso_639_1 та iso_3166_1?

iso_639_1 це код мови, наприклад pt. iso_3166_1 це країна, що йде з нею, наприклад BR. Для мов поза 14 обслуговуваними він повторює код мови великими літерами, наприклад DA для da, тому завжди зіставляйте за iso_639_1.

### Чому поле всередині data порожнє?

Порожній рядок або нуль означає, що для цього поля цією мовою тексту немає. Не показуйте його. Переходьте до наступної мови у вашому ланцюжку, зазвичай англійської, або до оригінальної назви.

### Які мови охоплює ендпоінт?

Записи фільмів і серіалів перелічують усі мови, що є в каталозі, часто від 40 до 80 рядків. Це включає 14 обслуговуваних: en, ru, uk, be, zh, pt, bg, he, cs, ro, fr, pl, it та es. Серії перелічують лише частину цих 14.

## Пов'язані сторінки

- [API деталей фільму](https://amodb.dev/uk/movies/): API деталей фільму з тими самими шляхами та JSON, що в TMDB v3. Отримайте фільм за id, додайте акторів, рейтинги й настрої через append_to_response, 14 мовами.
- [API серіалів](https://amodb.dev/uk/tv-series/): API серіалів з тими самими шляхами та JSON, що в TMDB v3. Отримайте серіал за id із сезонами, телемережами й наступною серією, плюс вікові рейтинги.
- [API деталей персони](https://amodb.dev/uk/people/): API деталей персони з тими самими шляхами та JSON, що в TMDB v3. Отримайте актора чи режисера за id: біографія, фільмографія, зовнішні id і список популярних.
- [API колекцій](https://amodb.dev/uk/collections/): API колекцій фільмів зі шляхами TMDB v3: отримайте франшизу за id з усіма частинами, прочитайте belongs_to_collection у фільму та знайдіть колекцію за назвою.
- [Мови](https://amodb.dev/uk/languages/): amodb віддає назви, описи та імена 14 мовами. Передайте в language тег у стилі TMDB, наприклад ru-RU або pt-BR; будь-який інший тег переходить на англійську.
- [API багатомовних метаданих фільмів](https://amodb.dev/uk/multilingual-movie-metadata-api/): API багатомовних метаданих фільмів на 14 мов. Теги мов TMDB, усі переклади, відкат на англійську та підтримка івриту з написанням справа наліво.

Оновлено: 2026-10-18. Source: https://amodb.dev/uk/translations/
