API Discover
Discover lista películas en GET /3/discover/movie y series de TV en GET /3/discover/tv, filtradas y ordenadas con los parámetros que elijas: género, reparto, equipo técnico, productora, palabra clave, fechas, puntuación, votos, duración, idioma y plataforma de streaming. El JSON coincide con TMDB v3 y los resultados se guardan en caché 30 minutos.
Descubrir películas
GET /3/discover/movie devuelve una lista paginada de películas que cumplen todos los filtros que envías, en el orden que elijas. Es el endpoint para páginas de exploración, listas de «lo mejor de» y recomendaciones por faceta, y no necesita texto en query. Cuando tengas un título escrito por un usuario, usa la búsqueda.
El ejemplo lista las películas de ciencia ficción (id de género 878) con al menos 1000 votos, las mejor valoradas primero.
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)
}
}Parámetros
api_keyconsultauno de los dosTu clave. Usa esta o el encabezadoAuthorization: Bearer.sort_byconsultaCampo y dirección comovote_average.desc. Campos:popularity,vote_average,vote_count,primary_release_date,revenue,title,original_title, cada uno con.asco.desc.titleyoriginal_titleordenan ambos por el título original. Un valor desconocido recurre apopularity.desc, que también es el valor por defecto.with_genresconsultaIds de género. Una coma significa AND, una barra vertical significa OR.without_genresconsultaIds de género que se excluyen.with_cast,with_crewconsultaIds de persona. Búscalos con la búsqueda.with_peopleconsultaIds de persona que aparecen en el reparto o en el equipo técnico.with_companies,without_companiesconsultaIds de productoras que se exigen o se excluyen. La coma y la barra vertical funcionan como enwith_genres.with_keywords,without_keywordsconsultaIds de palabras clave que se exigen o se excluyen. Consulta palabras clave.with_origin_countryconsultaCódigo de país de producción de 2 letras en mayúsculas, comoFR.primary_release_yearconsultaAño de cuatro dígitos de la fecha de estreno principal.yearconsultaAño de cuatro dígitos. Coincide con cualquier fecha de estreno de ese año, así que devuelve más títulos queprimary_release_year.primary_,release_ date.gte primary_consultarelease_ date.lte Límite inferior y superior de la fecha de estreno principal,YYYY-MM-DD.release_date.gte,release_date.lteconsultaLímite inferior y superior de cualquier fecha de estreno en cualquier país,YYYY-MM-DD.regionconsultaCódigo de país de 2 letras en mayúsculas. Sustituyerelease_dateen cada resultado por la fecha de ese país. No elimina títulos.certification_country,certificationconsultaFiltro de clasificación por edad, por ejemploUSyPG.certificationse ignora sin país.certification.gteycertification.ltedefinen un rango.vote_average.gte,vote_average.lteconsultaPuntuación media mínima y máxima, de 0 a 10.vote_count.gte,vote_count.lteconsultaNúmero mínimo y máximo de votos.with_runtime.gte,with_runtime.lteconsultaDuración mínima y máxima en minutos.with_original_languageconsultaIdioma original como código de 2 letras, por ejemplofroko.with_watch_providersconsultaIds de proveedores. Necesitawatch_regiony se ignora sin él. Los ids salen de géneros y listas de consulta.watch_regionconsultaCódigo de país de 2 letras en mayúsculas para la disponibilidad del proveedor.include_adultconsultaSe acepta y se ignora. Nunca se devuelven títulos para adultos.languageconsultaEtiqueta de TMDB comoen-USopl-PL. Se sirven 14 idiomas base. Valor por defectoen-US.pageconsultaNúmero de página de 1 a 500. Valor por defecto 1.
Campos de la respuesta
| Campo | Tipo | Notas |
|---|---|---|
page, total_pages, total_results | entero | Paginación de este conjunto de filtros. Los filtros amplios informan como máximo 1001 páginas y 20001 resultados, pero solo se pueden leer las páginas de 1 a 500. |
results | array | Hasta 20 películas. Vacío cuando ningún título cumple todos los filtros. |
id | entero | Id de película para los detalles de película. |
title, original_title, overview | texto | Texto localizado y título original. |
original_language | texto | Código de dos letras del idioma en que se hizo la película. |
release_date | texto | YYYY-MM-DD. |
genre_ids | array de enteros | Solo ids. Conviértelos en nombres con /genre/movie/list. |
poster_path, backdrop_path | texto o null | Añádelo a https:/. |
vote_average, vote_count, popularity | número | Valores de puntuación y de ranking. |
adult, video | booleano | adult es siempre false. |
Ejemplo de respuesta
{
"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 respuesta se obtuvo de la API real con la solicitud del ejemplo. Se corta a 3 de las 20 entradas de la página 1, y las cadenas overview largas se acortan.
Combinar filtros
Los parámetros separados se combinan con AND. Dentro de un mismo parámetro, una coma significa AND y una barra vertical significa OR. En una URL sin codificar la barra se escribe %7C, y los clientes que codifican los valores de consulta lo hacen por ti.
| Objetivo | Solicitud |
|---|---|
| Ciencia ficción mejor valorada con suficientes votos | / |
| Acción o aventura | / |
| Acción pero no animación | / |
| Un actor con un director | / |
| Películas largas de un año | / |
| Estrenos en una ventana de fechas | / |
| Películas en un idioma original | / |
| En streaming en un país | / |
| Clasificación R en Estados Unidos | / |
| Sin una palabra clave | / |
with_original_language filtra por el idioma en que se hizo un título, y acepta códigos fuera de los 14 idiomas servidos, por ejemplo ja o ko. El parámetro language sigue decidiendo el idioma del texto que recibes. En la fila de proveedores, 8 es Netflix. Lee los ids de proveedor de /watch/providers/movie.
Descubrir series de TV
GET /3/discover/tv usa la misma estructura de respuesta y la misma paginación. Las entradas traen name, original_name, first_air_date, origin_country y genre_ids, y los ids de género salen de /genre/tv/list, que contiene los ids de TV combinados, como 10765 para ciencia ficción y fantasía.
| Parámetro | Descripción |
|---|---|
first_air_date.gte, first_air_date.lte | Límite inferior y superior de la fecha de primera emisión, YYYY-MM-DD. |
first_air_date_year | Año de cuatro dígitos de la fecha de primera emisión. |
air_date.gte, air_date.lte | Límite inferior y superior de las fechas en que una serie tiene episodios en emisión, YYYY-MM-DD. |
with_networks | Ids de cadenas. Búscalos en productoras y cadenas de TV. |
with_status | Código de estado numérico: 0 serie que continúa, 2 en producción, 3 finalizada, 4 cancelada. |
with_type | Tipo numérico de programa: 0 documental, 1 noticias, 2 miniserie, 3 reality, 4 con guion, 5 programa de entrevistas, 6 vídeo. |
sort_by | popularity, vote_average, vote_count, first_air_date, name u original_name, cada uno con .asc o .desc. name y original_name ordenan ambos por el nombre original. |
with_genres, without_genres, with_companies, with_keywords, without_keywords | Mismas reglas que para las películas. |
vote_average.gte, vote_count.gte, with_runtime.gte, with_runtime.lte, with_original_language | Mismas reglas que para las películas. |
with_watch_providers, watch_region, language, page | Mismas reglas que para las películas. |
Una solicitud como / lista series de drama que empezaron en 2025 o después. Lee un resultado en detalle en series de TV.
Errores
| HTTP | status_code | Cuándo |
|---|---|---|
| 401 | 7 | La clave falta o es incorrecta. |
| 402 | 36 | El periodo del plan ha terminado. |
| 405 | 37 | Llamaste a un método de escritura. |
| 429 | 25 | Superaste tus solicitudes por minuto. Espera los segundos de Retry-After. |
| 500 | 11 | Un page fuera del rango de 1 a 500. |
| 504 | 24 | El backend no respondió a tiempo. Reintenta una vez. |
Un conjunto de filtros sin coincidencias no es un error. Recibes HTTP 200 con un array results vacío y total_results en 0. Consulta errores y límites de solicitudes.
Notas prácticas
- La caché perimetral guarda cada conjunto de filtros distinto 30 minutos y lo comparte entre claves. La clave de caché usa la consulta ordenada, así que el orden de tus parámetros no importa.
- Una página tiene 20 entradas y la última es la 500, así que un conjunto de filtros llega a 10,000 entradas. Divide por ventanas de fechas para ir más a fondo. Un filtro amplio informa
total_resultsde 20001, que es un tope y no un recuento real. - Combina siempre
sort_conby= vote_ average.desc vote_count.gte. Sin él, los títulos con pocos votos ocupan los primeros puestos. - Los ids de los filtros son numéricos. Obtén los ids de persona en la búsqueda, y los ids de género y de proveedor en géneros y listas de consulta.
- Para listas ya preparadas como populares o en cartelera, consulta tendencias y listas.