Skip to content
Sections: Filters and sorting

Essentials

Filters and sorting

The /titles catalog picks titles with filters and orders them with sort. The same grammar works in collections, relations, filmographies, shared titles and discovery feeds, and the filters work in the release calendar too: learn it once and you can filter any list of titles.

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"
Response200
{
  "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
}

Where:

  • kind=anime and country=jp select Japanese anime;
  • votes_imdb.gte=50000 asks for at least 50,000 IMDb votes;
  • sort=-rating_imdb orders from the highest IMDb rating down.

Operators

An operator goes after the filter name:

operatormeaningexample
noneequals; several comma-separated values mean any of themkind=movie,series
.anyany of the listed valuesgenre.any=drama,comedy
.allall of the listed values at oncegenre.all=drama,war
.notnone of the listed valuescountry.not=us
.gte, .lteat least, at mostyear.gte=1990&year.lte=1999

A number without an operator is an exact value: year=1999 is the same as year.gte=1999&year.lte=1999. Conditions on different filters combine with "and".

What you can filter

groupfilters
IDsimdb_id, kp_id, tmdb_id, tmdb_tv_id
Kindkind, is_series, adult
Datesyear, release_date, premiere_world, premiere_ru, digital_release, released, start_year, end_year
Ratings and votesrating, 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
Contentgenre, tag, country, region, original_language, runtime
Companiescompanies, company.kind, platform
Peopleperson, person.role
Collections and franchisescollection, franchise
Seriesseasons_total, episodes_total
Moneybudget, box_office_us, revenue_world
Awardswins_imdb, oscars_won
Age ratingage_limit, age_limit_max, mpaa
Data completenessrequired, has_poster

GET /filters returns the values for genre, country, region, platform, tag and companies with title counts, in the value field. GET /enums returns the labels of every enum, the sort keys and the fields names.

Sorting

?sort=-rating_imdb          descending
?sort=+year                 ascending
?sort=-rating_imdb,+year    the second key breaks ties in the first

The sign is the direction; no sign means descending. Keys: 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. The money and award names match the title card.

You can send the + sign as is: sort=+year and sort=%2Byear work the same.

  • Without sort the catalog goes by popularity: the vote total across all sources. Titles without votes, announcements included, come last.
  • With a search q the default is relevance.
  • Sorting by a field keeps only titles that have it. Collections, relations and filmographies are the exception: there, titles without the value stay at the end.
  • sort=rating takes a title's first known rating (IMDb, then Kinopoisk, then TMDB) and puts titles with 50 or more votes above the rest.
  • sort=rating_weighted is the average of the Kinopoisk, IMDb and TMDB ratings, weighted by vote count: a rating more people stand behind weighs more.
  • sort=divergence orders by the gap between the Kinopoisk and IMDb ratings: with no sign or with -, largest gaps first; +divergence puts the closest ratings first. More in Rating divergence.
  • sort=popularity orders by the vote total across all sources. The popularity filter and the card's ratings.popularity are a different number: TMDB's popularity index.
  • sort=random shuffles the set. It can't be paged; repeat the request for a fresh draw.

Ratings: set a vote threshold

The card has no overall score on purpose: sources have different scales and audiences, and an average would hide that. For sorting there is rating_weighted, an average weighted by vote count, but set a threshold with it too. Sorting by a single rating without a vote threshold lifts titles rated by a handful of people to the top: IMDb and TMDB accept votes before release, so even an unreleased film can get a 10 from one viewer. Set the threshold explicitly:

?rating_imdb.gte=8&votes_imdb.gte=100000&sort=-rating_imdb

Every source with votes has a threshold: votes_imdb, votes_kp, votes_tmdb, votes_kr (Kinorium), votes_letterboxd.

The rating window

When several audiences need to agree, use the window:

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"
Response200
{
  "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
}
parametermeaning
rating_min, rating_maxThe window's bounds.
rating_sourcesWhose ratings to check: kp, imdb, tmdb, kr (Kinorium), letterboxd. The first three by default.
rating_matchall: every listed source must fall in the window. Without it, any one is enough.

People and companies

person picks titles a person worked on. Pass the ID with its catalog and a colon: kp:41477, imdb:nm0634240, tmdb:525, kinorium:476400. Several people separated by commas means any of them; repeating the parameter means all of them: person=kp:37859&person=kp:41477 gives titles with both DiCaprio and Nolan. person.role narrows the role and returns 400 without person:

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"
Response200
{
  "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 searches by company name, company.kind by the company's role: production, studio, network, special_effects, distributor_theatrical, distributor_online, dubbing. Together they answer "where was HBO the network": companies=HBO&company.kind=network.

Age ratings and release

  • age_limit is the Russian age rating: 0, 6, 12, 16, 18. A comma-separated list (age_limit=12,16) or a range (age_limit.gte=16). age_limit_max=12 is the same as age_limit.lte=12. Titles without a rating never match: an unknown rating isn't zero.
  • mpaa is the US certificate: G, PG, PG-13, R, NC-17 and the TV-* family. A title has one certificate, so for "any of" write mpaa=R,NC-17.
  • released=true is out already, released=false is upcoming. A title counts as upcoming if its release date or year is later than today.

Ready-made sets: preset

A preset is a named set of filters. Explicit parameters refine it: preset=top&votes_imdb.gte=500000 is stricter than the usual top. order=asc reverses the preset’s sort (preset=top&order=asc starts with the lowest ratings), while sort replaces it entirely.

presetwhat's inside
topsort=-rating_imdb, votes_imdb.gte=100000, has a Kinopoisk rating and a poster
hidden_gemseverything but shorts and TV shows: 1,000–50,000 Kinopoisk votes and 1,000–25,000 IMDb votes, no concerts, stand-up, stage recordings, music or documentaries, sort=-rating_weighted
trendingreleased, sort=-popularity
newreleased in the last 30 days, sort=-release_date
classicsup to 1980, 50,000+ IMDb votes, sort=-rating_imdb
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"
Response200
{
  "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
}

Collections and franchises

  • collection picks the titles of one of our collections by its slug: collection=popular-titles. The list of collections is GET /collections. An unknown collection returns 400 with the list of existing ones.
  • franchise picks a franchise's titles by part of its TMDB name: franchise=matrix.

Data completeness

required keeps titles that have every listed field filled: required=poster,rating_imdb or required=kinorium_id. has_poster=true does the same for the poster alone.

In other lists

The same filters and sort work in collections, relations, filmographies, shared titles and discovery feeds, and the filters work in the release calendar too. For example, Christopher Nolan's movies with 100,000 votes or more, by IMDb rating:

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"
Response200
{
  "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
}

Presets work too: preset=top in a filmography puts the best IMDb-rated titles first. In filmographies and shared titles the default order runs from newest to oldest, and order=asc reverses it.

Mistakes in a request

An unknown filter or operator returns 400 instead of being ignored: a silently dropped filter would look like a filter that everything matched. When the fix is obvious, the API suggests it in hint. There is no status filter; ask about release status with released:

curl -G -H "X-API-Key: $KINODATA_KEY" \
  --data-urlencode "status=released" \
  "https://api.kinodata.space/v1.3/titles"
Response400
{
  "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"
  }
}

A parameter that takes one value can’t be repeated: kind=movie&kind=series returns 400 too. Put several values in one parameter, separated by commas: kind=movie,series. The exception is person: repeating it means “all of these people”.

Next

Esc

Loading the index…

    ↑ ↓ to selectEnter to openEsc to close