Discover API

Discover выводит фильмы через GET /3/discover/movie и сериалы через GET /3/discover/tv с фильтрами и сортировкой по вашим параметрам: жанр, актеры, съемочная группа, студия, ключевое слово, даты, рейтинг, голоса, длительность, язык и стриминговый провайдер. JSON совпадает с TMDB v3, результаты кэшируются на 30 минут.

Обновлено Открыть в Markdown

Discover для фильмов

GET /3/discover/movie возвращает постраничный список фильмов, которые соответствуют всем переданным фильтрам, в выбранном вами порядке. Этот эндпоинт подходит для страниц просмотра, подборок «лучшее» и рекомендаций по признакам, а текст query ему не нужен. Если пользователь ввел название, используйте поиск.

Пример выводит научно-фантастические фильмы (ID жанра 878) не менее чем с 1000 голосов, сначала с лучшей оценкой.

bashjspyphpgo
curl -sSf --get "https://api.amodb.dev/3/discover/movie" \
  --data-urlencode "with_genres=878" \
  --data-urlencode "sort_by=vote_average.desc" \
  --data-urlencode "vote_count.gte=1000" \
  --data-urlencode "language=en-US" \
  -H "Authorization: Bearer $AMODB_KEY"
const params = new URLSearchParams({
  with_genres: '878',
  sort_by: 'vote_average.desc',
  'vote_count.gte': '1000',
  language: 'en-US',
});
const res = await fetch(`https://api.amodb.dev/3/discover/movie?${params}`, {
  headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { results, total_pages } = await res.json();
console.log(`page 1 of ${total_pages}`);
for (const m of results.slice(0, 5)) console.log(m.vote_average, m.title, m.release_date);
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/discover/movie",
    params={
        "with_genres": 878,
        "sort_by": "vote_average.desc",
        "vote_count.gte": 1000,
        "language": "en-US",
    },
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
data = r.json()
print("page 1 of", data["total_pages"])
for m in data["results"][:5]:
    print(m["vote_average"], m["title"], m["release_date"])
<?php
$url = 'https://api.amodb.dev/3/discover/movie?' . http_build_query([
    'with_genres' => 878,
    'sort_by' => 'vote_average.desc',
    'vote_count.gte' => 1000,
    'language' => 'en-US',
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
    throw new RuntimeException("amodb returned $status");
}
$data = json_decode($body, true);
foreach (array_slice($data['results'], 0, 5) as $m) {
    echo $m['vote_average'], ' ', $m['title'], PHP_EOL;
}
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"time"
)

type Page struct {
	TotalPages int `json:"total_pages"`
	Results    []struct {
		Title       string  `json:"title"`
		ReleaseDate string  `json:"release_date"`
		VoteAverage float64 `json:"vote_average"`
	} `json:"results"`
}

func main() {
	q := url.Values{
		"with_genres":    {"878"},
		"sort_by":        {"vote_average.desc"},
		"vote_count.gte": {"1000"},
		"language":       {"en-US"},
	}
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/discover/movie?"+q.Encode(), nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	client := &http.Client{Timeout: 10 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic(res.Status)
	}
	var p Page
	if err := json.NewDecoder(res.Body).Decode(&p); err != nil {
		panic(err)
	}
	fmt.Println("pages:", p.TotalPages)
	for _, m := range p.Results {
		fmt.Println(m.VoteAverage, m.Title, m.ReleaseDate)
	}
}

Параметры

  • api_keyстрока запросаодин из двух
    Ваш ключ. Используйте его или заголовок Authorization: Bearer.
  • sort_byстрока запроса
    Поле и направление, например vote_average.desc. Поля: popularity, vote_average, vote_count, primary_release_date, revenue, title, original_title, каждое с .asc или .desc. title и original_title оба сортируют по оригинальному названию. Неизвестное значение заменяется на popularity.desc, это же значение по умолчанию.
  • with_genresстрока запроса
    ID жанров. Запятая означает AND, вертикальная черта означает OR.
  • without_genresстрока запроса
    ID жанров, которые нужно исключить.
  • with_cast, with_crewстрока запроса
    ID персон. Найдите их через поиск.
  • with_peopleстрока запроса
    ID персон, которые участвуют как актеры или как съемочная группа.
  • with_companies, without_companiesстрока запроса
    ID кинокомпаний, которые нужно требовать или исключить. Запятая и вертикальная черта работают так же, как в with_genres.
  • with_keywords, without_keywordsстрока запроса
    ID ключевых слов, которые нужно требовать или исключить. См. ключевые слова.
  • with_origin_countryстрока запроса
    2-буквенный код страны производства в верхнем регистре, например FR.
  • primary_release_yearстрока запроса
    Год основной даты выхода из четырех цифр.
  • yearстрока запроса
    Год из четырех цифр. Совпадает с любой датой выхода в этом году, поэтому возвращает больше проектов, чем primary_release_year.
  • primary_release_date.gte, primary_release_date.lteстрока запроса
    Нижняя и верхняя граница основной даты выхода, YYYY-MM-DD.
  • release_date.gte, release_date.lteстрока запроса
    Нижняя и верхняя граница любой даты выхода в любой стране, YYYY-MM-DD.
  • regionстрока запроса
    2-буквенный код страны в верхнем регистре. Заменяет release_date в каждом результате датой выхода в этой стране. Проекты из выдачи не убирает.
  • certification_country, certificationстрока запроса
    Фильтр по возрастному рейтингу, например US и PG. Без страны certification игнорируется. certification.gte и certification.lte задают диапазон.
  • vote_average.gte, vote_average.lteстрока запроса
    Минимальная и максимальная средняя оценка, от 0 до 10.
  • vote_count.gte, vote_count.lteстрока запроса
    Минимальное и максимальное число голосов.
  • with_runtime.gte, with_runtime.lteстрока запроса
    Минимальная и максимальная длительность в минутах.
  • with_original_languageстрока запроса
    Язык оригинала в виде 2-буквенного кода, например fr или ko.
  • with_watch_providersстрока запроса
    ID провайдеров. Требует watch_region, без него игнорируется. ID берите на странице жанры и справочники.
  • watch_regionстрока запроса
    2-буквенный код страны в верхнем регистре для доступности у провайдера.
  • include_adultстрока запроса
    Принимается и игнорируется. Проекты для взрослых никогда не возвращаются.
  • languageстрока запроса
    Тег TMDB, например en-US или pl-PL. Поддерживаются 14 базовых языков. По умолчанию en-US.
  • pageстрока запроса
    Номер страницы от 1 до 500. По умолчанию 1.

Поля ответа

ПолеТипПримечания
page, total_pages, total_resultsцелое числоПостраничная информация для этого набора фильтров. Широкие фильтры сообщают не больше 1001 страницы и 20001 результата, но читать можно только страницы с 1 по 500.
resultsмассивДо 20 фильмов. Пустой, если ни один проект не соответствует всем фильтрам.
idцелое числоID фильма для запроса сведений о фильме.
title, original_title, overviewстрокаЛокализованный текст и оригинальное название.
original_languageстрокаДвухбуквенный код языка, на котором снят фильм.
release_dateстрокаYYYY-MM-DD.
genre_idsмассив целых чиселТолько ID. Сопоставьте их с названиями через /genre/movie/list.
poster_path, backdrop_pathстрока или nullДобавьте к https://img.amodb.dev/t/p/{size}.
vote_average, vote_count, popularityчислоОценка и значения ранжирования.
adult, videoлогическоеadult всегда равно false.

Пример ответа

JSON
{
  "page": 1,
  "results": [
    {
      "adult": false,
      "backdrop_path": "/wLWvHcQz7N13DvSOTV7bHgwGXpT.jpg",
      "genre_ids": [878, 12],
      "id": 687163,
      "original_language": "en",
      "original_title": "Project Hail Mary",
      "overview": "Science teacher Ryland Grace wakes up on a spaceship light years from home with no recollection of who he i...",
      "popularity": 101.0341,
      "poster_path": "/yihdXomYb5kTeSivtFndMy5iDmf.jpg",
      "release_date": "2026-03-15",
      "title": "Project Hail Mary",
      "video": false,
      "vote_average": 8.635,
      "vote_count": 8354
    },
    {
      "adult": false,
      "backdrop_path": "/Ys8UIGWJpd2TMuQk8fU77W3mBz.jpg",
      "genre_ids": [12, 18, 878],
      "id": 157336,
      "original_language": "en",
      "original_title": "Interstellar",
      "overview": "The adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitatio...",
      "popularity": 74.3949,
      "poster_path": "/yQvGrMoipbRoddT0ZR8tPoR7NfX.jpg",
      "release_date": "2014-11-04",
      "title": "Interstellar",
      "video": false,
      "vote_average": 8.491,
      "vote_count": 41526
    },
    {
      "adult": false,
      "backdrop_path": "/tanwf7KOwQ6dxZzehKsXkffIJOd.jpg",
      "genre_ids": [878, 28, 12],
      "id": 969681,
      "original_language": "en",
      "original_title": "Spider-Man: Brand New Day",
      "overview": "Fighting crime full-time as Spider-Man in a world that doesn't remember him...",
      "popularity": 663.5004,
      "poster_path": "/bjiS5ipwxb9JFy3XRRN4OAilSeX.jpg",
      "release_date": "2026-07-29",
      "title": "Spider-Man: Brand New Day",
      "video": false,
      "vote_average": 8.468,
      "vote_count": 5684
    }
  ],
  "total_pages": 39,
  "total_results": 772
}

Ответ получен из рабочего API для запроса из примера. Он сокращен до 3 из 20 записей на странице 1, а длинные строки overview укорочены.

Комбинирование фильтров

Отдельные параметры объединяются через AND. Внутри одного параметра запятая означает AND, а вертикальная черта означает OR. В сыром URL черта записывается как %7C, а клиенты, которые кодируют значения запроса, делают это за вас.

ЦельЗапрос
Лучшая научная фантастика с достаточным числом голосов/discover/movie?with_genres=878&sort_by=vote_average.desc&vote_count.gte=1000
Боевик или приключения/discover/movie?with_genres=28%7C12
Боевик, но не анимация/discover/movie?with_genres=28&without_genres=16
Один актер с одним режиссером/discover/movie?with_cast=6193&with_crew=525
Длинные фильмы одного года/discover/movie?primary_release_year=2010&with_runtime.gte=150
Выходы в окне дат/discover/movie?primary_release_date.gte=2026-10-01&primary_release_date.lte=2026-10-31
Фильмы на одном языке оригинала/discover/movie?with_original_language=fr
Стриминг в одной стране/discover/movie?with_watch_providers=8&watch_region=US
Рейтинг R в США/discover/movie?certification_country=US&certification=R
С одним ключевым словом и без другого/discover/movie?with_keywords=818&without_keywords=4565

with_original_language фильтрует по языку, на котором снят проект, и принимает коды вне 14 поддерживаемых языков, например ja или ko. Язык возвращаемого текста по-прежнему определяет параметр language. В строке с провайдером 8 это Netflix. ID провайдеров читайте из /watch/providers/movie.

Discover для сериалов

GET /3/discover/tv использует ту же оболочку ответа и тот же постраничный вывод. Записи содержат name, original_name, first_air_date, origin_country и genre_ids, а ID жанров берутся из /genre/tv/list, где собраны объединенные ID сериалов, например 10765 для Sci-Fi и фэнтези.

ПараметрОписание
first_air_date.gte, first_air_date.lteНижняя и верхняя граница даты первого эфира, YYYY-MM-DD.
first_air_date_yearГод даты первого эфира из четырех цифр.
air_date.gte, air_date.lteНижняя и верхняя граница дат, когда у сериала выходят серии в эфир, YYYY-MM-DD.
with_networksID телесетей. Найдите их на странице компании и телесети.
with_statusЧисловой код статуса: 0 сериал продолжается, 2 в производстве, 3 завершен, 4 отменен.
with_typeЧисловой тип сериала: 0 документальный, 1 новости, 2 мини-сериал, 3 реалити, 4 игровой, 5 ток-шоу, 6 видео.
sort_bypopularity, vote_average, vote_count, first_air_date, name или original_name, каждое с .asc или .desc. name и original_name оба сортируют по оригинальному названию.
with_genres, without_genres, with_companies, with_keywords, without_keywordsТе же правила, что и для фильмов.
vote_average.gte, vote_count.gte, with_runtime.gte, with_runtime.lte, with_original_languageТе же правила, что и для фильмов.
with_watch_providers, watch_region, language, pageТе же правила, что и для фильмов.

Запрос вида /discover/tv?first_air_date.gte=2025-01-01&with_genres=18&vote_count.gte=100&sort_by=popularity.desc выводит драматические сериалы, которые начались в 2025 году или позже. Подробности о результате смотрите на странице сериалы.

Ошибки

HTTPstatus_codeКогда
4017Ключ отсутствует или неверен.
40236Срок действия тарифа закончился.
40537Вы вызвали метод записи.
42925Превышен лимит запросов в минуту. Подождите столько секунд, сколько указано в Retry-After.
50011Значение page вне диапазона от 1 до 500.
50424Бэкенд не ответил вовремя. Повторите запрос один раз.

Набор фильтров, которому ничего не соответствует, не считается ошибкой. Вы получите HTTP 200 с пустым массивом results и total_results, равным 0. См. ошибки и лимиты запросов.

Практические замечания

  • Edge-серверы кэшируют каждый уникальный набор фильтров на 30 минут и делят его между ключами. Ключ кэша строится по отсортированному запросу, поэтому порядок ваших параметров не важен.
  • На странице 20 записей, а последняя страница имеет номер 500, поэтому один набор фильтров охватывает 10,000 записей. Чтобы зайти глубже, режьте выборку по окнам дат. Широкий фильтр сообщает total_results равным 20001, это предел, а не реальное количество.
  • Всегда сочетайте sort_by=vote_average.desc с vote_count.gte. Без него наверх попадают проекты с несколькими голосами.
  • ID в фильтрах числовые. ID персон берите через поиск, а ID жанров и провайдеров на странице жанры и справочники.
  • Готовые списки, например популярные или идущие сейчас в кино, смотрите на странице списки трендов.