# API бази фільмів для вашого каталогу

> Використовуйте amodb як джерело для власної бази фільмів. Фільми, персони, компанії, колекції, ключові слова та жанри мають спільні числові id, тож рядки легко поєднуються. Заповнюйте базу сторінками discover у вікнах дат виходу, оновлюйте рядки за віком і зіставляйте власні id через пошук за зовнішнім ID. JSON TMDB v3, від 20 до 120 запитів на хвилину.

## Побудуйте власну базу фільмів через API

amodb це незалежний API, що працює за протоколом TMDB v3. Фільми, персони, компанії, колекції, ключові слова та жанри мають числові id і посилаються одне на одного, тож ви можете заповнити з них SQL-таблиці й підтримувати їх актуальними. Заповнюйте таблиці сторінками discover, оновлюйте їх за віком і зіставляйте власні ідентифікатори через `find`. У amodb немає стрічки змін, тож оновлення це звичайний повторний запит рядків, які ви зберігаєте.

Що ви отримуєте:

- Шість пов'язаних типів сутностей зі стабільними числовими id.
- Сторінки discover для першого завантаження: до 20 результатів на сторінці, 500 сторінок на запит.
- Вікна дат виходу в discover, щоб розбити перше завантаження та показувати нові прем'єри.
- Пошук за зовнішніми id для `imdb_id`, `tvdb_id`, `wikidata_id` і `kinopoisk_id`.

## Які дані ви отримуєте

Це модель даних. Кожен рядок це одна таблиця в реляційній копії.

| Сутність      | Як читати                           | Ключ            | Зв'язки                                                                                            |
| ------------- | ----------------------------------- | --------------- | -------------------------------------------------------------------------------------------------- |
| Фільм         | `GET /3/movie/{movie_id}`           | `id`, `imdb_id` | `genres[].id`, `production_companies[].id`, `belongs_to_collection.id`                             |
| Персона       | `GET /3/person/{person_id}`         | `id`, `imdb_id` | Фільми через `/3/movie/{movie_id}/credits`                                                         |
| Компанія      | `GET /3/company/{company_id}`       | `id`            | Фільми через `with_companies` у discover. `parent_company` завжди `null`, а `description` порожній |
| Колекція      | `GET /3/collection/{collection_id}` | `id`            | `parts[]`, список фільмів                                                                          |
| Ключове слово | `GET /3/keyword/{keyword_id}`       | `id`            | Фільми через `/3/keyword/{keyword_id}/movies` або `with_keywords`                                  |
| Жанр          | `GET /3/genre/movie/list`           | `id`            | `genres[].id` у фільмах                                                                            |

Зв'язки «багато до багатьох» потребують таблиць зв'язку: `movie_genre`, `movie_company`, `movie_keyword` і `movie_credit`. Використовуйте `credit_id` зі сторінки [акторський склад і знімальна група](https://amodb.dev/uk/credits/) як ключ останньої. Списки полів на сторінках [фільми](https://amodb.dev/uk/movies/), [персони](https://amodb.dev/uk/people/) і [колекції](https://amodb.dev/uk/collections/).

## Почніть за 3 кроки

1. Порівняйте три ліміти запитів на сторінці [ціни](https://amodb.dev/uk/pricing/). Більший ліміт скорочує перше завантаження, більше нічого не змінюється.
2. Створіть ключ у кабінеті акаунта й тримайте його в змінній середовища.
3. Викличте `/3/discover/movie` для однодобового вікна дат виходу, а потім отримайте кожен id зі списку.

## Приклад запиту

Скрипт на PHP виводить фільми, що вийшли вчора й сьогодні, через discover і додає або оновлює кожен запис у таблиці SQLite. Він робить паузу 3 секунди між запитами деталей, щоб лишатися в межах 20 запитів на хвилину, повторює 429 після `Retry-After` і видаляє рядки, id яких тепер повертає 404.

```bash
curl -s "https://api.amodb.dev/3/discover/movie?primary_release_date.gte=2026-10-17&primary_release_date.lte=2026-10-18&sort_by=primary_release_date.asc&page=1" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```php
<?php
const BASE = 'https://api.amodb.dev/3';

function amodb(string $path, array $query = []): ?array
{
    $url = BASE . $path . '?' . http_build_query($query);
    for ($attempt = 0; $attempt < 3; $attempt++) {
        $retryAfter = 1;
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
            CURLOPT_HEADERFUNCTION => function ($handle, $line) use (&$retryAfter) {
                if (stripos($line, 'Retry-After:') === 0) {
                    $retryAfter = max(1, (int) trim(substr($line, 12)));
                }
                return strlen($line);
            },
        ]);
        $body = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($status === 429) {
            sleep($retryAfter);
            continue;
        }
        if ($status === 404) {
            return null;
        }
        if ($status !== 200) {
            throw new RuntimeException("amodb returned $status for $path");
        }
        return json_decode($body, true);
    }
    throw new RuntimeException("Still rate limited on $path");
}

$db = new PDO('sqlite:movies.sqlite');
$db->exec('CREATE TABLE IF NOT EXISTS movie (id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, release_date TEXT, raw TEXT)');
$save = $db->prepare('INSERT OR REPLACE INTO movie (id, imdb_id, title, release_date, raw) VALUES (?, ?, ?, ?, ?)');
$drop = $db->prepare('DELETE FROM movie WHERE id = ?');

$from = date('Y-m-d', strtotime('-1 day'));
$to = date('Y-m-d');
$page = 1;
do {
    $list = amodb('/discover/movie', [
        'primary_release_date.gte' => $from,
        'primary_release_date.lte' => $to,
        'sort_by' => 'primary_release_date.asc',
        'page' => $page,
    ]);
    foreach ($list['results'] as $row) {
        $movie = amodb('/movie/' . $row['id'], ['language' => 'en-US']);
        if ($movie === null) {
            $drop->execute([$row['id']]);
            continue;
        }
        $save->execute([$movie['id'], $movie['imdb_id'] ?? null, $movie['title'], $movie['release_date'] ?? null, json_encode($movie)]);
        sleep(3);
    }
    $page++;
} while ($page <= min($list['total_pages'], 500));
```

Discover повертає рядки списку, а не повні записи. Це 2 із 20 результатів на сторінці 1. Решту полів читайте через `/3/movie/{id}`.

```json
{
  "page": 1,
  "results": [
    {
      "adult": false,
      "backdrop_path": "/siepLRGVjM8yLKppApkD3uSh8Y0.jpg",
      "genre_ids": [
        35
      ],
      "id": 1800227,
      "original_language": "en",
      "original_title": "Sly's Pack",
      "overview": "Nesmith, Gary, & Tony are smoking weed on the roof of a parking garage, but a...",
      "popularity": 0.0071,
      "poster_path": "/3HpIWZUI7jmpKZkfZNdchS2WsvN.jpg",
      "release_date": "2026-10-17",
      "title": "Sly's Pack",
      "video": false,
      "vote_average": 0,
      "vote_count": 0
    },
    {
      "adult": false,
      "backdrop_path": null,
      "genre_ids": [
        99
      ],
      "id": 1800168,
      "original_language": "en",
      "original_title": "The Good Life",
      "overview": "The Good LIfe is based on the best-selling book by Drs. Robert Waldinger and...",
      "popularity": 0.0143,
      "poster_path": null,
      "release_date": "2026-10-17",
      "title": "The Good Life",
      "video": false,
      "vote_average": 0,
      "vote_count": 0
    }
  ],
  "total_pages": 15,
  "total_results": 299
}
```

## Заповнення та оновлення таблиць

| Завдання               | Запит                                                                                                                   | Обмеження                                                                                                                              |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Перше завантаження     | `GET /3/discover/movie` з `sort_by` і вікном дат                                                                        | `page` від 1 до 500, до 20 результатів на сторінці, тож 10,000 на запит. Діліть за `primary_release_date.gte` і `.lte`, щоб піти далі. |
| Нові прем'єри          | `GET /3/discover/movie` з `primary_release_date.gte`, встановленим на час останнього запуску, і `GET /3/movie/upcoming` | Кеш 30 хвилин.                                                                                                                         |
| Оновлення рядків       | `GET /3/movie/{movie_id}` для рядків старших за 6 годин                                                                 | Стрічки змін немає. Оновлюйте тайтли, які відкривають користувачі, а решту рідше.                                                      |
| Зіставлення власних id | `GET /3/find/{external_id}`                                                                                             | Один id на запит, джерело вибирається через `external_source`.                                                                         |
| Ліниве заповнення      | `GET /3/movie/{movie_id}`, коли користувач відкриває тайтл                                                              | Зберігайте відповідь із міткою часу.                                                                                                   |

Вікно сторінок це головне архітектурне рішення. Коли `total_pages` у відповіді більше за 500, вікно містить понад 10,000 рядків, тож діліть його навпіл, доки воно не вміститься. Для недавнього року потрібні місяці, а один день прем'єр це кілька сотень тайтлів. Зберігайте завершений відрізок, щоб перерваний запуск міг продовжитися. Правила зіставлення для поєднання на сторінці [пошук за зовнішнім ID](https://amodb.dev/uk/find-by-external-id/).

## Планування синхронізації

Кожен рядок, який ви оновлюєте, коштує один запит деталей. Тариф з 20 запитами на хвилину дає 1,200 викликів на годину, 40 дає 2,400, а 120 дає 7,200. Сторінка discover перелічує 20 id за один запит. Запускайте оновлення в непіковий час, якщо ваш застосунок ділить ключ, бо ліміт діє на ключ, а не на скрипт. Заголовки, що показують залишок у вікні, описано на сторінці [ліміти запитів](https://amodb.dev/uk/rate-limits/).

## Кешування у два шари

| Шар          | Що містить                                   | TTL                                                                                  |
| ------------ | -------------------------------------------- | ------------------------------------------------------------------------------------ |
| Edge-кеш     | Деталі й акторський склад та знімальна група | 6 годин                                                                              |
| Edge-кеш     | Списки discover, трендів і популярних        | 30 хвилин                                                                            |
| Edge-кеш     | Пошук                                        | 10 хвилин                                                                            |
| Edge-кеш     | Конфігурація                                 | 24 години                                                                            |
| Edge-кеш     | Зображення                                   | 30 днів                                                                              |
| Ваші таблиці | Рядки, які ви зберігаєте                     | Доки ваше правило віку не вимагатиме повторного запиту, але не раніше ніж за 6 годин |

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

## Порівняння

| Можливість               | Скрапінг сторінок власноруч            | Статичні файли датасетів                        | amodb                                                 |
| ------------------------ | -------------------------------------- | ----------------------------------------------- | ----------------------------------------------------- |
| Свіжість                 | Настільки свіжа, як ваш останній обхід | Настільки свіжа, як останній опублікований файл | Деталі кешуються на 6 годин, повторний запит за віком |
| Інкрементальні оновлення | Повторний обхід і порівняння           | Завантаження нового файлу                       | Discover із вікном дат виходу, без стрічки змін       |
| Id між сутностями        | URL сторінок                           | Визначає видавець                               | Числові id, `imdb_id` і `/3/find`                     |
| Що ви запускаєте         | Краулери й сховище                     | Сховище та завдання імпорту                     | Сховище та скрипт синхронізації                       |
| Ліміт запитів            | Визначають сайти, які ви обходите      | Не застосовується                               | 20, 40 або 120 запитів на хвилину, рахуються на ключ  |
| Мови на запис            | Те, що пропонує кожна сторінка         | Залежить від файлів                             | 14, вибираються через `language`                      |

## Ціни

Перше завантаження найвитратніше, і воно обмежене вашим лімітом запитів на хвилину. Оберіть 20, 40 або 120 на хвилину на сторінці [ціни](https://amodb.dev/uk/pricing/). Платіть за 1, 3, 6, 12 або 24 місяці зі знижками 0, 10, 20, 30 або 40 відсотків. Нічого не поновлюється автоматично, безкоштовного тарифу немає, і кожен тариф читає ті самі дані.

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

### Як тримати локальну копію свіжою?

У amodb немає стрічки змін, тож оновлюйте за віком. Деталі кешуються на периферії на 6 годин, тому не запитуйте рядок раніше. Нові прем'єри підхоплюйте через discover з primary_release_date.gte, встановленим на час останнього запуску.

### Як завантажити першу копію?

Обійдіть /3/discover/movie зі сторінками від 1 до 500 (до 20 результатів на кожній, тобто 10,000 на запит) і діліть за вікнами primary_release_date, щоб піти далі. Лише березень 2025 містить близько 4,400 тайтлів. Потім прочитайте /3/movie/{id} для кожного id, який ви залишаєте.

### Скільки триває перше завантаження при моєму ліміті запитів?

При 20 запитах на хвилину можна зробити 1,200 викликів на годину, при 40 це 2,400, а при 120 це 7,200. Поділіть кількість потрібних запитів деталей на це число, щоб спланувати запуск.

### Чи можна поєднати id amodb з id, які я вже зберігаю?

Так. /3/find/{external_id} приймає imdb_id, tvdb_id, wikidata_id і kinopoisk_id та повертає відповідний запис amodb. Записи фільмів також містять imdb_id, тож поєднання працює в обидва боки.

### Чи є безкоштовний тариф для побудови бази?

Ні. Доступ передплачується на 1, 3, 6, 12 або 24 місяці й не поновлюється сам. Усі тарифи читають ті самі дані, тож більший тариф лише пришвидшує перше завантаження й оновлення.

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

- [API деталей фільму](https://amodb.dev/uk/movies/): API деталей фільму з тими самими шляхами та JSON, що в TMDB v3. Отримайте фільм за id, додайте акторів, рейтинги й настрої через append_to_response, 14 мовами.
- [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/companies-networks/): Дані про кінокомпанії та телемережі зі шляхами TMDB v3. Отримайте назву, країну й логотип за id, а потім відфільтруйте discover за id компанії чи мережі.
- [Пошук за зовнішнім ID](https://amodb.dev/uk/find-by-external-id/): Знайдіть фільм, серіал чи персону за id IMDb, TVDB, Wikidata або Kinopoisk через find TMDB, а також прочитайте зовнішні id і факти Wikidata про проєкт.
- [Ліміти запитів](https://amodb.dev/uk/rate-limits/): amodb обмежує кожен ключ запитами на хвилину в ковзному вікні 60 секунд: 20, 40 або 120 за тарифом. Читайте заголовки ліміту й обробляйте 429 із Retry-After.

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