Discover API
Discover выводит фильмы через GET /3/discover/movie и сериалы через GET /3/discover/tv с фильтрами и сортировкой по вашим параметрам: жанр, актеры, съемочная группа, студия, ключевое слово, даты, рейтинг, голоса, длительность, язык и стриминговый провайдер. JSON совпадает с TMDB v3, результаты кэшируются на 30 минут.
Discover для фильмов
GET /3/discover/movie возвращает постраничный список фильмов, которые соответствуют всем переданным фильтрам, в выбранном вами порядке. Этот эндпоинт подходит для страниц просмотра, подборок «лучшее» и рекомендаций по признакам, а текст query ему не нужен. Если пользователь ввел название, используйте поиск.
Пример выводит научно-фантастические фильмы (ID жанра 878) не менее чем с 1000 голосов, сначала с лучшей оценкой.
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:/. |
vote_average, vote_count, popularity | число | Оценка и значения ранжирования. |
adult, video | логическое | adult всегда равно false. |
Пример ответа
{
"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, а клиенты, которые кодируют значения запроса, делают это за вас.
| Цель | Запрос |
|---|---|
| Лучшая научная фантастика с достаточным числом голосов | / |
| Боевик или приключения | / |
| Боевик, но не анимация | / |
| Один актер с одним режиссером | / |
| Длинные фильмы одного года | / |
| Выходы в окне дат | / |
| Фильмы на одном языке оригинала | / |
| Стриминг в одной стране | / |
| Рейтинг R в США | / |
| С одним ключевым словом и без другого | / |
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_networks | ID телесетей. Найдите их на странице компании и телесети. |
with_status | Числовой код статуса: 0 сериал продолжается, 2 в производстве, 3 завершен, 4 отменен. |
with_type | Числовой тип сериала: 0 документальный, 1 новости, 2 мини-сериал, 3 реалити, 4 игровой, 5 ток-шоу, 6 видео. |
sort_by | popularity, 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 | Те же правила, что и для фильмов. |
Запрос вида / выводит драматические сериалы, которые начались в 2025 году или позже. Подробности о результате смотрите на странице сериалы.
Ошибки
| HTTP | status_code | Когда |
|---|---|---|
| 401 | 7 | Ключ отсутствует или неверен. |
| 402 | 36 | Срок действия тарифа закончился. |
| 405 | 37 | Вы вызвали метод записи. |
| 429 | 25 | Превышен лимит запросов в минуту. Подождите столько секунд, сколько указано в Retry-After. |
| 500 | 11 | Значение page вне диапазона от 1 до 500. |
| 504 | 24 | Бэкенд не ответил вовремя. Повторите запрос один раз. |
Набор фильтров, которому ничего не соответствует, не считается ошибкой. Вы получите 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 жанров и провайдеров на странице жанры и справочники.
- Готовые списки, например популярные или идущие сейчас в кино, смотрите на странице списки трендов.