API Discover

Discover liste les films sur GET /3/discover/movie et les séries sur GET /3/discover/tv, filtrés et triés selon les paramètres choisis : genre, distribution, équipe, société, mot-clé, dates, note, votes, durée, langue et plateforme de streaming. Le JSON suit TMDB v3, et les résultats sont mis en cache 30 minutes.

Mis à jour le Voir en Markdown

Découvrir des films

GET /3/discover/movie renvoie une liste paginée de films qui correspondent à tous les filtres envoyés, dans l'ordre choisi. C'est le point de terminaison des pages de navigation, des listes de meilleurs films et des recommandations par facette, et il n'a besoin d'aucun texte query. Quand un utilisateur a saisi un titre, utilisez plutôt recherche.

L'exemple liste les films de science-fiction (genre 878) avec au moins 1000 votes, les mieux notés en premier.

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

Paramètres

  • api_keyrequêtel'un des deux
    Votre clé. Utilisez-la ou l'en-tête Authorization: Bearer.
  • sort_byrequête
    Champ et sens comme vote_average.desc. Champs : popularity, vote_average, vote_count, primary_release_date, revenue, title, original_title, chacun avec .asc ou .desc. title et original_title trient tous deux par titre original. Une valeur inconnue se replie sur popularity.desc, qui est aussi la valeur par défaut.
  • with_genresrequête
    Identifiants de genres. Une virgule signifie ET, une barre verticale signifie OU.
  • without_genresrequête
    Identifiants de genres à exclure.
  • with_cast, with_crewrequête
    Identifiants de personnes. Trouvez-les avec recherche.
  • with_peoplerequête
    Identifiants de personnes qui apparaissent dans la distribution ou l'équipe.
  • with_companies, without_companiesrequête
    Identifiants de sociétés de production à exiger ou à exclure. La virgule et la barre verticale fonctionnent comme dans with_genres.
  • with_keywords, without_keywordsrequête
    Identifiants de mots-clés à exiger ou à exclure. Voir mots-clés.
  • with_origin_countryrequête
    Code pays de production à 2 lettres en majuscules comme FR.
  • primary_release_yearrequête
    Année à quatre chiffres de la date de sortie principale.
  • yearrequête
    Année à quatre chiffres. Correspond à n'importe quelle date de sortie de cette année, donc renvoie plus de titres que primary_release_year.
  • primary_release_date.gte, primary_release_date.lterequête
    Bornes inférieure et supérieure de la date de sortie principale, YYYY-MM-DD.
  • release_date.gte, release_date.lterequête
    Bornes inférieure et supérieure de n'importe quelle date de sortie dans n'importe quel pays, YYYY-MM-DD.
  • regionrequête
    Code pays à 2 lettres en majuscules. Remplace release_date dans chaque résultat par la date dans ce pays. Ne retire aucun titre.
  • certification_country, certificationrequête
    Filtre de classification par âge, par exemple US et PG. certification est ignoré sans pays. certification.gte et certification.lte donnent une plage.
  • vote_average.gte, vote_average.lterequête
    Note moyenne minimale et maximale, de 0 à 10.
  • vote_count.gte, vote_count.lterequête
    Nombre minimal et maximal de votes.
  • with_runtime.gte, with_runtime.lterequête
    Durée minimale et maximale en minutes.
  • with_original_languagerequête
    Langue originale sous forme de code à 2 lettres comme fr ou ko.
  • with_watch_providersrequête
    Identifiants de plateformes. Demande watch_region et est ignoré sans lui. Les identifiants viennent de genres et listes de référence.
  • watch_regionrequête
    Code pays à 2 lettres en majuscules pour la disponibilité des plateformes.
  • include_adultrequête
    Accepté et ignoré. Les titres pour adultes ne sont jamais renvoyés.
  • languagerequête
    Balise TMDB comme en-US ou pl-PL. 14 langues de base sont servies. Par défaut en-US.
  • pagerequête
    Numéro de page de 1 à 500. Par défaut 1.

Champs de la réponse

ChampTypeRemarques
page, total_pages, total_resultsentierPagination pour ce jeu de filtres. Les filtres larges annoncent au plus 1001 pages et 20001 résultats, mais seules les pages 1 à 500 peuvent être lues.
resultstableauJusqu'à 20 films. Vide quand aucun titre ne correspond à tous les filtres.
identierIdentifiant du film pour les détails du film.
title, original_title, overviewchaîneTexte localisé et titre original.
original_languagechaîneCode à deux lettres de la langue dans laquelle le film a été tourné.
release_datechaîneYYYY-MM-DD.
genre_idstableau d'entiersIdentifiants seulement. Associez-les à des noms avec /genre/movie/list.
poster_path, backdrop_pathchaîne ou nullÀ ajouter à https://img.amodb.dev/t/p/{size}.
vote_average, vote_count, popularitynombreValeurs de note et de classement.
adult, videobooléenadult vaut toujours false.

Exemple de réponse

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 réponse a été récupérée depuis l'API réelle pour la requête d'exemple. Elle est réduite à 3 des 20 entrées de la page 1, et les longues chaînes overview sont raccourcies.

Combiner des filtres

Des paramètres distincts se combinent avec ET. À l'intérieur d'un paramètre, une virgule signifie ET et une barre verticale signifie OU. Dans une URL brute, la barre verticale s'écrit %7C, et les clients qui encodent les valeurs de requête le font pour vous.

ObjectifRequête
Meilleure science-fiction avec assez de votes/discover/movie?with_genres=878&sort_by=vote_average.desc&vote_count.gte=1000
Action ou aventure/discover/movie?with_genres=28%7C12
Action mais pas animation/discover/movie?with_genres=28&without_genres=16
Un acteur avec un réalisateur/discover/movie?with_cast=6193&with_crew=525
Films longs d'une année/discover/movie?primary_release_year=2010&with_runtime.gte=150
Sorties dans une fenêtre de dates/discover/movie?primary_release_date.gte=2026-10-01&primary_release_date.lte=2026-10-31
Films dans une langue originale/discover/movie?with_original_language=fr
En streaming dans un pays/discover/movie?with_watch_providers=8&watch_region=US
Classés R aux États-Unis/discover/movie?certification_country=US&certification=R
Sans un mot-clé/discover/movie?with_keywords=818&without_keywords=4565

with_original_language filtre par la langue dans laquelle un titre a été tourné, et il accepte des codes en dehors des 14 langues servies, par exemple ja ou ko. Le paramètre language décide toujours de la langue du texte renvoyé. Dans la ligne des plateformes, 8 est Netflix. Lisez les identifiants de plateformes dans /watch/providers/movie.

Découvrir des séries

GET /3/discover/tv utilise la même enveloppe et la même pagination. Les entrées contiennent name, original_name, first_air_date, origin_country et genre_ids, et les identifiants de genres viennent de /genre/tv/list, qui contient les identifiants TV fusionnés comme 10765 pour Sci-Fi et Fantasy.

ParamètreDescription
first_air_date.gte, first_air_date.lteBornes inférieure et supérieure de la date de première diffusion, YYYY-MM-DD.
first_air_date_yearAnnée à quatre chiffres de la date de première diffusion.
air_date.gte, air_date.lteBornes inférieure et supérieure des dates où une série a des épisodes diffusés, YYYY-MM-DD.
with_networksIdentifiants de chaînes. Trouvez-les sur sociétés et chaînes.
with_statusCode de statut numérique : 0 série en cours, 2 en production, 3 terminée, 4 annulée.
with_typeType de série numérique : 0 documentaire, 1 actualités, 2 mini-série, 3 téléréalité, 4 fiction, 5 talk-show, 6 vidéo.
sort_bypopularity, vote_average, vote_count, first_air_date, name ou original_name, chacun avec .asc ou .desc. name et original_name trient tous deux par nom original.
with_genres, without_genres, with_companies, with_keywords, without_keywordsMêmes règles que pour les films.
vote_average.gte, vote_count.gte, with_runtime.gte, with_runtime.lte, with_original_languageMêmes règles que pour les films.
with_watch_providers, watch_region, language, pageMêmes règles que pour les films.

Une requête comme /discover/tv?first_air_date.gte=2025-01-01&with_genres=18&vote_count.gte=100&sort_by=popularity.desc liste les séries dramatiques commencées en 2025 ou plus tard. Lisez un résultat en détail sur séries TV.

Erreurs

HTTPstatus_codeQuand
4017La clé est absente ou fausse.
40236La période de l'offre est terminée.
40537Vous avez appelé une méthode d'écriture.
42925Au-dessus de vos requêtes par minute. Attendez les secondes de Retry-After.
50011Une page en dehors de 1 à 500.
50424Le backend n'a pas répondu à temps. Réessayez une fois.

Un jeu de filtres qui ne correspond à rien n'est pas une erreur. Vous obtenez un HTTP 200 avec un tableau results vide et total_results à 0. Voir erreurs et limites de débit.

Remarques pratiques

  • La périphérie met en cache chaque jeu de filtres distinct 30 minutes et le partage entre les clés. La clé de cache utilise la requête triée : l'ordre de vos paramètres n'a donc pas d'importance.
  • Une page contient 20 entrées et la dernière page est la 500 : un jeu de filtres atteint donc 10 000 entrées. Découpez par fenêtres de dates pour aller plus loin. Un filtre large annonce un total_results de 20001, qui est un plafond et non un vrai compte.
  • Associez toujours sort_by=vote_average.desc à vote_count.gte. Sans cela, les titres ayant quelques votes encombrent le haut de la liste.
  • Les identifiants dans les filtres sont numériques. Prenez les identifiants de personnes dans recherche, et les identifiants de genres et de plateformes dans genres et listes de référence.
  • Pour des listes prêtes à l'emploi comme populaires ou à l'affiche, voir tendances et listes.