Каталог и поиск¶
GET /titles¶
Ищет и фильтрует по всей базе: свободный текст, полсотни фильтров, сортировка, пагинация.
Параметры¶
| имя | тип | обязательный | по умолчанию | описание |
|---|---|---|---|---|
q |
строка | нет | — | свободный поиск по названиям; сортировка становится релевантностью |
sort |
строка | нет | release_date |
ключ со знаком; запятая добавляет тай-брейкер |
preset |
строка | нет | — | top · hidden_gems · trending · new · classics |
lang |
строка | нет | ru |
язык производного title: ru · en |
fields |
CSV | нет | вся карточка | оставить перечисленные ключи карточки |
limit |
целое | нет | 50 | размер страницы, максимум 50 |
offset |
целое | нет | 0 | смещение |
cursor |
строка | нет | — | курсор глубокой прокрутки; пустое значение начинает обход |
Фильтры — отдельная группа, их около пятидесяти. Грамматика операторов и полный список полей: Соглашения → Фильтры.
Запрос¶
curl -H "X-API-Key: $KINODATA_KEY" \
"https://api.kinodata.space/v1.2/titles?kind=anime&country=jp&rating_imdb.gte=8&sort=-year&limit=1"
Ответ¶
{
"has_more": true,
"items": [
{
"imdb_id": "tt41293157",
"kp_id": "12951729",
"tmdb_id": null,
"tmdb_tv_id": "286345",
"title_ru": "Хоть я и бездарная злодейка",
"title_en": "Though I Am an Inept Villainess",
"title_original": "ふつつかな悪女ではございますが ~雛宮蝶鼠とりかえ伝~",
"year": 2026,
"release_date": "2026-07-12",
"kind": "anime",
"poster_kp": "https://avatars.mds.yandex.net/get-kinopoisk-image/9784475/7255d393-a7ad-4e24-91c4-ea2b06cb7938/600x900",
"poster_tmdb": "https://image.tmdb.org/t/p/original/iDiCEyM5RPNi0QEQk52H6n3MyZL.jpg",
"poster_imdb": null,
"rating_kp": 8.6,
"rating_tmdb": 8.4,
"rating_imdb": 8.1,
"votes_kp": 10869,
"votes_tmdb": 9,
"votes_imdb": 414,
"countries": [ { "code": "jp", "name_ru": "Япония", "name_en": "Japan" } ],
"genres": ["animation", "anime", "drama", "fantasy", "mystery"],
"rating_kr": null,
"rating_letterboxd": null,
"kinorium_id": "12941627",
"title": "Хоть я и бездарная злодейка",
"poster_url": "https://avatars.mds.yandex.net/get-kinopoisk-image/9784475/7255d393-a7ad-4e24-91c4-ea2b06cb7938/600x900"
}
],
"limit": 1,
"offset": 0,
"total": null
}
Ошибки¶
| статус | код | когда |
|---|---|---|
400 |
invalid_request |
неизвестное значение фильтра, ключа сортировки, lang, preset или имени в fields; нечисловой limit; cursor при sort=random; курсор, выписанный под другую сортировку |
401 |
unauthorized |
ключ отсутствует или недействителен |
429 |
rate_limited |
превышен предел ключа |
Примечания¶
total здесь всегда null: точный счёт по фильтру — это второй полный агрегат
по 1.38 млн строк. Ключ на месте ради единой формы конверта, а листать помогает
has_more.
title и poster_url — производные: первое разрешает три названия по ?lang=,
второе выбирает постер из трёх источников. Исходные поля остаются рядом, если
логика выбора нужна своя.
Поиск q идёт по русскому, английскому и оригинальному названию сразу и терпит
опечатки, но точное совпадение всегда выигрывает:
curl -H "X-API-Key: $KINODATA_KEY" \
"https://api.kinodata.space/v1.2/titles?q=интерстелар&limit=2&fields=title,year,kind,rating_imdb,imdb_id"
{
"has_more": true,
"items": [
{ "imdb_id": "tt4168808", "kind": "movie", "rating_imdb": 6.8, "title": "Интерстелар", "year": 2014 },
{ "imdb_id": "tt0816692", "kind": "movie", "rating_imdb": 8.7, "title": "Интерстеллар", "year": 2014 }
],
"limit": 2,
"offset": 0,
"total": null
}
Первым идёт тайтл, который так и называется, вторым — тот, который искали.
Для глубокой прокрутки берите cursor вместо offset — он не съезжает, когда
данные меняются между страницами. Ответ с курсором несёт next_cursor вместо
offset.
sort=random перемешивает выборку и не принимает ни cursor, ни offset:
каждый запрос — самостоятельная выборка.
GET /filters¶
Отдаёт значения фасетов, диапазоны и раскрытие пресетов — всё, из чего строится панель фильтров.
Параметры¶
| имя | тип | обязательный | по умолчанию | описание |
|---|---|---|---|---|
facet |
CSV | нет | все | genres · countries · kinds · regions · platforms · tags · companies |
q |
строка | нет | — | искать по названию или слагу значения, на любом языке |
limit |
целое | нет | 50 | значений на фасет; 0 снимает предел |
Запрос¶
Ответ¶
{
"genres": [
{ "count": 441178, "name_en": "Drama", "name_ru": "драма", "slug": "drama" },
{ "count": 271526, "name_en": "Comedy", "name_ru": "комедия", "slug": "comedy" },
{ "count": 217753, "name_en": "Documentary", "name_ru": "документальный", "slug": "documentary" }
],
"genres_total": 23,
"presets": [
{
"filters": ["sort=-rating_imdb", "votes_imdb.gte=100000", "required=rating_kp,poster"],
"name": "top"
},
{
"filters": ["sort=-rating_imdb", "rating_imdb.gte=7.5", "votes_imdb.gte=2000",
"votes_imdb.lte=25000", "votes_kp.gte=1000", "kind=movie", "required=poster"],
"name": "hidden_gems"
},
{
"filters": ["sort=-popularity", "released=true"],
"name": "trending"
},
{
"filters": ["release_date.gte=<30 days ago>", "released=true", "sort=-release_date"],
"name": "new"
},
{
"filters": ["year.lte=1980", "votes_imdb.gte=50000", "sort=-rating_imdb"],
"name": "classics"
}
],
"year_range": { "min": 1888, "max": 2031 }
}
Ошибки¶
| статус | код | когда |
|---|---|---|
400 |
invalid_request |
неизвестное имя фасета |
401 |
unauthorized |
ключ отсутствует или недействителен |
Примечания¶
<фасет>_total говорит, сколько значений подошло до отсечения по limit, — по
нему видно, стоит ли показывать «ещё».
presets публикует, во что раскрывается каждый пресет: готовая строка запроса,
параметр за параметром. Пресет можно взять отправной точкой и доуточнить руками
— явные параметры имеют приоритет. <30 days ago> в раскрытии new означает,
что граница считается от даты запроса.
count у значения фасета — число тайтлов, так что пустые варианты в панели
можно не рисовать.