API Discover

Discover elenca i film su GET /3/discover/movie e le serie TV su GET /3/discover/tv, filtrati e ordinati in base ai parametri scelti: genere, cast, troupe, società, parola chiave, date, voto, voti, durata, lingua e piattaforma di streaming. Il JSON segue TMDB v3, e i risultati restano in cache 30 minuti.

Aggiornato il Vedi in Markdown

Scoprire film

GET /3/discover/movie restituisce una lista paginata di film che corrispondono a tutti i filtri inviati, nell'ordine che scegli. È l'endpoint per le pagine di navigazione, le classifiche dei migliori e i consigli per sfaccettatura, e non richiede alcun testo query. Quando un utente ha digitato un titolo, usa invece ricerca.

L'esempio elenca i film di fantascienza (genere 878) con almeno 1000 voti, prima i meglio votati.

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)
	}
}

Parametri

  • api_keyqueryuno dei due
    La tua chiave. Usa questa o l'header Authorization: Bearer.
  • sort_byquery
    Campo e direzione come vote_average.desc. Campi: popularity, vote_average, vote_count, primary_release_date, revenue, title, original_title, ciascuno con .asc o .desc. title e original_title ordinano entrambi per titolo originale. Un valore sconosciuto ripiega su popularity.desc, che è anche il valore predefinito.
  • with_genresquery
    ID dei generi. Una virgola significa AND, una barra verticale significa OR.
  • without_genresquery
    ID dei generi da escludere.
  • with_cast, with_crewquery
    ID delle persone. Trovali con ricerca.
  • with_peoplequery
    ID delle persone che compaiono come cast o troupe.
  • with_companies, without_companiesquery
    ID delle case di produzione da richiedere o escludere. Virgola e barra verticale funzionano come in with_genres.
  • with_keywords, without_keywordsquery
    ID delle parole chiave da richiedere o escludere. Vedi parole chiave.
  • with_origin_countryquery
    Codice del paese di produzione di 2 lettere maiuscole come FR.
  • primary_release_yearquery
    Anno di quattro cifre della data di uscita principale.
  • yearquery
    Anno di quattro cifre. Corrisponde a qualsiasi data di uscita in quell'anno, quindi restituisce più titoli di primary_release_year.
  • primary_release_date.gte, primary_release_date.ltequery
    Limite inferiore e superiore della data di uscita principale, YYYY-MM-DD.
  • release_date.gte, release_date.ltequery
    Limite inferiore e superiore di qualsiasi data di uscita in qualsiasi paese, YYYY-MM-DD.
  • regionquery
    Codice paese di 2 lettere maiuscole. Sostituisce release_date in ogni risultato con la data in quel paese. Non rimuove titoli.
  • certification_country, certificationquery
    Filtro sulla classificazione per età, per esempio US e PG. certification viene ignorato senza paese. certification.gte e certification.lte danno un intervallo.
  • vote_average.gte, vote_average.ltequery
    Punteggio medio minimo e massimo, da 0 a 10.
  • vote_count.gte, vote_count.ltequery
    Numero minimo e massimo di voti.
  • with_runtime.gte, with_runtime.ltequery
    Durata minima e massima in minuti.
  • with_original_languagequery
    Lingua originale come codice di 2 lettere come fr o ko.
  • with_watch_providersquery
    ID delle piattaforme. Richiede watch_region e viene ignorato senza. Gli ID vengono da generi e liste di riferimento.
  • watch_regionquery
    Codice paese di 2 lettere maiuscole per la disponibilità delle piattaforme.
  • include_adultquery
    Accettato e ignorato. I titoli per adulti non vengono mai restituiti.
  • languagequery
    Tag TMDB come en-US o pl-PL. Sono servite 14 lingue di base. Predefinito en-US.
  • pagequery
    Numero di pagina da 1 a 500. Predefinito 1.

Campi della risposta

CampoTipoNote
page, total_pages, total_resultsinteroPaginazione per questo insieme di filtri. I filtri ampi dichiarano al massimo 1001 pagine e 20001 risultati, ma si possono leggere solo le pagine da 1 a 500.
resultsarrayFino a 20 film. Vuoto quando nessun titolo corrisponde a tutti i filtri.
idinteroID del film per i dettagli del film.
title, original_title, overviewstringaTesto localizzato e titolo originale.
original_languagestringaCodice di due lettere della lingua in cui è stato girato il film.
release_datestringaYYYY-MM-DD.
genre_idsarray di interiSolo ID. Associali ai nomi con /genre/movie/list.
poster_path, backdrop_pathstringa o nullDa accodare a https://img.amodb.dev/t/p/{size}.
vote_average, vote_count, popularitynumeroValori di punteggio e di classifica.
adult, videobooleanoadult è sempre false.

Risposta di esempio

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
}

La risposta è stata recuperata dall'API reale per la richiesta di esempio. È ridotta a 3 delle 20 voci della pagina 1, e le stringhe overview lunghe sono accorciate.

Combinare i filtri

Parametri separati si combinano con AND. All'interno di un parametro, una virgola significa AND e una barra verticale significa OR. In un URL grezzo la barra verticale si scrive %7C, e i client che codificano i valori di query lo fanno per te.

ObiettivoRichiesta
Fantascienza meglio votata con abbastanza voti/discover/movie?with_genres=878&sort_by=vote_average.desc&vote_count.gte=1000
Azione o avventura/discover/movie?with_genres=28%7C12
Azione ma non animazione/discover/movie?with_genres=28&without_genres=16
Un attore con un regista/discover/movie?with_cast=6193&with_crew=525
Film lunghi di un anno/discover/movie?primary_release_year=2010&with_runtime.gte=150
Uscite in una finestra di date/discover/movie?primary_release_date.gte=2026-10-01&primary_release_date.lte=2026-10-31
Film in una lingua originale/discover/movie?with_original_language=fr
In streaming in un paese/discover/movie?with_watch_providers=8&watch_region=US
Classificati R negli Stati Uniti/discover/movie?certification_country=US&certification=R
Senza una parola chiave/discover/movie?with_keywords=818&without_keywords=4565

with_original_language filtra per la lingua in cui è stato girato un titolo, e accetta codici fuori dalle 14 lingue servite, per esempio ja o ko. Il parametro language decide comunque la lingua del testo che ricevi. Nella riga delle piattaforme, 8 è Netflix. Leggi gli ID delle piattaforme da /watch/providers/movie.

Scoprire serie TV

GET /3/discover/tv usa la stessa busta e la stessa paginazione. Le voci contengono name, original_name, first_air_date, origin_country e genre_ids, e gli ID dei generi vengono da /genre/tv/list, che contiene gli ID TV unificati come 10765 per Sci-Fi e Fantasy.

ParametroDescrizione
first_air_date.gte, first_air_date.lteLimite inferiore e superiore della data di prima messa in onda, YYYY-MM-DD.
first_air_date_yearAnno di quattro cifre della data di prima messa in onda.
air_date.gte, air_date.lteLimite inferiore e superiore delle date in cui una serie ha episodi in onda, YYYY-MM-DD.
with_networksID delle emittenti. Trovali in società ed emittenti.
with_statusCodice di stato numerico: 0 serie in corso, 2 in produzione, 3 conclusa, 4 cancellata.
with_typeTipo numerico di serie: 0 documentario, 1 notiziario, 2 miniserie, 3 reality, 4 fiction, 5 talk show, 6 video.
sort_bypopularity, vote_average, vote_count, first_air_date, name o original_name, ciascuno con .asc o .desc. name e original_name ordinano entrambi per nome originale.
with_genres, without_genres, with_companies, with_keywords, without_keywordsStesse regole dei film.
vote_average.gte, vote_count.gte, with_runtime.gte, with_runtime.lte, with_original_languageStesse regole dei film.
with_watch_providers, watch_region, language, pageStesse regole dei film.

Una richiesta come /discover/tv?first_air_date.gte=2025-01-01&with_genres=18&vote_count.gte=100&sort_by=popularity.desc elenca le serie drammatiche iniziate nel 2025 o dopo. Leggi un risultato nel dettaglio in serie TV.

Errori

HTTPstatus_codeQuando
4017La chiave manca o è sbagliata.
40236Il periodo del piano è terminato.
40537Hai chiamato un metodo di scrittura.
42925Oltre le tue richieste al minuto. Attendi i secondi di Retry-After.
50011Una page fuori da 1-500.
50424Il backend non ha risposto in tempo. Riprova una volta.

Un insieme di filtri che non corrisponde a nulla non è un errore. Ottieni un HTTP 200 con un array results vuoto e total_results pari a 0. Vedi errori e limiti di richieste.

Note pratiche

  • L'edge mette in cache ogni insieme di filtri distinto per 30 minuti e lo condivide tra le chiavi. La chiave di cache usa la query ordinata, quindi l'ordine dei tuoi parametri non conta.
  • Una pagina contiene 20 voci e l'ultima pagina è la 500, quindi un insieme di filtri arriva a 10.000 voci. Dividi per finestre di date per andare più a fondo. Un filtro ampio dichiara un total_results di 20001, che è un tetto e non un conteggio reale.
  • Abbina sempre sort_by=vote_average.desc a vote_count.gte. Senza, i titoli con pochi voti affollano la cima.
  • Gli ID nei filtri sono numerici. Prendi gli ID delle persone da ricerca, e gli ID di generi e piattaforme da generi e liste di riferimento.
  • Per liste già pronte come i popolari o i film in sala, vedi tendenze e liste.