API фильмов с протоколами TMDB v3 и OMDb

amodb является независимым API фильмов. Он использует тот же протокол, что TMDB v3 и OMDb, поэтому клиент, написанный для любого из них, работает после смены базового URL на https://api.amodb.dev/3 (или на https://api.amodb.dev/omdb/ для вызовов в стиле OMDb). Фильм вы находите через /search/movie, затем читаете его через /movie/{movie_id} и append_to_response.

Что вы получаете:

  • JSON в формате TMDB v3 с теми же путями и параметрами запроса.
  • Названия и описания на 14 языках, выбираются через language.
  • Актерский состав, съемочная группа, трейлеры, ключевые слова, изображения и даты выхода через append_to_response.
  • Рейтинги IMDb, Kinopoisk, Metacritic, Rotten Tomatoes и TMDB, где они известны.
  • Постеры с https://img.amodb.dev/t/p/{size}/{file}, без ключа.

Какие данные вы получаете

Что нужноВызовПримечания
Найти фильм по названиюGET /3/search/movie?query=Постранично, до 20 результатов на странице, edge-кэш 10 минут. См. поиск.
Основная записьGET /3/movie/{movie_id}Названия, описание, длительность, жанры, дата выхода. См. фильмы.
Актеры и съемочная группаappend_to_response=creditsПоля описаны на странице актеры и съемочная группа.
Трейлерыappend_to_response=videosВозвращает массив results с key, site и type.
Оценкиappend_to_response=ratingsПять источников, у каждого { value, votes } или null. См. рейтинги.
Ответ в стиле OMDbGET /omdb/?t=InceptionТе же поля тела, что у OMDb. См. эндпоинт OMDb.

Начало работы в 3 шага

  1. Выберите тариф на странице цены. Тарифы различаются только лимитом: 20, 40 или 120 запросов в минуту.
  2. Создайте ключ в личном кабинете. Ключ состоит из 32 строчных шестнадцатеричных символов.
  3. Вызывайте эндпоинт, передавая ключ в параметре api_key или в заголовке Authorization: Bearer. См. аутентификация.

Пример запроса

Пример находит Inception по названию, берет первый результат и читает фильм с актерами, трейлерами и рейтингами еще одним вызовом. Всего получается два запроса.

bashjs
# 1. find the id
curl -s "https://api.amodb.dev/3/search/movie?query=inception&language=en-US" \
  -H "Authorization: Bearer $AMODB_KEY"

# 2. read the movie with extras
curl -s "https://api.amodb.dev/3/movie/27205?language=en-US&append_to_response=credits,videos,ratings" \
  -H "Authorization: Bearer $AMODB_KEY"
const base = 'https://api.amodb.dev/3';
const headers = { Authorization: `Bearer ${process.env.AMODB_KEY}` };

async function get(path, params) {
  const res = await fetch(`${base}${path}?${new URLSearchParams(params)}`, { headers });
  if (res.status === 429) {
    throw new Error(`Over the limit, retry in ${res.headers.get('Retry-After')} s`);
  }
  if (!res.ok) throw new Error(`amodb returned ${res.status}`);
  return res.json();
}

const found = await get('/search/movie', { query: 'inception', language: 'en-US' });
if (!found.results.length) throw new Error('No match');

const movie = await get(`/movie/${found.results[0].id}`, {
  language: 'en-US',
  append_to_response: 'credits,videos,ratings',
});
const director = movie.credits.crew.find((c) => c.job === 'Director');
console.log(movie.title, movie.release_date, movie.runtime, director?.name);
console.log('IMDb', movie.ratings.imdb?.value);

Сокращенный ответ. Из записи фильма оставлены только некоторые поля, credits урезан до одного актера и режиссера, а блок videos опущен.

JSON
{
  "genres": [
    {
      "id": 12,
      "name": "Adventure"
    },
    {
      "id": 28,
      "name": "Action"
    },
    {
      "id": 80,
      "name": "Crime"
    }
  ],
  "id": 27205,
  "imdb_id": "tt1375666",
  "poster_path": "/xlaY2zyzMfkhk0HSC5VUwzoZPU1.jpg",
  "release_date": "2010-07-15",
  "runtime": 148,
  "title": "Inception",
  "credits": {
    "cast": [
      {
        "adult": false,
        "gender": 2,
        "id": 6193,
        "known_for_department": "Acting",
        "name": "Leonardo DiCaprio",
        "original_name": "Leonardo DiCaprio",
        "popularity": 9.3213,
        "profile_path": "/wo2hJpn04vbtmh0B9utCFdsQhxM.jpg",
        "character": "Dom Cobb",
        "credit_id": "52fe4534c3a368484e04de03",
        "order": 0
      }
    ],
    "crew": [
      {
        "adult": false,
        "gender": 2,
        "id": 525,
        "known_for_department": "Directing",
        "name": "Christopher Nolan",
        "original_name": "Christopher Nolan",
        "popularity": 8.578,
        "profile_path": "/xuAIuYSmsUzKlUMBFGVZaWsY3DZ.jpg",
        "credit_id": "5e83ac2ee33f830018359a00",
        "department": "Directing",
        "job": "Director"
      }
    ]
  },
  "ratings": {
    "imdb": {
      "value": 8.8,
      "votes": 2877173
    },
    "kinopoisk": {
      "value": 8.7,
      "votes": null
    },
    "metacritic": {
      "value": 74,
      "votes": null
    },
    "rotten_tomatoes": {
      "value": 86,
      "votes": null
    },
    "tmdb": {
      "value": 8.373,
      "votes": 40457
    }
  }
}

Способы найти фильм

Выберите вызов, который соответствует тому, что у вас уже есть.

Что у вас естьВызовРезультат
Название, введенное пользователемGET /3/search/movie?query=Массив results с id, title, release_date, poster_path
IMDb id, например tt0133093GET /3/find/tt0133093?external_source=imdb_idМассив movie_results
Числовой id фильма, например 603GET /3/movie/603Полная запись
Существующий клиент OMDbGET /omdb/?i=tt0133093Тело OMDb с Title, Year, Ratings

Сохраняйте оба id. Числовой id служит ключом для всех остальных вызовов, а imdb_id связывает ваши данные с другими системами. Правила поиска описаны на странице поиск по внешнему ID.

Пустые поля и неудачные запросы

В реальных данных о фильмах бывают пробелы, поэтому предусмотрите их в коде отображения. Поиск без совпадений не считается ошибкой: он возвращает HTTP 200 с пустым массивом results. Неизвестный id считается ошибкой.

СлучайЧто вы видитеЧто делать
Поиск ничего не нашел200 и "results": []Показать «нет совпадений», не повторять запрос
Неизвестный id фильма404 с status_code 34Уберите id из своего списка
Ключ отсутствует или неверен401 с status_code 7Остановитесь и исправьте ключ
Пустое overviewПустая строкаПовторите запрос с language=en-US
Неизвестная оценкаnull внутри ratingsСкройте этот значок
Нет даты выходаПустое release_dateПоставьте фильм в конец сортировки

Полный список ошибок приведен на странице ошибки.

Как уложиться в лимит запросов

Поиск и запрос данных стоят по одному запросу. При 20 запросах в минуту это десять поисков фильма в минуту, при 120 запросах в минуту шестьдесят. Попадание в edge-кэш тоже засчитывается, потому что проверка ключа и лимит запросов выполняются до кэша. Заведите собственный кэш для повторных запросов и читайте X-RateLimit-Remaining, чтобы видеть, сколько осталось от минуты. Получив 429, подождите число секунд из Retry-After. Лимиты по тарифам описаны на странице лимиты запросов.

Сравнение

ВозможностьПарсинг страниц самостоятельноAPI метаданных с бесплатным тарифомamodb
Формат ответаHTML, который нужно разбиратьJSONJSON в формате TMDB v3
Стабильность схемыЛомается при изменении разметки страницОпределяется провайдеромФиксированные пути и поля, могут появляться новые поля
Условия доступаДействуют условия каждого сайтаБесплатный тариф с условиями использования, проверьте ихПлатно, предоплата, без бесплатного тарифа
Лимит запросовНичего, на что можно положитьсяОпределяется провайдером20, 40 или 120 запросов в минуту на ключ
Рейтинги из нескольких источниковОдин парсер на сайтПо-разному, смотрите документациюratings в том же вызове, null, если неизвестно
ЯзыкиЧто предлагает каждая страницаПо-разному14, выбираются через language
Повторное использование клиентов TMDB v3 и OMDbНетТолько если используется тот же протоколДа, смените базовый URL

Цены

Доступ оплачивается заранее на 1, 3, 6, 12 или 24 месяца, скидка на более длинные периоды составляет 0, 10, 20, 30 и 40 процентов. Автоматического продления и бесплатного тарифа нет. Каждый тариф дает все данные, а тарифы различаются только лимитом: 20, 40 или 120 запросов в минуту. Выберите тариф на странице цены и сделайте первый вызов через несколько минут.