# API tłumaczeń

> Endpointy tłumaczeń zwracają wszystkie wersje językowe rekordu w jednej odpowiedzi: title lub name, overview, tagline i homepage dla filmów i seriali oraz name i overview dla odcinków. Każdy wiersz niesie iso_639_1, iso_3166_1 i english_name. Użyj ich dla języków, których parametr language nie obsługuje, lub do zbudowania łańcucha zapasowego.

## Endpoint

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

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

Odpowiedź:

```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
      }
    }
  ]
}
```

## Pobieranie tłumaczeń filmu

`GET /3/movie/{movie_id}/translations` zwraca jeden wiersz na każdy język, który ma tekst dla filmu. Każdy wiersz zawiera obiekt `data` z przetłumaczonymi polami. Wywołanie nie przyjmuje parametru języka, bo cały sens polega na zobaczeniu wszystkich języków naraz.

Przykład znajduje wiersz rosyjski i wypisuje jego tytuł oraz początek opisu.

```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")
}
```

### Parametry

| Parametr   | Gdzie | Wymagany      | Opis                                                       |
| ---------- | ----- | ------------- | ---------------------------------------------------------- |
| `movie_id` | path  | tak           | Numeryczne ID filmu, na przykład `550`.                    |
| `api_key`  | query | jeden z dwóch | Twój klucz. Użyj go albo nagłówka `Authorization: Bearer`. |

### Pola odpowiedzi

| Pole                          | Typ     | Uwagi                                                                                                                                                   |
| ----------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                          | integer | ID filmu.                                                                                                                                               |
| `translations`                | array   | Jeden wiersz na każdy język, który ma tekst, posortowane według kodu języka. Film 550 zwraca 50 wierszy.                                                |
| `translations[].iso_3166_1`   | string  | Kod kraju towarzyszący językowi, na przykład `US` dla `en` lub `BR` dla `pt`. Dla języków spoza 14 obsługiwanych powtarza kod języka wielkimi literami. |
| `translations[].iso_639_1`    | string  | Kod języka, na przykład `ru` lub `pt`. Unikalny w tablicy.                                                                                              |
| `translations[].name`         | string  | Język zapisany w tym języku.                                                                                                                            |
| `translations[].english_name` | string  | Nazwa języka po angielsku.                                                                                                                              |
| `translations[].data`         | object  | Przetłumaczone pola. Klucze zależą od zasobu, zobacz tabelę poniżej.                                                                                    |

### Przykładowa odpowiedź

Pokazano dwa z 50 wierszy, a opisy są przycięte.

```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
      }
    }
  ]
}
```

W amodb `runtime` w wierszu tłumaczenia to zawsze 0. Czas trwania odczytaj z rekordu [szczegółów filmu](https://amodb.dev/pl/movies/).

## Endpointy tłumaczeń i ich klucze data

Wszystkie ścieżki mają wspólną bazę `https://api.amodb.dev/3`. Każda zwraca `id` i tablicę `translations` o kształcie wiersza powyżej. Zmieniają się tylko klucze wewnątrz `data`.

| Metoda i ścieżka                                                                   | Klucze `data`                                                    |
| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `GET /movie/{movie_id}/translations`                                               | `title`, `overview`, `homepage`, `tagline`, `runtime` (zawsze 0) |
| `GET /tv/{series_id}/translations`                                                 | `name`, `overview`, `homepage`, `tagline`                        |
| `GET /tv/{series_id}/season/{season_number}/translations`                          | brak, tablica jest zawsze pusta                                  |
| `GET /tv/{series_id}/season/{season_number}/episode/{episode_number}/translations` | `name`, `overview`                                               |

Rekordy seriali wymieniają mniej więcej tyle języków co filmy. Wiersze odcinków obejmują tylko obsługiwane języki, które mają tekst dla danego odcinka, od 2 do 14 w sprawdzonych próbkach. Brakujący klucz traktuj jak pustą wartość, a nieznane klucze ignoruj. Rekordy nadrzędne zobacz w [seriale](https://amodb.dev/pl/tv-series/).

amodb nie udostępnia tłumaczeń dla osób ani kolekcji. Biografia osoby zależy od parametru `language` w wywołaniu szczegółów osoby, a opis kolekcji przychodzi tak, jak zapisano.

## Zapas, gdy brakuje tekstu

Tytuł może istnieć w 14 językach i mimo to mieć pusty opis w języku wybranym przez użytkownika. Przejdź łańcuch języków, weź pierwszą niepustą wartość i zapamiętaj, z jakiego języka pochodzi.

```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');
```

Dla serialu przekaż jako pole `'name'` zamiast `'title'`. Oznacz w interfejsie tekst z języka zapasowego, by użytkownik wiedział, dlaczego ukraińska strona pokazuje angielskie streszczenie.

## Tłumaczenia czy parametr language

| Potrzeba                                                           | Użyj                                        |
| ------------------------------------------------------------------ | ------------------------------------------- |
| Pokazać jeden język jednemu użytkownikowi                          | `language` w wywołaniu szczegółów           |
| Wypisać wszystkie języki tytułu w edytorze                         | Ten endpoint                                |
| Odczytać język, którego `language` nie obsługuje, na przykład `ja` | Ten endpoint, wiersz wybierz po `iso_639_1` |
| Sprawdzić, które z 14 obsługiwanych języków mają tekst             | Ten endpoint, porównaj `iso_639_1`          |
| Zbudować linki do alternatywnych języków strony                    | Ten endpoint, odczytaj obecne kody          |

Tagi, które przyjmuje `language`, zobacz w [języki](https://amodb.dev/pl/languages/). Każdy inny tag wraca do angielskiego w wywołaniu szczegółów.

## Błędy

| HTTP | status_code | Kiedy                                                                               |
| ---- | ----------- | ----------------------------------------------------------------------------------- |
| 401  | 7           | Brakuje klucza lub jest błędny.                                                     |
| 402  | 36          | Okres planu dobiegł końca.                                                          |
| 404  | 34          | Brak sezonu lub odcinka o tym ID albo ID nie jest liczbą.                           |
| 405  | 37          | Użyto metody zapisu na ścieżce tłumaczeń.                                           |
| 429  | 25          | Przekroczono limit żądań na minutę. Poczekaj tyle sekund, ile podaje `Retry-After`. |

Nieistniejące ID filmu lub serialu nie jest na tej ścieżce błędem: odpowiada 200 z `"translations": []`, podczas gdy ścieżka szczegółów odpowiada 404. Więcej w [błędy](https://amodb.dev/pl/errors/) i [limity żądań](https://amodb.dev/pl/rate-limits/).

## Praktyczne uwagi

- Jedno wywołanie zastępuje do 14 wywołań szczegółów. Użyj go, gdy potrzebujesz więcej niż dwóch języków tego samego tytułu.
- Wiersze są posortowane według kodu języka, co nie jest kolejnością priorytetu. Wybieraj wiersze po `iso_639_1`, nigdy po pozycji w tablicy.
- Wywołania typu szczegółów są w cache na edge przez 6 godzin, więc cache klienta o tej samej długości nic nie kosztuje pod względem świeżości.
- Tytuły oryginalne w innych pismach, takich jak japońskie czy koreańskie, są zawsze dostępne w `original_title` i `original_name` w rekordzie szczegółów.
- Aby dodać tłumaczenia do wywołania szczegółów, przekaż `append_to_response=translations` i odczytaj tę samą tablicę z odpowiedzi. Działa dla filmów, seriali i odcinków. Dołączony blok nie ma `id`.

## Pytania i odpowiedzi

### Kiedy użyć tłumaczeń zamiast parametru language?

Użyj language, gdy pokazujesz użytkownikowi jeden język. Użyj tłumaczeń, gdy potrzebujesz kilku języków jednego tytułu naraz, na przykład w edytorze, na stronach w alternatywnych językach lub przy sprawdzaniu pokrycia. Zwracają też języki, których language nie obsługuje, takie jak ja lub de.

### Jaka jest różnica między iso_639_1 a iso_3166_1?

iso_639_1 to kod języka, na przykład pt. iso_3166_1 to kraj, który mu towarzyszy, na przykład BR. Dla języków spoza 14 obsługiwanych powtarza kod języka wielkimi literami, na przykład DA dla da, więc zawsze dopasowuj po iso_639_1.

### Dlaczego pole wewnątrz data jest puste?

Pusty ciąg lub zero oznacza, że dla tego pola w tym języku nie ma tekstu. Nie pokazuj go. Przejdź do następnego języka w swoim łańcuchu, zwykle angielskiego, albo do tytułu oryginalnego.

### Jakie języki obejmuje endpoint?

Rekordy filmów i seriali wymieniają każdy język, który ma katalog, często od 40 do 80 wierszy. Obejmuje to 14 obsługiwanych: en, ru, uk, be, zh, pt, bg, he, cs, ro, fr, pl, it i es. Odcinki wymieniają tylko niektóre z tych 14.

## Powiązane strony

- [API szczegółów filmu](https://amodb.dev/pl/movies/): API szczegółów filmu z tymi samymi ścieżkami i JSON co TMDB v3. Pobierz film po ID, dołącz obsadę, oceny i nastroje przez append_to_response, 14 języków.
- [API szczegółów serialu](https://amodb.dev/pl/tv-series/): API szczegółów serialu z tymi samymi ścieżkami i JSON co TMDB v3. Serial po ID z sezonami, sieciami, klasyfikacją wiekową i dostawcami streamingu.
- [API szczegółów osoby](https://amodb.dev/pl/people/): API szczegółów osoby z tymi samymi ścieżkami i JSON co TMDB v3. Aktor lub ekipa po ID z biografią, filmografią, zewnętrznymi ID i listą popularnych osób.
- [API kolekcji](https://amodb.dev/pl/collections/): API kolekcji filmów ze ścieżkami TMDB v3: pobierz franczyzę po ID ze wszystkimi filmami, odczytaj belongs_to_collection w filmie i szukaj kolekcji po nazwie.
- [Języki](https://amodb.dev/pl/languages/): amodb serwuje tytuły, opisy i nazwy w 14 językach. Podaj tag w stylu TMDB, np. ru-RU lub pt-BR, w language; każdy inny tag wraca do angielskiego.
- [API wielojęzycznych metadanych filmów](https://amodb.dev/pl/multilingual-movie-metadata-api/): API wielojęzycznych metadanych filmów w 14 językach: tagi TMDB, wszystkie tłumaczenia, powrót do angielskiego i obsługa hebrajskiego od prawej do lewej.

Zaktualizowano: 2026-10-18. Source: https://amodb.dev/pl/translations/
