Discover API
Discover wypisuje filmy pod GET /3/discover/movie i seriale pod GET /3/discover/tv, filtrowane i sortowane według wybranych parametrów: gatunek, obsada, ekipa, firma, słowo kluczowe, daty, ocena, głosy, czas trwania, język i dostawca streamingu. JSON odpowiada TMDB v3, a wyniki są w cache przez 30 minut.
Discover dla filmów
GET /3/discover/movie zwraca listę z paginacją filmów pasujących do wszystkich wysłanych filtrów, w wybranej kolejności. To endpoint do stron przeglądania, list „najlepszych” i rekomendacji według faset i nie potrzebuje tekstu query. Gdy masz tytuł wpisany przez użytkownika, użyj zamiast niego wyszukiwania.
Przykład wypisuje filmy science fiction (ID gatunku 878) z co najmniej 1000 głosów, najlepiej oceniane na początku.
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)
}
}Parametry
api_keyqueryjeden z dwóchTwój klucz. Użyj go albo nagłówkaAuthorization: Bearer.sort_byqueryPole i kierunek, na przykładvote_average.desc. Pola:popularity,vote_average,vote_count,primary_release_date,revenue,title,original_title, każde z.asclub.desc.titleioriginal_titlesortują według tytułu oryginalnego. Nieznana wartość wraca dopopularity.desc, które jest też domyślne.with_genresqueryID gatunków. Przecinek oznacza AND, znak kreski pionowej OR.without_genresqueryID gatunków do wykluczenia.with_cast,with_crewqueryID osób. Znajdziesz je przez wyszukiwanie.with_peoplequeryID osób, które występują jako obsada lub ekipa.with_companies,without_companiesqueryID firm produkcyjnych do wymagania lub wykluczenia. Przecinek i kreska pionowa działają jak wwith_genres.with_keywords,without_keywordsqueryID słów kluczowych do wymagania lub wykluczenia. Zobacz słowa kluczowe.with_origin_countryqueryDwuliterowy kod kraju produkcji wielkimi literami, na przykładFR.primary_release_yearqueryCzterocyfrowy rok głównej daty premiery.yearqueryCzterocyfrowy rok. Pasuje do dowolnej daty premiery w tym roku, więc zwraca więcej tytułów niżprimary_release_year.primary_,release_ date.gte primary_queryrelease_ date.lte Dolna i górna granica głównej daty premiery,YYYY-MM-DD.release_date.gte,release_date.ltequeryDolna i górna granica dowolnej daty premiery w dowolnym kraju,YYYY-MM-DD.regionqueryDwuliterowy kod kraju wielkimi literami. Zastępujerelease_datew każdym wyniku datą w tym kraju. Nie usuwa tytułów.certification_country,certificationqueryFiltr klasyfikacji wiekowej, na przykładUSiPG.certificationjest ignorowane bez kraju.certification.gteicertification.ltedają zakres.vote_average.gte,vote_average.ltequeryMinimalna i maksymalna średnia ocena, od 0 do 10.vote_count.gte,vote_count.ltequeryMinimalna i maksymalna liczba głosów.with_runtime.gte,with_runtime.ltequeryMinimalny i maksymalny czas trwania w minutach.with_original_languagequeryJęzyk oryginału jako dwuliterowy kod, na przykładfrlubko.with_watch_providersqueryID dostawców. Wymagawatch_regioni bez niego jest ignorowane. ID pochodzą ze strony gatunki i słowniki.watch_regionqueryDwuliterowy kod kraju wielkimi literami dla dostępności u dostawcy.include_adultqueryPrzyjmowany i ignorowany. Tytuły dla dorosłych nigdy nie są zwracane.languagequeryTag TMDB, na przykładen-USlubpl-PL. Obsługiwanych jest 14 języków bazowych. Domyślnieen-US.pagequeryNumer strony od 1 do 500. Domyślnie 1.
Pola odpowiedzi
| Pole | Typ | Uwagi |
|---|---|---|
page, total_pages, total_results | integer | Paginacja dla tego zestawu filtrów. Szerokie filtry zgłaszają najwyżej 1001 stron i 20001 wyników, ale czytać można tylko strony od 1 do 500. |
results | array | Do 20 filmów. Puste, gdy żaden tytuł nie spełnia wszystkich filtrów. |
id | integer | ID filmu dla szczegółów filmu. |
title, original_title, overview | string | Tekst zlokalizowany i tytuł oryginalny. |
original_language | string | Dwuliterowy kod języka, w którym nakręcono film. |
release_date | string | YYYY-MM-DD. |
genre_ids | array of integers | Tylko ID. Zamień je na nazwy przez /genre/movie/list. |
poster_path, backdrop_path | string lub null | Dołącz do https:/. |
vote_average, vote_count, popularity | number | Ocena i wartości rankingowe. |
adult, video | boolean | adult jest zawsze false. |
Przykładowa odpowiedź
{
"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
}Odpowiedź pobrano z działającego API dla przykładowego żądania. Jest przycięta do 3 z 20 pozycji na stronie 1, a długie ciągi overview skrócono.
Łączenie filtrów
Osobne parametry łączą się przez AND. W jednym parametrze przecinek oznacza AND, a znak kreski pionowej OR. W surowym URL kreska pionowa to %7C, a klienty kodujące wartości zapytania robią to za ciebie.
| Cel | Żądanie |
|---|---|
| Najlepiej oceniane sci-fi z wystarczającą liczbą głosów | / |
| Akcja lub przygoda | / |
| Akcja, ale nie animacja | / |
| Jeden aktor z jednym reżyserem | / |
| Długie filmy z jednego roku | / |
| Premiery w oknie dat | / |
| Filmy w jednym języku oryginału | / |
| Streaming w jednym kraju | / |
| Z klasyfikacją R w USA | / |
| Bez słowa kluczowego | / |
with_original_language filtruje według języka, w którym nakręcono tytuł, i przyjmuje też kody spoza 14 obsługiwanych języków, na przykład ja lub ko. Język zwracanego tekstu nadal ustala parametr language. W wierszu z dostawcą 8 to Netflix. ID dostawców odczytaj z /watch/providers/movie.
Discover dla seriali
GET /3/discover/tv używa tej samej koperty i paginacji. Pozycje zawierają name, original_name, first_air_date, origin_country i genre_ids, a ID gatunków pochodzą z /genre/tv/list, który zawiera połączone ID seriali, na przykład 10765 dla Sci-Fi i fantasy.
| Parametr | Opis |
|---|---|
first_air_date.gte, first_air_date.lte | Dolna i górna granica daty pierwszej emisji, YYYY-MM-DD. |
first_air_date_year | Czterocyfrowy rok daty pierwszej emisji. |
air_date.gte, air_date.lte | Dolna i górna granica dat, w których serial ma emitowane odcinki, YYYY-MM-DD. |
with_networks | ID sieci. Znajdziesz je na stronie firmy i sieci telewizyjne. |
with_status | Numeryczny kod statusu: 0 serial powracający, 2 w produkcji, 3 zakończony, 4 anulowany. |
with_type | Numeryczny typ programu: 0 dokument, 1 wiadomości, 2 miniserial, 3 reality, 4 fabularny, 5 talk show, 6 wideo. |
sort_by | popularity, vote_average, vote_count, first_air_date, name lub original_name, każde z .asc lub .desc. name i original_name sortują według nazwy oryginalnej. |
with_genres, without_genres, with_companies, with_keywords, without_keywords | Te same zasady co dla filmów. |
vote_average.gte, vote_count.gte, with_runtime.gte, with_runtime.lte, with_original_language | Te same zasady co dla filmów. |
with_watch_providers, watch_region, language, page | Te same zasady co dla filmów. |
Żądanie takie jak / wypisuje seriale dramatyczne, które wystartowały w 2025 roku lub później. Wynik szczegółowo omawia strona seriale.
Błędy
| HTTP | status_code | Kiedy |
|---|---|---|
| 401 | 7 | Brakuje klucza lub jest błędny. |
| 402 | 36 | Okres planu dobiegł końca. |
| 405 | 37 | Wywołano metodę zapisu. |
| 429 | 25 | Przekroczono limit żądań na minutę. Poczekaj tyle sekund, ile podaje Retry-After. |
| 500 | 11 | Wartość page spoza zakresu od 1 do 500. |
| 504 | 24 | Backend nie odpowiedział na czas. Spróbuj jeszcze raz. |
Zestaw filtrów, który nic nie znajduje, nie jest błędem. Dostajesz HTTP 200 z pustą tablicą results i total_results równym 0. Zobacz błędy i limity żądań.
Praktyczne uwagi
- Edge trzyma w cache każdy odrębny zestaw filtrów przez 30 minut i współdzieli go między kluczami. Klucz cache używa posortowanego zapytania, więc kolejność parametrów nie ma znaczenia.
- Strona ma 20 pozycji, a ostatnia to 500, więc jeden zestaw filtrów sięga 10 000 pozycji. Aby pójść głębiej, dziel według okien dat. Szeroki filtr zgłasza
total_resultsrówne 20001, co jest limitem, a nie prawdziwą liczbą. - Zawsze łącz
sort_zby= vote_ average.desc vote_count.gte. Bez tego na górze tłoczą się tytuły z kilkoma głosami. - ID w filtrach są numeryczne. ID osób pobierz przez wyszukiwanie, a ID gatunków i dostawców ze strony gatunki i słowniki.
- Gotowe listy, takie jak popularne lub aktualnie w kinach, znajdziesz na stronie trendy i listy.