# kinodata API > kinodata связывает ID фильмов и сериалов в IMDb, Кинопоиске, TMDB и Кинориуме и по этой связке отдаёт данные тайтла: названия на русском и английском, оценки каждого источника, состав, медиа, связи, фильмографии, подборки и календарь релизов. - Базовый адрес — `https://api.kinodata.space/v1.3`. Все запросы — `GET`, ключ — в заголовке `X-API-Key`. - Успешный ответ — сами данные без обёртки. Ошибка — `{"error": {"code", "message", "field", "allowed", "hint"}}` и статус 4xx или 5xx. Ветвитесь по `error.code`. - Текстовые поля приходят парами `_ru` и `_en`. `lang=ru` или `lang=en` оставляет одну половину. Нет перевода — `null`, без подстановки. - Неизвестный параметр или значение — `400` со списком допустимых в `allowed` и подсказкой в `hint`. Не придумывайте параметры: берите их из справочника ниже. - Каждая страница документации доступна в Markdown: добавьте `.md` к её адресу. --- # Введение > Что умеет kinodata API, базовый адрес и формат ответов. > https://kinodata.space/ru/docs.md kinodata связывает ID фильмов и сериалов в IMDb, Кинопоиске, TMDB и Кинориуме. По этой связке API отдаёт данные тайтла: названия на русском и английском, рейтинги каждого источника, состав, кадры и трейлеры, связи между тайтлами, фильмографии и подборки. ## Один фильм — пять ID У «Начала» в каждом каталоге свой ID, и сами числа не говорят, что это один фильм: | каталог | тип в пути | ID | |---|---|---| | IMDb | `imdb` | `tt1375666` | | Кинопоиск | `kp` | `447301` | | TMDB, фильмы | `tmdb` | `27205` | | TMDB, сериалы | `tmdb_tv` | — | | Кинориум | `kinorium` | `472809` | Любой ID открывает тот же тайтл: `/titles/imdb/tt1375666`, `/titles/kp/447301` и `/titles/tmdb/27205` возвращают одинаковую карточку. Берите тот ID, который уже есть в вашей базе. ## Базовый адрес ```text https://api.kinodata.space/v1.3 ``` Пути в справочнике указаны от него: `/ids/kp/447301` — это `https://api.kinodata.space/v1.3/ids/kp/447301`. Все запросы — `GET` по HTTPS, ключ передаётся в заголовке `X-API-Key`. ## Формат ответа JSON в UTF-8. Успешный ответ — сами данные, без обёртки. Ошибка — объект `error` и статус 4xx или 5xx: ```json { "error": { "code": "not_found", "message": "title not found: kp 999999999" } } ``` Успех от ошибки отличайте по статусу HTTP, а не по форме тела. Подробно — на странице [Ошибки](https://kinodata.space/ru/docs/errors.md). ## Языки Текстовые поля приходят парами: `title_ru` и `title_en`, `name_ru` и `name_en`. Язык всегда виден из имени поля. Параметр `lang=ru` или `lang=en` оставляет в ответе один язык, имена полей при этом не меняются. Если перевода нет, поле равно `null`: подставить другой язык или оригинальное название решаете вы. ## Ключ — только на сервере Ключ даёт доступ к API от вашего имени. Держите его на сервере или в переменной окружения. В коде сайта и мобильного приложения его увидит любой, кто откроет инструменты разработчика. ## Дальше - [Быстрый старт](https://kinodata.space/ru/docs/quickstart.md) — первый запрос за пять минут. - [Языки ответа](https://kinodata.space/ru/docs/languages.md) — как устроены поля `_ru` и `_en`. - [ID во всех каталогах](https://kinodata.space/ru/docs/ids.md) — самый простой эндпоинт. --- # Быстрый старт > Ключ, первый запрос, карточка тайтла и поиск — за пять минут. > https://kinodata.space/ru/docs/quickstart.md За пять минут вы получите ключ, свяжете ID одного фильма во всех каталогах, откроете его карточку и найдёте тайтл по названию. Понадобится терминал с `curl` или любой язык из примеров. ## Получите ключ Ключ бесплатный, в него входит 500 запросов в сутки. [Как получить ключ](https://kinodata.space/ru/pricing). Сохраните ключ в переменную окружения: все примеры документации берут его оттуда, и в код он не попадает. macOS и Linux: ```bash export KINODATA_KEY="ваш_ключ" ``` Windows, PowerShell: ```powershell $env:KINODATA_KEY = "ваш_ключ" ``` ## Свяжите ID фильма Передайте ID «Начала» на Кинопоиске — в ответ придут его ID во всех каталогах: ```bash curl -H "X-API-Key: $KINODATA_KEY" \ "https://api.kinodata.space/v1.3/ids/kp/447301" ``` Ответ `200`: ```json { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809" } ``` Где: - `kp` — каталог, из которого ID. Подходит любой из пяти: `imdb`, `kp`, `tmdb`, `tmdb_tv`, `kinorium`. - `447301` — ID в этом каталоге. - `null` — ID в этом каталоге нет. «Начало» — фильм, поэтому `tmdb_tv_id` пуст. ## Откройте карточку Тот же ID открывает карточку тайтла. Параметр `fields` оставляет нужные блоки, здесь — названия и вид: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "fields=title,type" \ "https://api.kinodata.space/v1.3/titles/kp/447301" ``` Ответ `200`: ```json { "ids": { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809", "urls": { "imdb": "https://www.imdb.com/title/tt1375666/", "kinorium": "https://ru.kinorium.com/472809/", "kp": "https://www.kinopoisk.ru/film/447301/", "tmdb": "https://www.themoviedb.org/movie/27205" } }, "title": { "title_ru": "Начало", "title_en": "Inception", "title_original": "Inception" }, "type": { "kind": "movie", "is_series": false, "status": "released", "kind_label_ru": "Фильм", "kind_label_en": "Movie", "status_label_ru": "Вышел", "status_label_en": "Released" } } ``` Блок `ids` приходит всегда. Без `fields` карточка приходит целиком: до 22 блоков, около 26 КБ. Текстовые поля приходят парами `_ru` и `_en`. Чтобы получить один язык, добавьте `lang=ru` или `lang=en`. ## Найдите тайтл по названию Если ID нет, ищите по названию на любом языке. Поиск прощает опечатки — запрос «начло» с пропущенной буквой находит «Начало»: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "q=начло" \ --data-urlencode "limit=1" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809", "title_ru": "Начало", "title_en": "Inception", "title_original": "Inception", "year": 2010, "release_date": "2010-07-15", "kind": "movie", "poster_url_ru": "https://avatars.mds.yandex.net/get-kinopoisk-image/1629390/8ab9a119-dd74-44f0-baec-0629797483d7/600x900", "poster_url_en": "https://image.tmdb.org/t/p/original/xlaY2zyzMfkhk0HSC5VUwzoZPU1.jpg", "posters_by_source": { "kp": "https://avatars.mds.yandex.net/get-kinopoisk-image/1629390/8ab9a119-dd74-44f0-baec-0629797483d7/600x900", "tmdb": "https://image.tmdb.org/t/p/original/piQXcdOGgv1O9HQ07pI0tnjkGJw.jpg", "imdb": null, "kinorium": "https://images.kinorium.com/movie/poster/472809/w1500_37543056.jpg" }, "rating_kp": 8.7, "rating_tmdb": 8.4, "rating_imdb": 8.8, "rating_kr": 8.6, "rating_letterboxd": 8.4, "votes_kp": 1132562, "votes_tmdb": 40402, "votes_imdb": 2877173, "countries": [ { "code": "us", "name_ru": "США", "name_en": "United States" }, { "code": "gb", "name_ru": "Великобритания", "name_en": "United Kingdom" } ], "genres": [ { "slug": "action", "name_ru": "Боевик", "name_en": "Action" }, { "slug": "drama", "name_ru": "Драма", "name_en": "Drama" }, { "slug": "mystery", "name_ru": "Детектив", "name_en": "Mystery" }, { "slug": "speculative_fiction", "name_ru": "Фантастика", "name_en": "Speculative Fiction" }, { "slug": "thriller", "name_ru": "Триллер", "name_en": "Thriller" } ] } ], "limit": 1, "offset": 0, "total": null } ``` `has_more: true` значит, что результатов больше. Следующую страницу отдаёт параметр `offset`. ## Дальше - [Ключ и лимиты](https://kinodata.space/ru/docs/keys.md) — пределы тарифа и как следить за остатком. - [Карточка тайтла](https://kinodata.space/ru/docs/titles/card.md) — все блоки карточки. - [Фильтры и сортировка](https://kinodata.space/ru/docs/filters.md) — как выбрать тайтлы из каталога. --- # Подключить к ИИ > MCP-сервер kinodata: настройки для Claude, Claude Code, Cursor и VS Code, инструменты и расход квоты. > https://kinodata.space/ru/docs/mcp.md Подключите kinodata к Claude, Cursor или VS Code — и ассистент сам найдёт фильм, свяжет его ID во всех каталогах и откроет карточку, когда это понадобится в разговоре или в коде. Для этого у API есть MCP-сервер: он работает по открытому протоколу Model Context Protocol, через который ИИ-ассистенты вызывают внешние инструменты. Адрес сервера: ```text https://api.kinodata.space/mcp ``` MCP-сервер есть на всех тарифах, включая Free. Ключ тот же, что для API, — из личного кабинета. ## Как считаются запросы Каждый инструмент сервера делает обычные запросы к API v1.3 с вашим ключом. Поэтому квота, пределы и статистика в кабинете у API и MCP общие: - большинство инструментов стоят один запрос; - `resolve_ids` — по запросу на каждый ID и ещё один на всю пачку; - `get_person` — два запроса: карточка и первая страница фильмографии; - подключение и список инструментов квоту не тратят. Предел в секунду сервер соблюдает сам: запросы аккаунта идут не чаще, чем разрешает тариф, — со всех его ключей, из одного вызова и из нескольких сразу. Поэтому `resolve_ids` на 50 ID на Free (10 запросов в секунду) займёт около пяти секунд, но не оборвётся на середине. Когда квота на сутки кончается, инструмент отвечает текстом: сколько запросов было и когда квота обновится. Ассистент перескажет это сам. Пределы тарифов — на странице [Ключ и лимиты](https://kinodata.space/ru/docs/keys.md). ## Подключите клиент Сервер принимает ключ в заголовке `Authorization: Bearer <ключ>` или, как API, в `X-API-Key`. Ниже — настройки для каждого клиента; ключ в них берётся из переменной окружения `KINODATA_KEY`, как в [Быстром старте](https://kinodata.space/ru/docs/quickstart.md). ### Claude Code macOS и Linux: ```bash claude mcp add --transport http kinodata https://api.kinodata.space/mcp --scope user --header "Authorization: Bearer $KINODATA_KEY" ``` Windows, PowerShell: ```powershell claude mcp add --transport http kinodata https://api.kinodata.space/mcp --scope user --header "Authorization: Bearer $env:KINODATA_KEY" ``` Где: - `kinodata` — имя сервера в Claude Code. - `--scope user` — сервер доступен во всех ваших проектах и не попадает в файлы проекта. Проверьте подключение командой `/mcp` в Claude Code. ### Cursor Откройте файл `~/.cursor/mcp.json` и добавьте сервер: ```json { "mcpServers": { "kinodata": { "url": "https://api.kinodata.space/mcp", "headers": { "Authorization": "Bearer ${env:KINODATA_KEY}" } } } } ``` Cursor подставит ключ из переменной окружения `KINODATA_KEY`. Переменная должна быть видна самому Cursor: задайте её в системе, а не только в открытом терминале. ### VS Code Выполните команду **MCP: Open User Configuration** и добавьте в открывшийся `mcp.json`: ```json { "inputs": [ { "type": "promptString", "id": "kinodata-key", "description": "Ключ kinodata API", "password": true } ], "servers": { "kinodata": { "type": "http", "url": "https://api.kinodata.space/mcp", "headers": { "Authorization": "Bearer ${input:kinodata-key}" } } } } ``` VS Code спросит ключ при первом запуске сервера, в файле он не хранится. ### Claude В claude.ai и приложении Claude сервер подключается как свой коннектор: 1. Откройте **Customize → Connectors** и нажмите **Add custom connector**. 2. В поле адреса введите `https://api.kinodata.space/mcp`. 3. В **Authentication** выберите **No sign-in**. 4. В **Request headers** добавьте `authorization` со значением `Bearer ` и ваш ключ — целиком, со словом `Bearer` и пробелом. Раздел **Request headers** пока в бета-версии и виден не во всех аккаунтах. Если его нет, подключите сервер в Claude Code или в приложении Claude через мост `mcp-remote` (нужен Node.js). Файл `claude_desktop_config.json`: ```json { "mcpServers": { "kinodata": { "command": "npx", "args": ["-y", "mcp-remote", "https://api.kinodata.space/mcp", "--header", "Authorization:${AUTH_HEADER}"], "env": { "AUTH_HEADER": "Bearer ваш_ключ" } } } } ``` Пробелов вокруг двоеточия в `args` нет намеренно: на Windows приложение не экранирует пробелы в аргументах, и заголовок ломается. Пробел внутри `AUTH_HEADER` можно. ### ChatGPT ChatGPT пока не подключить: он не передаёт ключ в заголовке, а входа по OAuth у сервера нет. ## Инструменты | инструмент | что делает | |---|---| | `resolve_ids` | ID тайтлов во всех каталогах — до 50 ID за раз. | | `search_titles` | Фильмы и сериалы по названию на русском или английском, с опечатками. | | `get_title` | Карточка тайтла: названия, год, жанры, страны, оценки, описание, режиссёры и главные роли. | | `get_title_section` | Длинный раздел тайтла по страницам: актёры, съёмочная группа, награды, эпизоды, факты, цитаты, медиа, сайты, теги. | | `find_titles` | Тайтлы по условиям каталога: вид, жанры, страны, годы, оценка и число голосов, тег Кинориума, пресеты. | | `get_related_titles` | Похожие тайтлы и франшиза. | | `search_persons` | Актёры, режиссёры и другие люди кино по имени. | | `get_person` | Карточка человека: даты, возраст, рост, семья с полом родственников, награды по церемониям, факты, ссылки — каталоги, Википедия, Wikidata, сайт и соцсети, — и фильмография по страницам. | | `get_collection` | Подборки: их список или тайтлы одной подборки, например `daily-trending-titles` — в тренде сегодня. | Ответы компактные: пустые поля сервер не присылает, длинные списки отдаёт страницами. ## Что спросить - «Дай ID на Кинопоиске для tt0111161, tt0068646 и tt0468569». - «Корейские триллеры 2010-х с оценкой Кинопоиска выше 7,5». - «Кто снял „Сталкера“ и что ещё он снял после 1970 года?» - «Что сейчас в тренде и есть ли там аниме?» - «Сколько сезонов и эпизодов у „Во все тяжкие“?» ## Берегите ключ - Храните ключ в пользовательских настройках клиента или в переменной окружения. Не кладите его в `mcp.json` проекта, который уходит в репозиторий, и не вставляйте в чат с ассистентом. - Ключ передаётся только в заголовке. Адрес с ключом в строке запроса сервер отклоняет. - Описания и факты из каталогов — чужие тексты. Сервер убирает из них ссылки, картинки и HTML, но если ассистент вдруг предлагает действие «из описания фильма», не соглашайтесь. ## Если не подключается | ответ | когда | что делать | |---|---|---| | `401` | Ключа нет, он неверный или отозван. | Проверьте заголовок: `Authorization: Bearer` и ключ из кабинета целиком. | | `400` | Ключ передан в адресе. | Уберите его из адреса и передайте в заголовке. | | `429` | С вашего адреса за минуту пришло 30 запросов с неверным ключом. | Подождите минуту и проверьте ключ. | ## Дальше - [Ключ и лимиты](https://kinodata.space/ru/docs/keys.md) — пределы тарифов и как следить за остатком. - [ID во всех каталогах](https://kinodata.space/ru/docs/ids.md) — на этом эндпоинте работает `resolve_ids`. --- # Ключ и лимиты > Как передать ключ, пределы тарифов, заголовки остатка и как экономить запросы. > https://kinodata.space/ru/docs/keys.md Каждый запрос передаёт ключ в заголовке `X-API-Key`. Считаются два предела: запросы в секунду и запросы в сутки. На этой странице — как передать ключ, как следить за остатком и как не тратить запросы впустую. ## Передайте ключ Ключ идёт в заголовке `X-API-Key` каждого запроса. Во всех примерах документации он берётся из переменной окружения `KINODATA_KEY`: ```bash curl -H "X-API-Key: $KINODATA_KEY" \ "https://api.kinodata.space/v1.3/ids/kp/447301" ``` Ответ `200`: ```json { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809" } ``` Без ключа или с неверным ключом API отвечает `401`. Тот же запрос без заголовка: ```bash curl -s "https://api.kinodata.space/v1.3/ids/kp/447301" ``` Ответ `401`: ```json { "error": { "code": "unauthorized", "message": "missing api key" } } ``` Без ключа отвечает только `https://api.kinodata.space/health` — проверка, что API работает. ## Пределы тарифов | тариф | запросов в секунду | запросов в сутки | |---|---|---| | Free | 10 | 500 | | Basic | 20 | 5 000 | | Business | 40 | без предела при добросовестном использовании | На Basic и Business можно выпустить два ключа. Пределы при этом — на аккаунт, а не на ключ: два ключа Basic делят одни 20 запросов в секунду и 5 000 в сутки, а не получают столько каждый. Сутки считаются по UTC: квота обновляется в полночь по UTC, а не через 24 часа после первого запроса. Тарифы и цены — на странице [Тарифы](https://kinodata.space/ru/pricing). ## Следите за остатком С каждым ответом приходят заголовки с текущим остатком: | заголовок | что это | |---|---| | `X-RateLimit-Limit` | Сколько запросов разрешено в секунду. | | `X-RateLimit-Remaining` | Сколько осталось в текущей секунде. | | `X-RateLimit-Reset` | Когда начнётся следующая секунда, Unix-время. | | `X-Quota-Limit` | Сколько запросов разрешено в сутки. | | `X-Quota-Remaining` | Сколько осталось на сегодня. | | `X-Quota-Reset` | Когда квота обновится, Unix-время: ближайшая полночь по UTC. | | `Retry-After` | Только в ответе `429`: через сколько секунд повторить запрос. | Так выглядят заголовки ключа Basic: ```text X-RateLimit-Limit: 20 X-RateLimit-Remaining: 19 X-RateLimit-Reset: 1791566201 X-Quota-Limit: 5000 X-Quota-Remaining: 4812 X-Quota-Reset: 1791590400 ``` У ключа без предела соответствующих заголовков нет. Из браузера они тоже видны: API открывает их в `Access-Control-Expose-Headers`. ## Если упёрлись в предел API отвечает `429`. Текст ошибки говорит, какой предел сработал: ```json { "error": { "code": "rate_limited", "message": "quota limit exceeded" } } ``` - `rate limit exceeded` — запросов в этой секунде больше, чем разрешено. Подождите `Retry-After` секунд и разнесите запросы во времени: очередь или пауза между запросами помогут лучше повторов. - `quota limit exceeded` — квота на сутки закончилась. `Retry-After` покажет, сколько секунд до полуночи по UTC. Если квоты не хватает регулярно, посмотрите [тарифы](https://kinodata.space/ru/pricing). Запрос, отклонённый пределом в секунду, квоту на сутки не тратит. ## Экономьте запросы ### Берите только нужные блоки Карточка тайтла целиком весит около 26 КБ. Если нужны название и оценки, попросите только их: `fields=title,ratings`. Ответ станет меньше, а запрос — дешевле для вашей сети. Подробнее — в разделе [Списки и пагинация](https://kinodata.space/ru/docs/lists.md#только-нужные-поля). ### Кэшируйте ответы Ответ можно хранить пять минут: API присылает `Cache-Control: private, max-age=300`. Хранить его может ваш сервер или браузер, но не общий кэш вроде CDN: ответ принадлежит ключу. Чтобы проверить, изменились ли данные, не скачивая их заново, используйте условный запрос. 1. Сохраните заголовок `ETag` из ответа — здесь в переменную `ETAG`: ```bash ETAG=$(curl -sI -H "X-API-Key: $KINODATA_KEY" "https://api.kinodata.space/v1.3/titles/tmdb/27205" | grep -i '^etag:' | cut -d' ' -f2 | tr -d '\r') ``` 2. В следующем запросе к тому же адресу передайте его в `If-None-Match` как есть, вместе с кавычками: ```bash curl -s -o /dev/null -w '%{http_code}\n' -H "X-API-Key: $KINODATA_KEY" -H "If-None-Match: $ETAG" "https://api.kinodata.space/v1.3/titles/tmdb/27205" ``` Если данные не изменились, придёт `304` без тела — значит, сохранённый ответ ещё верен. Ответ `304` не тратит квоту: проверять свежесть данных так можно сколько угодно часто. ### Включите сжатие С заголовком `Accept-Encoding: gzip` карточка «Начала» весит 8 КБ вместо 26 КБ. Большинство HTTP-клиентов просят сжатие сами. curl — только с флагом `--compressed`. ## Храните ключ на сервере API отвечает на запросы из браузера с любого сайта, но ключ в коде страницы или мобильного приложения увидит любой, кто откроет инструменты разработчика. Отправляйте запросы со своего сервера, а в браузер отдавайте готовые данные. ## Если что-то не так С каждым ответом приходят два служебных заголовка: | заголовок | что это | |---|---| | `X-Request-Id` | ID запроса. Приложите его к обращению — по нему мы найдём запрос. | | `X-API-Version` | Версия API, которая ответила: `1.3`. | ## Дальше - [Ошибки](https://kinodata.space/ru/docs/errors.md) — все коды и что с ними делать. - [Списки и пагинация](https://kinodata.space/ru/docs/lists.md) — как листать длинные ответы. --- # Языки ответа > Язык в имени поля, параметр lang и что пока есть только на одном языке. > https://kinodata.space/ru/docs/languages.md API отдаёт тексты на русском и английском. Язык каждого текстового поля указан в его имени, а параметр `lang` оставляет в ответе один язык. ## Язык в имени поля Каждое текстовое поле заканчивается на `_ru` или `_en`: `title_ru`, `kind_label_en`, `name_ru`. Без `lang` приходят обе половины: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "fields=title,type" \ "https://api.kinodata.space/v1.3/titles/kp/447301" ``` Ответ `200`: ```json { "ids": { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809", "urls": { "imdb": "https://www.imdb.com/title/tt1375666/", "kinorium": "https://ru.kinorium.com/472809/", "kp": "https://www.kinopoisk.ru/film/447301/", "tmdb": "https://www.themoviedb.org/movie/27205" } }, "title": { "title_ru": "Начало", "title_en": "Inception", "title_original": "Inception" }, "type": { "kind": "movie", "is_series": false, "status": "released", "kind_label_ru": "Фильм", "kind_label_en": "Movie", "status_label_ru": "Вышел", "status_label_en": "Released" } } ``` Имена полей не меняются никогда: `title_en` — всегда английское название, в любом ответе и с любым `lang`. Разбирайте ответ по именам полей, а не по языку запроса. ## Один язык: lang `lang=ru` оставляет поля `_ru`, `lang=en` — поля `_en`. Остальные поля ответа не меняются. ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "fields=title,type" \ --data-urlencode "lang=en" \ "https://api.kinodata.space/v1.3/titles/kp/447301" ``` Ответ `200`: ```json { "ids": { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809", "urls": { "imdb": "https://www.imdb.com/title/tt1375666/", "kinorium": "https://en.kinorium.com/472809/", "kp": "https://www.kinopoisk.ru/film/447301/", "tmdb": "https://www.themoviedb.org/movie/27205" } }, "title": { "title_en": "Inception", "title_original": "Inception" }, "type": { "kind": "movie", "is_series": false, "status": "released", "kind_label_en": "Movie", "status_label_en": "Released" } } ``` `lang` принимает только `ru` и `en`. Другое значение — ошибка `400`. Передавать `lang` можно в любой запрос: там, где текстов нет (`/ids`, `/meta/stats`), он ничего не меняет. ## Перевода нет — null Если текста на нужном языке нет, поле равно `null`. API не подставляет вместо него другой язык или оригинал: что показать, решаете вы. Для названия разумно взять `title_original`, для описания — текст на другом языке с пометкой. ## Что не зависит от языка Поля без суффикса одинаковы на любом языке: ID, `slug`, `kind`, коды стран, даты, числа, `title_original`, названия компаний. Суффикс `_ru` в фильтрах дат означает регион, а не язык: `premiere_ru` — премьера в России. ## Что сейчас есть только на одном языке На обоих языках приходят названия, описания, жанры, страны, метки настроения и ключевые слова, церемонии и номинации наград, подборки и подписи всех перечислений. Пока на одном языке: | что | язык | что видно в ответе | |---|---|---| | Факты, вопросы и цитаты — `/titles/{type}/{id}/texts` | русский | `text_en` равно `null` | | Биография и место рождения человека — [карточка человека](https://kinodata.space/ru/docs/persons/card.md) | английский, из TMDB; русская биография — у единиц | `biography_ru` и `birthplace_ru` почти всегда `null` | | Сводка наград | два разных текста: `summary_kinorium_ru` от Кинориума и `summary_imdb_en` от IMDb | это не перевод друг друга | | Название франшизы — `franchise.name` | английский | поле пока без суффикса | Факты с `lang=en` приходят без текста — так видно, что перевода ещё нет: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "kind=fact" \ --data-urlencode "limit=1" \ --data-urlencode "lang=en" \ "https://api.kinodata.space/v1.3/titles/kp/447301/texts" ``` Ответ `200`: ```json { "counts": { "fact": 37, "faq": 16, "quote": 5 }, "has_more": true, "items": [ { "fact_kind": "general", "is_spoiler": false, "kind": "fact", "ord": 0, "text_en": null } ], "limit": 1, "offset": 0, "total": 37 } ``` Когда перевод появится, он придёт в `*_en`, а ваш код менять не придётся. ## Английские названия и постеры - `title_en` — только настоящее английское название. Оригинальное название неанглоязычного фильма или транслитерация туда не попадают: тогда `title_en` равно `null`, а название на языке оригинала лежит в `title_original`. - `poster_url_en` — постер с надписями на английском. Если такого нет — `null`. `poster_url_ru` — постер для русской витрины. - Ссылки на Кинориум с `lang=en` ведут на английскую версию сайта, `en.kinorium.com`. ## Дальше - [Списки и пагинация](https://kinodata.space/ru/docs/lists.md) — как устроены все списки API. - [ID во всех каталогах](https://kinodata.space/ru/docs/ids.md) — связка ID одного тайтла. --- # Списки и пагинация > Форма любого списка, страницы и курсор, разделы и выбор полей. > https://kinodata.space/ru/docs/lists.md Все списки API устроены одинаково: каталог и поиск, чарты, подборки, состав, медиа, фильмография. Разобрав форму один раз, вы прочитаете любой список. ## Форма списка ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "q=матрица" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,year,rating_imdb" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt0133093", "kp_id": "301", "tmdb_id": "603", "tmdb_tv_id": null, "kinorium_id": "116780", "title_ru": "Матрица", "title_en": "The Matrix", "year": 1999, "rating_imdb": 8.7 }, { "imdb_id": "tt0234215", "kp_id": "299", "tmdb_id": "604", "tmdb_tv_id": null, "kinorium_id": "190315", "title_ru": "Матрица: Перезагрузка", "title_en": "The Matrix Reloaded", "year": 2003, "rating_imdb": 7.2 }, { "imdb_id": "tt0242653", "kp_id": "316", "tmdb_id": "605", "tmdb_tv_id": null, "kinorium_id": "196883", "title_ru": "Матрица: Революция", "title_en": "The Matrix Revolutions", "year": 2003, "rating_imdb": 6.7 } ], "limit": 3, "offset": 0, "total": null } ``` | поле | что это | |---|---| | `items` | Элементы списка. | | `total` | Сколько элементов всего. `null`, если API их не считает — об этом ниже. | | `limit` | Сколько элементов на странице. Если вы попросили больше, чем можно, здесь будет настоящее число. | | `offset` | Сколько элементов пропущено от начала. | | `has_more` | Есть ли следующая страница. | | `next_cursor` | Курсор следующей страницы. Только когда вы листаете курсором. | Поля самого ресурса приходят рядом: `roles` у состава и фильмографии, `counts` у связей и текстов, `collection` у подборки. ## Когда total равен null Список бывает двух видов. - **Набор задан адресом**: состав тайтла, его связи и медиа, фильмография человека, подборка. Такой набор конечен, и `total` — число. - **Набор задан запросом**: каталог и поиск, топ, скрытые жемчужины, поиск людей. Здесь `total: null`: точный подсчёт по фильтру — второй проход по всей базе на каждой странице. Чтобы понять, есть ли ещё, смотрите на `has_more`. Расхождения оценок и календарь релизов считают `total` и с фильтрами. ## Сколько элементов на странице | список | по умолчанию | максимум | |---|---|---| | Каталог и поиск, чарты, витрины, календарь релизов, подборки, поиск людей | 50 | 50 | | Состав, медиа, тексты, связи, серии, фильмография, совместные работы | 1000 | 1000 | | Разделы, когда список разбит на них | 10 в разделе | 50 в разделе | Набор, заданный адресом, приходит целиком: это и есть ответ. Набор, заданный запросом, отсортирован, и на странице приходит его начало. `limit` — целое число от 1, `offset` — от 0. Число больше максимума не ошибка: API уменьшит его и вернёт настоящее значение в `limit`. `limit=5000` в каталоге даст `"limit": 50`. Ноль, отрицательное число или не число — ошибка `400`. ## Страницы: offset ```text ?limit=50&offset=100 ``` `offset` — сколько элементов пропустить. Следующая страница — `offset` плюс `limit`, пока `has_more` равно `true`. ## Глубокая прокрутка: cursor Для долгого листания каталога `/titles` берите курсор: он не сбивается, если база меняется, пока вы листаете. Передайте пустой `cursor=` — в ответе появится `next_cursor`: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "sort=-rating_imdb" \ --data-urlencode "votes_imdb.gte=100000" \ --data-urlencode "limit=2" \ --data-urlencode "fields=title,rating_imdb" \ --data-urlencode "cursor=" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt0903747", "kp_id": "404900", "tmdb_id": null, "tmdb_tv_id": "1396", "kinorium_id": "400796", "title_ru": "Во все тяжкие", "title_en": "Breaking Bad", "rating_imdb": 9.5 }, { "imdb_id": "tt5491994", "kp_id": "1007472", "tmdb_id": null, "tmdb_tv_id": "68595", "kinorium_id": "1605088", "title_ru": "Планета Земля 2", "title_en": "Planet Earth II", "rating_imdb": 9.4 } ], "limit": 2, "next_cursor": "eyJzIjoicmF0aW5nX2ltZGIiLCJkIjp0cnVlLCJ2IjoiOS40MCIsImlkIjoyMjA4MDF9", "total": null } ``` Передавайте `next_cursor` в следующий запрос с теми же параметрами, пока он не станет `null`. Курсор работает в каталоге `/titles` и в витринах, которые на нём построены, — топе и скрытых жемчужинах. Остальные списки листаются `offset`, а на `cursor` отвечают `400`. С `sort=random` листать нельзя: у случайного порядка нет следующей страницы. `cursor` и `offset` с ним дают `400` — просто повторите запрос, чтобы получить новую выборку. ## Разделы Списки, элементы которых различаются по одному признаку, приходят разделами. Каждый раздел — сам список, с теми же полями и подписью на двух языках: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "limit=1" \ --data-urlencode "fields=title" \ "https://api.kinodata.space/v1.3/titles/kp/301/relations" ``` Ответ `200`: ```json { "counts": { "reference": 86, "referenced_in": 672, "related": 9, "similar": 74 }, "has_more": false, "items": [ { "has_more": true, "items": [ { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809", "title_ru": "Начало", "title_en": "Inception" } ], "label_en": "Similar", "label_ru": "Похожие", "relation": "similar", "total": 74 }, { "has_more": true, "items": [ { "imdb_id": "tt0366179", "kp_id": "63744", "tmdb_id": "24358", "tmdb_tv_id": null, "kinorium_id": null, "title_ru": "Аниматрица: Второе возрождение – Часть 1", "title_en": "The Second Renaissance Part I" } ], "label_en": "Related", "label_ru": "Связанные", "relation": "related", "total": 9 }, { "has_more": true, "items": [ { "imdb_id": "tt1431045", "kp_id": "462360", "tmdb_id": "293660", "tmdb_tv_id": null, "kinorium_id": "485426", "title_ru": "Дэдпул", "title_en": "Deadpool" } ], "label_en": "Referenced in", "label_ru": "Упоминается в", "relation": "referenced_in", "total": 672 }, { "has_more": true, "items": [ { "imdb_id": "tt0060196", "kp_id": "349", "tmdb_id": "429", "tmdb_tv_id": null, "kinorium_id": "56474", "title_ru": "Хороший, плохой, злой", "title_en": "The Good, the Bad and the Ugly" } ], "label_en": "References", "label_ru": "Отсылки к", "relation": "reference", "total": 86 } ], "limit": 1, "offset": 0, "total": 4 } ``` | список | разделы по умолчанию | другие варианты `group` | |---|---|---| | Состав `/titles/{type}/{id}/cast` | по роли: `role` | `none` | | Тексты `/titles/{type}/{id}/texts` | по виду: `kind` | `none` | | Связи `/titles/{type}/{id}/relations` | по связи: `relation` | `none` | | Медиа `/titles/{type}/{id}/media` | без разделов | `type`, `class`, `language` | | Фильмография `/persons/{type}/{id}/filmography` | без разделов | `role` | | Серии `/titles/{type}/{id}/episodes` | без разделов | `season` — сводка по сезонам | `limit` в разделённом списке относится к каждому разделу, а `total` раздела — его настоящий размер. Чтобы получить плоский список, передайте `group=none`. Чтобы листать один раздел, сузьте список до него: `role=actor`, `kind=fact`, `relation=similar`. Листать разделённый список нельзя: у разделов нет общей последовательности. `offset` без сужения даёт `400`: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "limit=2" \ --data-urlencode "offset=2" \ "https://api.kinodata.space/v1.3/titles/kp/447301/cast" ``` Ответ `400`: ```json { "error": { "code": "invalid_request", "message": "grouped lists have no single sequence to page through — narrow to one value to page inside it, or ask for group=none", "field": "offset" } } ``` ## Только нужные поля Параметр `fields` оставляет в ответе то, что вы перечислили. - **В карточке тайтла** имена — блоки карточки: `fields=title,ratings`. Можно и наоборот, убрать лишнее: `fields=-akas,-tags`. Смешивать в одном параметре нельзя: `fields=title,-akas` даёт `400`. - **В списках** имена — поля элемента списка: `fields=title,year,rating_imdb` или `fields=-genres,-countries`. `title` оставляет `title_ru` и `title_en`, `poster_url` — `poster_url_ru` и `poster_url_en`. ID тайтла приходят всегда, даже если вы их не перечислили: без них элемент не с чем связать. Поля идут в том же порядке, что и без `fields`. Неизвестное имя — `400` со списком допустимых. `fields` работает в карточке тайтла, во всех списках тайтлов — каталоге, подборке, связях, фильмографии, совместных работах, витринах и календаре — и в поиске людей. В составе, медиа, текстах и сериях его нет: там `fields` даёт `400`. ## Дальше - [Фильтры и сортировка](https://kinodata.space/ru/docs/filters.md) — как выбрать и упорядочить элементы. - [Каталог и поиск](https://kinodata.space/ru/docs/titles.md) — главный список API. --- # Фильтры и сортировка > Операторы, все фильтры каталога, сортировка, окно оценок и пресеты. > https://kinodata.space/ru/docs/filters.md Каталог `/titles` выбирает тайтлы фильтрами и упорядочивает их параметром `sort`. Та же грамматика работает в подборке, связях, фильмографии, совместных работах и витринах, а фильтры — ещё и в календаре релизов: выучив её один раз, вы фильтруете любой список тайтлов. ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "kind=anime" \ --data-urlencode "country=jp" \ --data-urlencode "votes_imdb.gte=50000" \ --data-urlencode "sort=-rating_imdb" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,year,rating_imdb" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt2560140", "kp_id": "749374", "tmdb_id": null, "tmdb_tv_id": "1429", "kinorium_id": "678289", "title_ru": "Атака титанов", "title_en": "Attack on Titan", "year": 2013, "rating_imdb": 9.1 }, { "imdb_id": "tt1355642", "kp_id": "452838", "tmdb_id": null, "tmdb_tv_id": "31911", "kinorium_id": "468024", "title_ru": "Стальной алхимик: Братство", "title_en": "Fullmetal Alchemist: Brotherhood", "year": 2009, "rating_imdb": 9.1 }, { "imdb_id": "tt14986406", "kp_id": "4789626", "tmdb_id": null, "tmdb_tv_id": "326913", "kinorium_id": "2794509", "title_ru": "Блич: Тысячелетняя кровавая война", "title_en": "Bleach: Thousand-Year Blood War", "year": 2022, "rating_imdb": 9 } ], "limit": 3, "offset": 0, "total": null } ``` Где: - `kind=anime` и `country=jp` — японское аниме; - `votes_imdb.gte=50000` — не меньше 50 000 голосов на IMDb; - `sort=-rating_imdb` — от высокой оценки IMDb к низкой. ## Операторы К имени фильтра добавляется оператор: | оператор | что значит | пример | |---|---|---| | без оператора | равно; несколько значений через запятую — любое из них | `kind=movie,series` | | `.any` | любое из перечисленных | `genre.any=drama,comedy` | | `.all` | все перечисленные сразу | `genre.all=drama,war` | | `.not` | кроме перечисленных | `country.not=us` | | `.gte`, `.lte` | не меньше, не больше | `year.gte=1990&year.lte=1999` | Число без оператора — точное значение: `year=1999` то же, что `year.gte=1999&year.lte=1999`. Условия разных фильтров складываются через «и». ## Что можно фильтровать | группа | фильтры | |---|---| | ID | `imdb_id`, `kp_id`, `tmdb_id`, `tmdb_tv_id` | | Вид | `kind`, `is_series`, `adult` | | Даты | `year`, `release_date`, `premiere_world`, `premiere_ru`, `digital_release`, `released`, `start_year`, `end_year` | | Оценки и голоса | `rating`, `rating_imdb`, `rating_kp`, `rating_tmdb`, `rating_kr`, `rating_letterboxd`, `rating_rt`, `rating_metacritic`, `rating_critics`, `votes_imdb`, `votes_kp`, `votes_tmdb`, `votes_kr`, `votes_letterboxd`, `votes_total`, `popularity` | | Содержание | `genre`, `tag`, `country`, `region`, `original_language`, `runtime` | | Компании | `companies`, `company.kind`, `platform` | | Люди | `person`, `person.role` | | Подборки и франшизы | `collection`, `franchise` | | Сериалы | `seasons_total`, `episodes_total` | | Деньги | `budget`, `box_office_us`, `revenue_world` | | Награды | `wins_imdb`, `oscars_won` | | Возраст | `age_limit`, `age_limit_max`, `mpaa` | | Полнота данных | `required`, `has_poster` | Значения для `genre`, `country`, `region`, `platform`, `tag` и `companies` вместе с числом тайтлов отдаёт [`GET /filters`](https://kinodata.space/ru/docs/facets.md) — в поле `value`. Подписи всех перечислений, ключи `sort` и имена `fields` — [`GET /enums`](https://kinodata.space/ru/docs/enums.md). ## Сортировка ```text ?sort=-rating_imdb по убыванию ?sort=+year по возрастанию ?sort=-rating_imdb,+year второй ключ решает при равенстве первого ``` Знак — направление, без знака — по убыванию. Ключи: `popularity`, `relevance`, `release_date`, `year`, `runtime`, `rating`, `rating_imdb`, `rating_kp`, `rating_tmdb`, `rating_kr`, `rating_letterboxd`, `rating_rt`, `rating_metacritic`, `rating_critics`, `votes_imdb`, `votes_kp`, `votes_tmdb`, `votes_kr`, `votes_letterboxd`, `votes_total`, `rating_weighted`, `divergence`, `budget`, `box_office_us`, `revenue_world`, `wins_imdb`, `oscars_won`, `random`. Имена денег и наград — те же, что в карточке тайтла. Знак `+` можно передать как есть: `sort=+year` и `sort=%2Byear` работают одинаково. - **Без `sort`** каталог идёт по популярности — по сумме голосов всех источников. Тайтлы без голосов, в том числе анонсы, стоят в конце. - **С поиском `q`** по умолчанию — по релевантности. - **Сортировка по полю** оставляет только тайтлы, у которых оно есть. Исключение — подборка, связи и фильмография: там тайтлы без значения остаются в конце. - **`sort=rating`** берёт первую известную оценку тайтла — IMDb, затем Кинопоиск, затем TMDB — и ставит тайтлы с 50 и больше голосами выше остальных. - **`sort=rating_weighted`** — средняя оценка Кинопоиска, IMDb и TMDB, взвешенная по числу голосов: оценка, за которой больше людей, весит больше. - **`sort=divergence`** — по величине расхождения оценок Кинопоиска и IMDb: без знака и с `-` — сильные расхождения первыми, `+divergence` — самые близкие оценки первыми. Подробнее — [Расхождения оценок](https://kinodata.space/ru/docs/discover/divergence.md). - **`sort=popularity`** — по сумме голосов всех источников. Фильтр `popularity` и поле `ratings.popularity` в карточке — другое число: индекс популярности TMDB. - **`sort=random`** перемешивает выборку. Листать её нельзя — повторите запрос за новой. ## Оценки: ставьте порог голосов Общего балла в карточке нет намеренно: у источников разные шкалы и аудитории, и среднее это скрыло бы. Для сортировки есть `rating_weighted` — среднее, взвешенное по числу голосов, — но и с ним ставьте порог. Сортировка по одной оценке без порога голосов поднимает наверх тайтлы, которые оценили несколько человек: IMDb и TMDB принимают голоса и до премьеры, поэтому десятку от одного зрителя может получить даже невышедший фильм. Ставьте порог явно: ```text ?rating_imdb.gte=8&votes_imdb.gte=100000&sort=-rating_imdb ``` Порог есть у каждого источника с голосами: `votes_imdb`, `votes_kp`, `votes_tmdb`, `votes_kr` (Кинориум), `votes_letterboxd`. ### Окно оценок Когда важно мнение нескольких аудиторий сразу, используйте окно: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "rating_min=8.5" \ --data-urlencode "rating_sources=imdb,kp" \ --data-urlencode "rating_match=all" \ --data-urlencode "votes_imdb.gte=500000" \ --data-urlencode "sort=-votes_imdb" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,rating_imdb,rating_kp" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt0468569", "kp_id": "111543", "tmdb_id": "155", "tmdb_tv_id": null, "kinorium_id": "352641", "title_ru": "Тёмный рыцарь", "title_en": "The Dark Knight", "rating_kp": 8.5, "rating_imdb": 9.1 }, { "imdb_id": "tt0111161", "kp_id": "326", "tmdb_id": "278", "tmdb_tv_id": null, "kinorium_id": "101209", "title_ru": "Побег из Шоушенка", "title_en": "The Shawshank Redemption", "rating_kp": 9.1, "rating_imdb": 9.3 }, { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809", "title_ru": "Начало", "title_en": "Inception", "rating_kp": 8.7, "rating_imdb": 8.8 } ], "limit": 3, "offset": 0, "total": null } ``` | параметр | что значит | |---|---| | `rating_min`, `rating_max` | Границы окна. | | `rating_sources` | Чьи оценки проверять: `kp`, `imdb`, `tmdb`, `kr` (Кинориум), `letterboxd`. По умолчанию первые три. | | `rating_match` | `all` — в окно попадают все названные источники. Без него хватает любого. | ## Люди и компании `person` выбирает тайтлы с участием человека. ID передаётся с каталогом через двоеточие: `kp:41477`, `imdb:nm0634240`, `tmdb:525`, `kinorium:476400`. Несколько людей через запятую — любой из них, повтор параметра — все сразу: `person=kp:37859&person=kp:41477` — тайтлы, где есть и ДиКаприо, и Нолан. `person.role` уточняет роль и без `person` даёт `400`: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "person=kp:41477" \ --data-urlencode "person.role=director" \ --data-urlencode "released=true" \ --data-urlencode "sort=-year" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,year" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt33764258", "kp_id": "6385370", "tmdb_id": "1368337", "tmdb_tv_id": null, "kinorium_id": "11772913", "title_ru": "Одиссея", "title_en": "The Odyssey", "year": 2026 }, { "imdb_id": "tt15398776", "kp_id": "4664634", "tmdb_id": "872585", "tmdb_tv_id": null, "kinorium_id": "2828885", "title_ru": "Оппенгеймер", "title_en": "Oppenheimer", "year": 2023 }, { "imdb_id": "tt6723592", "kp_id": "1236063", "tmdb_id": "577922", "tmdb_tv_id": null, "kinorium_id": "2023303", "title_ru": "Довод", "title_en": "Tenet", "year": 2020 } ], "limit": 3, "offset": 0, "total": null } ``` `companies` ищет по названию компании, `company.kind` — по её роли: `production`, `studio`, `network`, `special_effects`, `distributor_theatrical`, `distributor_online`, `dubbing`. Вместе они отвечают на вопрос «где HBO была телеканалом»: `companies=HBO&company.kind=network`. ## Возраст и выход - `age_limit` — российский возрастной ценз: 0, 6, 12, 16, 18. Список через запятую (`age_limit=12,16`) или диапазон (`age_limit.gte=16`). `age_limit_max=12` — то же, что `age_limit.lte=12`. Тайтлы без ценза в выборку не попадают: неизвестный ценз — не ноль. - `mpaa` — американский сертификат: `G`, `PG`, `PG-13`, `R`, `NC-17` и семейство `TV-*`. У тайтла один сертификат, поэтому для «любой из» пишите `mpaa=R,NC-17`. - `released=true` — вышедшие, `released=false` — предстоящие. Тайтл считается предстоящим, если дата выхода или год позже сегодняшних. ## Готовые наборы: preset `preset` — набор фильтров под именем. Явные параметры уточняют его: `preset=top&votes_imdb.gte=500000` строже обычного топа. `order=asc` переворачивает сортировку пресета — `preset=top&order=asc` начинается с самых низких оценок, — а `sort` заменяет её целиком. | пресет | что внутри | |---|---| | `top` | `sort=-rating_imdb`, `votes_imdb.gte=100000`, есть оценка Кинопоиска и постер | | `hidden_gems` | всё, кроме короткого метра и ТВ-шоу: 1 000–50 000 голосов на Кинопоиске и 1 000–25 000 на IMDb, без концертов, стендапов, спектаклей, музыки и документального кино, `sort=-rating_weighted` | | `trending` | вышедшие, `sort=-popularity` | | `new` | вышли за последние 30 дней, `sort=-release_date` | | `classics` | до 1980 года, от 50 000 голосов на IMDb, `sort=-rating_imdb` | ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "preset=top" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,rating_imdb" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt0903747", "kp_id": "404900", "tmdb_id": null, "tmdb_tv_id": "1396", "kinorium_id": "400796", "title_ru": "Во все тяжкие", "title_en": "Breaking Bad", "rating_imdb": 9.5 }, { "imdb_id": "tt5491994", "kp_id": "1007472", "tmdb_id": null, "tmdb_tv_id": "68595", "kinorium_id": "1605088", "title_ru": "Планета Земля 2", "title_en": "Planet Earth II", "rating_imdb": 9.4 }, { "imdb_id": "tt0795176", "kp_id": "279548", "tmdb_id": null, "tmdb_tv_id": "1044", "kinorium_id": "379535", "title_ru": "Планета Земля", "title_en": "Planet Earth", "rating_imdb": 9.4 } ], "limit": 3, "offset": 0, "total": null } ``` ## Подборки и франшизы - `collection` — тайтлы нашей подборки по её `slug`: `collection=popular-titles`. Список подборок — `GET /collections`. Несуществующая подборка — ошибка `400` со списком существующих. - `franchise` — тайтлы франшизы по части её названия в TMDB: `franchise=matrix`. ## Полнота данных `required` оставляет тайтлы, у которых заполнены перечисленные поля: `required=poster,rating_imdb` или `required=kinorium_id`. `has_poster=true` — то же для одного постера. ## В других списках Те же фильтры и `sort` работают в подборке, связях, фильмографии, совместных работах и витринах, а фильтры — ещё и в календаре релизов. Например, фильмы Кристофера Нолана от 100 000 голосов — по оценке IMDb: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "kind=movie" \ --data-urlencode "votes_imdb.gte=100000" \ --data-urlencode "sort=-rating_imdb" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,rating_imdb" \ "https://api.kinodata.space/v1.3/persons/kp/41477/filmography" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt0468569", "kp_id": "111543", "tmdb_id": "155", "tmdb_tv_id": null, "kinorium_id": "352641", "title_ru": "Тёмный рыцарь", "title_en": "The Dark Knight", "rating_imdb": 9.1 }, { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809", "title_ru": "Начало", "title_en": "Inception", "rating_imdb": 8.8 }, { "imdb_id": "tt0816692", "kp_id": "258687", "tmdb_id": "157336", "tmdb_tv_id": null, "kinorium_id": "384511", "title_ru": "Интерстеллар", "title_en": "Interstellar", "rating_imdb": 8.7 } ], "limit": 3, "offset": 0, "roles": [ { "role": "director", "label_ru": "Режиссёры", "label_en": "Directors", "count": 19 }, { "role": "actor", "label_ru": "Актёры", "label_en": "Actors", "count": 2 }, { "role": "self", "label_ru": "В роли себя", "label_en": "Self", "count": 90 }, { "role": "archive", "label_ru": "Архивные кадры", "label_en": "Archive Footage", "count": 12 }, { "role": "writer", "label_ru": "Сценаристы", "label_en": "Writers", "count": 20 }, { "role": "producer", "label_ru": "Продюсеры", "label_en": "Producers", "count": 22 }, { "role": "cinematographer", "label_ru": "Операторы", "label_en": "Cinematographers", "count": 5 }, { "role": "composer", "label_ru": "Композиторы", "label_en": "Composers", "count": 1 }, { "role": "editor", "label_ru": "Монтажёры", "label_en": "Editors", "count": 5 }, { "role": "crew", "label_ru": "Съёмочная группа", "label_en": "Crew", "count": 3 } ], "total": 18 } ``` Пресеты тоже работают: `preset=top` в фильмографии ставит первыми работы с лучшей оценкой IMDb. В фильмографии и совместных работах порядок по умолчанию — от новых работ к старым, `order=asc` его переворачивает. ## Ошибки в запросе Неизвестный фильтр или оператор — ошибка `400`, а не тишина: незаметно отброшенный фильтр выглядел бы как фильтр, под который подошло всё. Где замена очевидна, API подсказывает её в `hint`. Фильтра `status` нет — статус выхода спрашивают через `released`: ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "status=released" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `400`: ```json { "error": { "code": "invalid_request", "message": "unknown query parameter \"status\"", "field": "status", "hint": "there is no status filter; the card carries type.status, the catalog filters by released" } } ``` Параметр с одним значением нельзя повторять: `kind=movie&kind=series` — тоже `400`. Несколько значений пишутся через запятую — `kind=movie,series`. Исключение — `person`: его повтор значит «все эти люди». ## Дальше - [Каталог и поиск](https://kinodata.space/ru/docs/titles.md) — все параметры `/titles`. - [Списки и пагинация](https://kinodata.space/ru/docs/lists.md) — как листать результат. --- # Ошибки > Как выглядит ошибка, что значит каждый код и когда повторять запрос. > https://kinodata.space/ru/docs/errors.md Если запрос не прошёл, API отвечает статусом 4xx или 5xx и объектом `error`. Код говорит, что случилось, а поля рядом — какой параметр виноват и какие значения допустимы. Например, в типе каталога опечатка — `tmbd` вместо `tmdb`: ```bash curl -H "X-API-Key: $KINODATA_KEY" \ "https://api.kinodata.space/v1.3/ids/tmbd/27205" ``` Ответ `400`: ```json { "error": { "code": "invalid_request", "message": "unknown type \"tmbd\"", "field": "type", "allowed": [ "imdb", "kp", "tmdb", "tmdb_tv", "kinorium" ], "hint": "did you mean \"tmdb\"?" } } ``` ## Поля ошибки | поле | есть всегда | что это | |---|---|---| | `code` | да | Машинный код. По нему и ветвитесь. | | `message` | да | Объяснение для человека, по-английски. Текст может уточняться, не разбирайте его в коде. | | `field` | нет | Параметр, из-за которого запрос отклонён. | | `allowed` | нет | Допустимые значения этого параметра. | | `hint` | нет | Подсказка, если значение похоже на допустимое (`tmbd` → `tmdb`) или входит в него целиком (`sort=kp` → `rating_kp` или `votes_kp`). | Ветвитесь по `code`, а не по статусу: один статус бывает у разных причин. ## Коды ### invalid_request - **Статус:** 400. - **Когда:** неизвестный параметр или значение, ID не в формате каталога, повторённый параметр, `limit` не целое число от 1. - **Что делать:** прочитайте `field`, `allowed` и `hint` и исправьте запрос. ### unauthorized - **Статус:** 401. - **Когда:** нет заголовка `X-API-Key`, ключ неизвестен или отозван. - **Что делать:** проверьте, что заголовок называется `X-API-Key` и ключ скопирован целиком. ### forbidden - **Статус:** 403. - **Когда:** запросы с вашего адреса закрыты: с него перебирали ключи или иначе нарушали правила. `message` — `this address is blocked`. Бан за подбор ключей снимается сам через сутки. - **Что делать:** если адрес закрыт по ошибке — например, он общий у офиса или оператора, — [напишите нам](https://kinodata.space/ru/contacts). ### not_found - **Статус:** 404. - **Когда:** тайтла или человека с таким ID нет, подборки с таким `slug` нет, такого адреса нет. - **Что делать:** проверьте тип и ID. `tmdb` и `tmdb_tv` легко перепутать: это разные ID. ### rate_limited - **Статус:** 429. - **Когда:** исчерпан предел в секунду или квота на сутки. `message` уточняет, какой: `rate limit exceeded` — секунда, `quota limit exceeded` — сутки. - **Что делать:** подождите столько секунд, сколько указано в заголовке `Retry-After`. Квота на сутки обновляется в полночь по UTC. - **Как не упереться:** остаток виден в каждом ответе. `X-RateLimit-Remaining` — сколько запросов осталось в текущей секунде, `X-Quota-Remaining` — на сутки, `X-Quota-Reset` — когда квота обновится (Unix-время). У ключа без предела этих заголовков нет. ### internal - **Статус:** 500. - **Когда:** сбой на нашей стороне. - **Что делать:** повторите запрос с паузой. Если ошибка повторяется, напишите нам и приложите `X-Request-Id`. ### source_unavailable - **Статус:** 502. - **Когда:** каталог, из которого мы дополняли данные, не ответил. - **Что делать:** повторите запрос позже. ## Повторять ли запрос | код | повторять | |---|---| | `rate_limited` | да, через `Retry-After` секунд | | `internal`, `source_unavailable` | да, с растущей паузой: 1, 2, 4 секунды | | остальные | нет: запрос не станет верным сам | Все запросы API — `GET`, поэтому повтор ничего не меняет и безопасен. ## Если не получается С каждым ответом приходит заголовок `X-Request-Id`. Приложите его к обращению — по нему мы найдём ваш запрос. ## Дальше - [Ключ и лимиты](https://kinodata.space/ru/docs/keys.md) — как не упираться в `429`. - [Списки и пагинация](https://kinodata.space/ru/docs/lists.md) — правила `limit`, `offset` и `cursor`. --- # ID во всех каталогах > По ID тайтла в одном каталоге — его ID в остальных. > https://kinodata.space/ru/docs/ids.md Запрос: `GET https://api.kinodata.space/v1.3/ids/{type}/{id}` Самый лёгкий запрос API: только ID, без названий и метаданных. Подходит, когда ID нужны для своей базы или чтобы открыть тайтл на сайте каталога. `tmdb` и `tmdb_tv` — разные пространства ID. Один и тот же ID означает в них разные произведения: `/ids/tmdb/1396` — «Зеркало» Тарковского, `/ids/tmdb_tv/1396` — «Во все тяжкие». Берите тип, который дал вам сам TMDB. ## Параметры пути - `type` (string, обязательный) — Каталог, из которого ID: IMDb, Кинопоиск, TMDB (фильм или сериал) или Кинориум. Значения: `imdb`, `kp`, `tmdb`, `tmdb_tv`, `kinorium`. - `id` (string, обязательный) — ID в этом каталоге. У IMDb — `tt` и цифры (`tt1375666`), у остальных — цифры (`447301`). ## Поля ответа - `imdb_id` (string | null) — ID в IMDb: `tt` и цифры. - `kp_id` (string | null) — ID на Кинопоиске. - `tmdb_id` (string | null) — ID фильма в TMDB. У сериала — `null`, его ID в `tmdb_tv_id`. - `tmdb_tv_id` (string | null) — ID сериала в TMDB. Заполнено не больше одного из `tmdb_id` и `tmdb_tv_id`. - `kinorium_id` (string | null) — ID на Кинориуме. ## Ошибки | статус | код | когда | |---|---|---| | 400 | `invalid_request` | Неизвестный `type` или ID не в формате каталога: у IMDb нет `tt`, у остальных не цифры; параметр запроса, кроме `lang`. | | 404 | `not_found` | Тайтл с таким ID не найден. | | 401 | `unauthorized` | Нет заголовка `X-API-Key`, ключ неизвестен или отозван. | | 429 | `rate_limited` | Исчерпан предел в секунду или квота на сутки. | Все коды и что с ними делать — на странице [Ошибки](https://kinodata.space/ru/docs/errors.md). ## Примеры ### По Кинопоиску ```bash curl -H "X-API-Key: $KINODATA_KEY" \ "https://api.kinodata.space/v1.3/ids/kp/447301" ``` Ответ `200`: ```json { "imdb_id": "tt1375666", "kp_id": "447301", "tmdb_id": "27205", "tmdb_tv_id": null, "kinorium_id": "472809" } ``` ### Сериал в TMDB ```bash curl -H "X-API-Key: $KINODATA_KEY" \ "https://api.kinodata.space/v1.3/ids/tmdb_tv/1396" ``` ### Неизвестный ID ```bash curl -H "X-API-Key: $KINODATA_KEY" \ "https://api.kinodata.space/v1.3/ids/kp/999999999" ``` ### Опечатка в типе ```bash curl -H "X-API-Key: $KINODATA_KEY" \ "https://api.kinodata.space/v1.3/ids/tmbd/27205" ``` --- # Каталог и поиск > Поиск тайтлов по названию и выборка по фильтрам из всей базы. > https://kinodata.space/ru/docs/titles.md Запрос: `GET https://api.kinodata.space/v1.3/titles` Главный список API: поиск, витрины и выборки по любым признакам. Фильтры, сортировка и пресеты подробно разобраны в [Фильтры и сортировка](https://kinodata.space/ru/docs/filters.md), пагинация и `fields` — в [Списки и пагинация](https://kinodata.space/ru/docs/lists.md). Без `sort` каталог идёт по популярности, тайтлы без голосов — в конце. К сортировке по оценке добавляйте порог голосов: оценку ставят и несколько человек. ## Параметры запроса - `q` (string) — Поиск по названию на любом языке. Прощает опечатки: «матрца» и «matrx» найдут «Матрицу». С `q` сортировка по умолчанию — по релевантности. Пример: `q=матрица`. - `фильтры` — Любой фильтр каталога с операторами `.any`, `.all`, `.not`, `.gte`, `.lte`: `kind=anime`, `country=jp`, `year.gte=1990`, `votes_imdb.gte=50000`, `person=kp:41477`. Полный список — в [Фильтры и сортировка](https://kinodata.space/ru/docs/filters.md#что-можно-фильтровать). - `sort` (string) — Порядок: ключ со знаком, `-` — по убыванию, `+` — по возрастанию. Можно два ключа через запятую: `sort=-rating_imdb,+year`. По умолчанию — по популярности, а с `q` — по релевантности. Значения: `popularity`, `relevance`, `release_date`, `year`, `runtime`, `rating`, `rating_imdb`, `rating_kp`, `rating_tmdb`, `rating_kr`, `rating_letterboxd`, `rating_rt`, `rating_metacritic`, `rating_critics`, `votes_imdb`, `votes_kp`, `votes_tmdb`, `votes_kr`, `votes_letterboxd`, `votes_total`, `rating_weighted`, `divergence`, `budget`, `box_office_us`, `revenue_world`, `wins_imdb`, `oscars_won`, `random`. По умолчанию: `popularity`, с `q` — `relevance`. Пример: `sort=-rating_imdb`. - `preset` (enum) — Готовый набор фильтров. Явные параметры его уточняют. Что внутри каждого — в [Фильтры и сортировка](https://kinodata.space/ru/docs/filters.md#готовые-наборы-preset). Значения: `top`, `hidden_gems`, `trending`, `new`, `classics`. Пример: `preset=top`. - `limit` (integer) — Сколько тайтлов на странице, от 1 до 50. По умолчанию: 50. Пример: `limit=20`. - `offset` (integer) — Сколько тайтлов пропустить от начала. По умолчанию: 0. - `cursor` (string) — Курсор для глубокой прокрутки. Первый запрос — с пустым `cursor=`, дальше — значение `next_cursor` из ответа. Не работает с `sort=random`. Есть только у каталога. - `fields` (csv) — Какие поля элемента вернуть: `fields=title,year`. Со знаком `-` — какие убрать: `fields=-genres`. `title` оставляет `title_ru` и `title_en`, `poster_url` — `poster_url_ru` и `poster_url_en`. ID приходят всегда. Значения: `title`, `title_original`, `year`, `release_date`, `kind`, `poster_url`, `posters_by_source`, `rating_kp`, `rating_tmdb`, `rating_imdb`, `rating_kr`, `rating_letterboxd`, `votes_kp`, `votes_tmdb`, `votes_imdb`, `countries`, `genres`. Пример: `fields=title,year`. - `lang` (ru | en) — Оставить в ответе один язык. ## Поля ответа - `items` (array) — Тайтлы. - `imdb_id`, `kp_id`, `tmdb_id`, `tmdb_tv_id`, `kinorium_id` (string | null) — ID тайтла в каталогах. Приходят всегда, даже с `fields`. - `title_ru`, `title_en`, `title_original` (string | null) — Названия: на русском, на английском и на языке оригинала. - `year` (integer | null) — Год выхода. - `release_date` (string | null) — Первая дата выхода, `YYYY-MM-DD`. - `kind` (enum) — Вид тайтла: `movie`, `series`, `mini_series`, `tv_show`, `anime`, `cartoon`, `short`. - `poster_url_ru`, `poster_url_en` (string | null) — Постер для русской и английской витрины. - `posters_by_source` (object) — Постер каждого источника: `kp`, `tmdb`, `imdb`, `kinorium`. - `rating_kp`, `rating_tmdb`, `rating_imdb`, `rating_kr`, `rating_letterboxd` (number | null) — Оценки Кинопоиска, TMDB, IMDb, Кинориума и Letterboxd, шкала 0–10. - `votes_kp`, `votes_tmdb`, `votes_imdb` (integer | null) — Голоса Кинопоиска, TMDB и IMDb. - `countries` (array) — Страны: `code`, `name_ru`, `name_en`. - `genres` (array) — Жанры: `slug`, `name_ru`, `name_en`. - `total` (null) — Каталог не считает общее число тайтлов: точный подсчёт по фильтру — второй проход по всей базе. Листайте по `has_more`. - `limit`, `offset` (integer) — Размер страницы и смещение. `offset` нет, когда вы листаете курсором. - `has_more` (boolean) — Есть ли следующая страница. - `next_cursor` (string | null) — Курсор следующей страницы, только если в запросе был `cursor`. `null` — дальше ничего нет. ## Ошибки | статус | код | когда | |---|---|---| | 400 | `invalid_request` | Неизвестный фильтр, оператор, ключ `sort` или имя в `fields`; повторённый параметр, кроме `person`; несуществующая подборка в `collection`; параметр другого эндпоинта (например, `role` или `relation`); `limit` не число; `person.role` без `person`; `cursor` или `offset` вместе с `sort=random`; испорченный курсор. | | 401 | `unauthorized` | Нет заголовка `X-API-Key`, ключ неизвестен или отозван. | | 429 | `rate_limited` | Исчерпан предел в секунду или квота на сутки. | Все коды и что с ними делать — на странице [Ошибки](https://kinodata.space/ru/docs/errors.md). ## Примеры ### Поиск ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "q=матрица" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,year,rating_imdb" \ "https://api.kinodata.space/v1.3/titles" ``` Ответ `200`: ```json { "has_more": true, "items": [ { "imdb_id": "tt0133093", "kp_id": "301", "tmdb_id": "603", "tmdb_tv_id": null, "kinorium_id": "116780", "title_ru": "Матрица", "title_en": "The Matrix", "year": 1999, "rating_imdb": 8.7 }, { "imdb_id": "tt0234215", "kp_id": "299", "tmdb_id": "604", "tmdb_tv_id": null, "kinorium_id": "190315", "title_ru": "Матрица: Перезагрузка", "title_en": "The Matrix Reloaded", "year": 2003, "rating_imdb": 7.2 }, { "imdb_id": "tt0242653", "kp_id": "316", "tmdb_id": "605", "tmdb_tv_id": null, "kinorium_id": "196883", "title_ru": "Матрица: Революция", "title_en": "The Matrix Revolutions", "year": 2003, "rating_imdb": 6.7 } ], "limit": 3, "offset": 0, "total": null } ``` ### С опечаткой ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "q=матрца" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,year,rating_imdb" \ "https://api.kinodata.space/v1.3/titles" ``` ### Фильтры ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "kind=anime" \ --data-urlencode "country=jp" \ --data-urlencode "votes_imdb.gte=50000" \ --data-urlencode "sort=-rating_imdb" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,year,rating_imdb" \ "https://api.kinodata.space/v1.3/titles" ``` ### Фильмы режиссёра ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "person=kp:41477" \ --data-urlencode "person.role=director" \ --data-urlencode "released=true" \ --data-urlencode "sort=-year" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,year" \ "https://api.kinodata.space/v1.3/titles" ``` ### Курсор ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "sort=-rating_imdb" \ --data-urlencode "votes_imdb.gte=100000" \ --data-urlencode "limit=2" \ --data-urlencode "fields=title,rating_imdb" \ --data-urlencode "cursor=" \ "https://api.kinodata.space/v1.3/titles" ``` ### Неизвестный фильтр ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "status=released" \ "https://api.kinodata.space/v1.3/titles" ``` ### Только английский ```bash curl -G -H "X-API-Key: $KINODATA_KEY" \ --data-urlencode "q=matrix" \ --data-urlencode "limit=3" \ --data-urlencode "fields=title,year,rating_imdb" \ --data-urlencode "lang=en" \ "https://api.kinodata.space/v1.3/titles" ``` --- # Карточка тайтла > Всё о фильме или сериале одним запросом: названия, описания, оценки, даты, награды, медиа и состав. > https://kinodata.space/ru/docs/titles/card.md Запрос: `GET https://api.kinodata.space/v1.3/titles/{type}/{id}` Карточка открывается по ID любого из пяти каталогов: `/titles/kp/447301` и `/titles/imdb/tt1375666` возвращают одно и то же. Целиком карточка — до 22 блоков и около 26 КБ, со сжатием около 8 КБ. Если нужна часть, перечислите блоки в `fields`: так ответ меньше, а разбирать его проще. Блок `ids` приходит всегда. ## Параметры пути - `type` (string, обязательный) — Каталог, из которого ID: IMDb, Кинопоиск, TMDB (фильм или сериал) или Кинориум. Значения: `imdb`, `kp`, `tmdb`, `tmdb_tv`, `kinorium`. - `id` (string, обязательный) — ID в этом каталоге. У IMDb — `tt` и цифры (`tt1375666`), у остальных — цифры (`447301`). ## Параметры запроса - `fields` (csv) — Какие блоки вернуть: `fields=title,ratings`. Со знаком `-` — какие убрать: `fields=-akas,-tags`. Смешивать нельзя. По умолчанию — все блоки. Значения: `ids`, `meta`, `title`, `type`, `synopsis`, `release`, `ratings`, `finance`, `awards`, `countries`, `classification`, `series`, `media`, `genres`, `companies`, `akas`, `tags`, `watch`, `parental`, `credits_top`, `franchise`, `counts`. Пример: `fields=title,ratings`. - `lang` (ru | en) — Оставить в ответе один язык. Без него текстовые поля приходят парами `_ru` и `_en`. Подробнее — [Языки ответа](https://kinodata.space/ru/docs/languages.md). ## Поля ответа - `ids` (object) — ID тайтла во всех каталогах и ссылки на его страницы. Приходит всегда, даже если его нет в `fields`. - `imdb_id` (string | null) — ID в IMDb. - `kp_id` (string | null) — ID на Кинопоиске. - `tmdb_id` (string | null) — ID фильма в TMDB. - `tmdb_tv_id` (string | null) — ID сериала в TMDB. Заполнено не больше одного из `tmdb_id` и `tmdb_tv_id`. - `kinorium_id` (string | null) — ID на Кинориуме. - `urls` (object) — Ссылки на страницы тайтла: `imdb`, `kp`, `tmdb`, `kinorium`. С `lang=en` ссылка на Кинориум ведёт на `en.kinorium.com`. - `meta` (object) — Служебные сведения о карточке. - `updated_at` (string) — Когда данные тайтла последний раз обновлялись, ISO 8601 в UTC. - `title` (object) — Названия. - `title_ru` (string | null) — Название на русском. - `title_en` (string | null) — Английское название. Только настоящее: оригинальное название неанглоязычного фильма или транслитерация сюда не попадают, тогда `null`. - `title_original` (string | null) — Название на языке оригинала. - `type` (object) — Вид и статус тайтла. - `kind` (enum) — Вид тайтла. Значения: `movie`, `series`, `mini_series`, `tv_show`, `anime`, `cartoon`, `short`. - `is_series` (boolean) — Многосерийный ли тайтл. - `status` (enum) — Статус выхода. Все значения — в `/enums`, набор `statuses`. Значения: `released`, `ended`, `returning_series`, `in_production`, `post_production`, `in_development`, `planned`, `canceled`. - `kind_label_ru`, `kind_label_en` (string) — Подпись вида: «Фильм» / «Movie». - `status_label_ru`, `status_label_en` (string) — Подпись статуса: «Вышел» / «Released». - `synopsis` (object) — Описания и слоганы. Каждый текст — из своего источника, а не перевод соседнего. - `overview_ru`, `overview_en` (string | null) — Описание сюжета. - `short_overview_ru`, `short_overview_en` (string | null) — Описание в одну-две фразы. - `tagline_ru`, `tagline_en` (string | null) — Слоган. - `overview_alter_ru`, `overview_alter_en` (string | null) — Второе описание из другого источника, если оно отличается от первого. - `release` (object) — Год, длительность и даты выхода. - `year` (integer | null) — Год выхода. - `runtime` (integer | null) — Длительность в минутах. - `releases` (array) — Даты выхода по регионам. Каждая дата стоит один раз: если цифровой релиз в США совпал с мировым, он только в `world`. - `region` (string) — Регион: `world` — самая ранняя дата в мире, `us` — США, `ru` — Россия. - `dates` (array) — Даты в регионе: `type` и `date`. Типы: `premiere` — премьера, `release` — выход в прокат, `digital` — цифровой релиз; подписи — в `/enums`, набор `title_release_types`. Дата — `YYYY-MM-DD`. - `ratings` (object) — Оценки по источникам. Общего балла нет намеренно: у источников разные шкалы и аудитории. - `sources` (object) — Оценки по источникам: ключ — источник (`imdb`, `kp`, `tmdb`, `kinorium`, `letterboxd`, `rt`, `metacritic`, `critics`, `cr`), значение — `value`, `votes`, `scale` (10 или 100), `kind: "critics"` у оценок критиков и `url` страницы. У Кинориума ещё `distribution` — сколько зрителей поставили каждую оценку от 1 до 10; Кинориум считает её отдельно, поэтому сумма не совпадает с `votes`. Подписи источников — в `/enums`, набор `rating_sources`. Источника нет — нет ключа. - `votes_total` (integer | null) — Голоса Кинопоиска, IMDb и TMDB вместе. - `divergence_kp_imdb` (number | null) — На сколько расходятся оценки Кинопоиска и IMDb, по модулю. - `popularity` (number | null) — Индекс популярности TMDB. Это не сумма голосов. - `finance` (object) — Деньги, в долларах США. - `budget` (integer | null) — Бюджет. - `box_office_us` (integer | null) — Сборы в США. - `revenue_world` (integer | null) — Сборы в мире. - `awards` (object) — Награды: итоги и разбор по церемониям. - `wins_imdb`, `nominations_imdb` (integer | null) — Победы и все номинации, включая выигранные, по данным IMDb, по всем премиям мира. - `oscars_won`, `oscars_nominated` (integer | null) — «Оскары»: победы и все номинации, включая выигранные. - `wins_ceremonies`, `nominations_ceremonies` (integer) — Победы и все номинации по церемониям из `ceremonies`. - `summary_kinorium_ru` (string | null) — Сводка Кинориума по церемониям: «Оскар: 4/8; Британская академия: 5/10…». - `summary_imdb_en` (string | null) — Сводка IMDb: «Won 4 Oscars. 160 wins & 220 nominations total». Это другой текст, а не перевод сводки Кинориума. - `ceremonies` (array) — Церемонии по престижу, «Оскар» первым. - `slug` (string | null) — Код церемонии: `oscar`, `bafta`, `golden_globe`… - `ceremony_ru`, `ceremony_en` (string) — Название церемонии. - `icon` (string | null) — Путь к иконке церемонии на `api.kinodata.space`: золотая при победе, серая при номинации. - `won` (boolean) — Есть ли хоть одна победа. - `wins`, `nominations` (integer) — Победы и все номинации, включая выигранные. - `years` (array) — Годы церемоний. - `items` (array) — Категории: `category_ru`, `category_en`, `won`, `year`. - `countries` (array) — Страны производства: `code` (ISO 3166-1, строчными), `name_ru`, `name_en`. - `classification` (object) — Возраст и язык. - `age_limit` (integer | null) — Российский возрастной ценз: 0, 6, 12, 16 или 18. - `mpaa` (string | null) — Американский сертификат: `G`, `PG`, `PG-13`, `R`, `NC-17` или `TV-*`. - `original_language` (string | null) — Язык оригинала, ISO 639-1. - `is_adult` (boolean) — Контент для взрослых. - `series` (object) — Сериал. У фильма все поля `null`. - `seasons_total`, `episodes_total` (integer | null) — Сезонов и серий. - `start_year`, `end_year` (integer | null) — Годы выхода. У идущего сериала `end_year` — `null`. - `media` (object) — Постеры, задник, трейлеры и саундтрек. Остальные кадры и видео — в `/titles/{type}/{id}/media`. - `poster_url_ru`, `poster_url_en` (string | null) — Постер для русской и английской витрины. Английский — с надписями на английском, нет такого — `null`. - `poster_source_ru`, `poster_source_en` (string | null) — Откуда постер: `kp`, `tmdb`, `imdb`, `kinorium`. - `posters_by_source` (object) — Постер каждого источника: `kp`, `tmdb`, `imdb`, `kinorium`. - `backdrop_url` (string | null) — Широкий кадр для фона. - `poster_animated` (string) — Анимированный постер Кинориума — ролик mp4 до 7 МБ. Есть примерно у каждого десятого популярного тайтла; когда его нет, нет и ключа. Показывайте в `