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_keyqueryодне з двох
    Ваш ключ. Використовуйте його або заголовок Authorization: Bearer.
  • sort_byquery
    Поле й напрямок, наприклад vote_average.desc. Поля: popularity, vote_average, vote_count, primary_release_date, revenue, title, original_title, кожне з .asc або .desc. title і original_title обидва сортують за оригінальною назвою. Невідоме значення відкочується на popularity.desc, це також значення за замовчуванням.
  • with_genresquery
    id жанрів. Кома означає І, вертикальна риска означає АБО.
  • without_genresquery
    id жанрів, які треба виключити.
  • with_cast, with_crewquery
    id персон. Знайдіть їх через пошук.
  • with_peoplequery
    id персон, які є в акторському складі або знімальній групі.
  • with_companies, without_companiesquery
    id кінокомпаній, які треба вимагати або виключити. Кома й вертикальна риска працюють так само, як у with_genres.
  • with_keywords, without_keywordsquery
    id ключових слів, які треба вимагати або виключити. Див. ключові слова.
  • with_origin_countryquery
    Дволітерний код країни виробництва великими літерами, наприклад FR.
  • primary_release_yearquery
    Чотирицифровий рік основної дати виходу.
  • yearquery
    Чотирицифровий рік. Збігається з будь-якою датою виходу в цьому році, тому повертає більше проєктів, ніж primary_release_year.
  • primary_release_date.gte, primary_release_date.ltequery
    Нижня й верхня межа основної дати виходу, YYYY-MM-DD.
  • release_date.gte, release_date.ltequery
    Нижня й верхня межа будь-якої дати виходу в будь-якій країні, YYYY-MM-DD.
  • regionquery
    Дволітерний код країни великими літерами. Замінює release_date у кожному результаті датою в цій країні. Проєкти він не прибирає.
  • certification_country, certificationquery
    Фільтр за віковим рейтингом, наприклад US і PG. certification ігнорується без країни. certification.gte та certification.lte задають діапазон.
  • vote_average.gte, vote_average.ltequery
    Мінімальна й максимальна середня оцінка, від 0 до 10.
  • vote_count.gte, vote_count.ltequery
    Мінімальна й максимальна кількість голосів.
  • with_runtime.gte, with_runtime.ltequery
    Мінімальна й максимальна тривалість у хвилинах.
  • with_original_languagequery
    Мова оригіналу як дволітерний код, наприклад fr або ko.
  • with_watch_providersquery
    id провайдерів. Потребує watch_region і без нього ігнорується. Id беріть зі сторінки жанри та довідкові списки.
  • watch_regionquery
    Дволітерний код країни великими літерами для доступності провайдера.
  • include_adultquery
    Приймається й ігнорується. Контент для дорослих ніколи не повертається.
  • languagequery
    Тег TMDB, наприклад en-US або pl-PL. Підтримується 14 базових мов. За замовчуванням en-US.
  • pagequery
    Номер сторінки від 1 до 500. За замовчуванням 1.

Поля відповіді

ПолеТипПримітки
page, total_pages, total_resultsintegerПосторінкові дані для цього набору фільтрів. Широкі фільтри повідомляють щонайбільше 1001 сторінку й 20001 результат, але прочитати можна лише сторінки від 1 до 500.
resultsarrayДо 20 фільмів. Порожній, якщо жоден проєкт не відповідає всім фільтрам.
idintegerid фільму для деталей фільму.
title, original_title, overviewstringЛокалізований текст і оригінальна назва.
original_languagestringДволітерний код мови, якою знято фільм.
release_datestringYYYY-MM-DD.
genre_idsarray of integersЛише id. Зіставте їх з назвами через /genre/movie/list.
poster_path, backdrop_pathstring або nullДодайте до https://img.amodb.dev/t/p/{size}.
vote_average, vote_count, popularitynumberОцінка та показники рейтингу.
adult, videobooleanadult завжди 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 обрізано.

Поєднання фільтрів

Окремі параметри поєднуються через І. Усередині одного параметра кома означає І, а вертикальна риска означає АБО. У сирому 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 для «НФ і фентезі».

ПараметрОпис
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. Див. помилки та ліміти запитів.

Практичні поради

  • CDN кешує кожен унікальний набір фільтрів на 30 хвилин і спільно використовує його для різних ключів. Ключ кешу будується з відсортованого запиту, тому порядок ваших параметрів не має значення.
  • Сторінка містить 20 записів, а остання сторінка має номер 500, тож один набір фільтрів дає 10 000 записів. Щоб зайти глибше, розбивайте запит на вікна дат. Широкий фільтр повідомляє total_results 20001, це обмеження, а не справжня кількість.
  • Завжди поєднуйте sort_by=vote_average.desc з vote_count.gte. Без нього нагору потрапляють проєкти з кількома голосами.
  • Id у фільтрах числові. Id персон беріть із пошуку, а id жанрів і провайдерів зі сторінки жанри та довідкові списки.
  • Готові списки, такі як популярні чи ті, що зараз у прокаті, дивіться на сторінці списки трендів.