API Discover
O Discover lista filmes em GET /3/discover/movie e séries de TV em GET /3/discover/tv, filtrados e ordenados pelos parâmetros que você escolher: gênero, elenco, equipe técnica, produtora, palavra-chave, datas, nota, votos, duração, idioma e provedor de streaming. O JSON segue o TMDB v3, e os resultados ficam em cache por 30 minutos.
Descobrir filmes
GET /3/discover/movie retorna uma lista paginada de filmes que atendem a todos os filtros enviados, na ordem que você escolher. É o endpoint para páginas de navegação, listas dos “melhores” e recomendações por faceta, e não precisa de texto em query. Quando você tem um título digitado por um usuário, use a busca.
O exemplo lista filmes de ficção científica (id de gênero 878) com pelo menos 1000 votos, os mais bem avaliados primeiro.
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_keyconsultaum dos doisSua chave. Use este parâmetro ou o headerAuthorization: Bearer.sort_byconsultaCampo e direção, comovote_average.desc. Campos:popularity,vote_average,vote_count,primary_release_date,revenue,title,original_title, cada um com.ascou.desc.titleeoriginal_titleordenam ambos pelo título original. Um valor desconhecido volta parapopularity.desc, que também é o padrão.with_genresconsultaIds de gênero. Vírgula significa E, barra vertical significa OU.without_genresconsultaIds de gênero a excluir.with_cast,with_crewconsultaIds de pessoa. Encontre-os na busca.with_peopleconsultaIds de pessoa que aparecem no elenco ou na equipe técnica.with_companies,without_companiesconsultaIds de produtora a exigir ou excluir. Vírgula e barra vertical funcionam como emwith_genres.with_keywords,without_keywordsconsultaIds de palavra-chave a exigir ou excluir. Veja palavras-chave.with_origin_countryconsultaCódigo de país de produção com 2 letras maiúsculas, comoFR.primary_release_yearconsultaAno com quatro dígitos da data de lançamento principal.yearconsultaAno com quatro dígitos. Corresponde a qualquer data de lançamento naquele ano, então retorna mais títulos queprimary_release_year.primary_,release_ date.gte primary_consultarelease_ date.lte Limites inferior e superior da data de lançamento principal,YYYY-MM-DD.release_date.gte,release_date.lteconsultaLimites inferior e superior de qualquer data de lançamento em qualquer país,YYYY-MM-DD.regionconsultaCódigo de país com 2 letras maiúsculas. Trocarelease_dateem cada resultado pela data nesse país. Não remove títulos.certification_country,certificationconsultaFiltro de classificação indicativa, por exemploUSePG.certificationé ignorado sem um país.certification.gteecertification.ltedefinem um intervalo.vote_average.gte,vote_average.lteconsultaNota média mínima e máxima, de 0 a 10.vote_count.gte,vote_count.lteconsultaNúmero mínimo e máximo de votos.with_runtime.gte,with_runtime.lteconsultaDuração mínima e máxima em minutos.with_original_languageconsultaIdioma original como código de 2 letras, comofrouko.with_watch_providersconsultaIds de provedor. Exigewatch_regione é ignorado sem ele. Os ids vêm de gêneros e listas de consulta.watch_regionconsultaCódigo de país com 2 letras maiúsculas para a disponibilidade do provedor.include_adultconsultaAceito e ignorado. Títulos adultos nunca são retornados.languageconsultaTag do TMDB comoen-USoupl-PL. 14 idiomas base são atendidos. Padrãoen-US.pageconsultaNúmero da página, de 1 a 500. Padrão 1.
Campos da resposta
| Campo | Tipo | Observações |
|---|---|---|
page, total_pages, total_results | inteiro | Paginação deste conjunto de filtros. Filtros amplos informam no máximo 1001 páginas e 20001 resultados, mas só as páginas de 1 a 500 podem ser lidas. |
results | array | Até 20 filmes. Vazio quando nenhum título atende a todos os filtros. |
id | inteiro | Id do filme para os detalhes do filme. |
title, original_title, overview | string | Texto localizado e título original. |
original_language | string | Código de duas letras do idioma em que o filme foi feito. |
release_date | string | YYYY-MM-DD. |
genre_ids | array de inteiros | Só os ids. Converta-os em nomes com /genre/movie/list. |
poster_path, backdrop_path | string ou null | Acrescente a https:/. |
vote_average, vote_count, popularity | número | Valores de nota e de ranking. |
adult, video | booleano | adult é sempre false. |
Exemplo de resposta
{
"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
}A resposta foi obtida da API real com a requisição do exemplo. Ela foi cortada para 3 das 20 entradas da página 1, e as strings longas de overview foram encurtadas.
Combinar filtros
Parâmetros separados se combinam com E. Dentro de um mesmo parâmetro, a vírgula significa E e a barra vertical significa OU. Em uma URL pura a barra vertical é escrita %7C, e os clientes que codificam os valores da consulta fazem isso por você.
| Objetivo | Requisição |
|---|---|
| Ficção científica mais bem avaliada, com votos suficientes | / |
| Ação ou aventura | / |
| Ação, mas não animação | / |
| Um ator com um diretor | / |
| Filmes longos de um ano | / |
| Lançamentos em uma janela de datas | / |
| Filmes em um idioma original | / |
| Em streaming em um país | / |
| Classificação R nos EUA | / |
| Sem uma palavra-chave | / |
with_original_language filtra pelo idioma em que o título foi feito e aceita códigos fora dos 14 idiomas atendidos, por exemplo ja ou ko. O parâmetro language continua definindo o idioma do texto que você recebe. Na linha do provedor, 8 é a Netflix. Leia os ids de provedor em /watch/providers/movie.
Descobrir séries de TV
GET /3/discover/tv usa o mesmo envelope e a mesma paginação. As entradas trazem name, original_name, first_air_date, origin_country e genre_ids, e os ids de gênero vêm de /genre/tv/list, que contém os ids de TV unificados, como 10765 para Sci-Fi e Fantasia.
| Parâmetro | Descrição |
|---|---|
first_air_date.gte, first_air_date.lte | Limites inferior e superior da data da primeira exibição, YYYY-MM-DD. |
first_air_date_year | Ano com quatro dígitos da primeira exibição. |
air_date.gte, air_date.lte | Limites inferior e superior das datas em que uma série tem episódios no ar, YYYY-MM-DD. |
with_networks | Ids de emissora. Encontre-os em produtoras e emissoras. |
with_status | Código numérico de status: 0 série em exibição, 2 em produção, 3 encerrada, 4 cancelada. |
with_type | Tipo numérico de programa: 0 documentário, 1 notícias, 2 minissérie, 3 reality, 4 roteirizado, 5 talk show, 6 vídeo. |
sort_by | popularity, vote_average, vote_count, first_air_date, name ou original_name, cada um com .asc ou .desc. name e original_name ordenam ambos pelo nome original. |
with_genres, without_genres, with_companies, with_keywords, without_keywords | As mesmas regras dos filmes. |
vote_average.gte, vote_count.gte, with_runtime.gte, with_runtime.lte, with_original_language | As mesmas regras dos filmes. |
with_watch_providers, watch_region, language, page | As mesmas regras dos filmes. |
Uma requisição como / lista séries de drama que começaram em 2025 ou depois. Veja um resultado em detalhe em séries de TV.
Erros
| HTTP | status_code | Quando |
|---|---|---|
| 401 | 7 | A chave está ausente ou incorreta. |
| 402 | 36 | O período do plano terminou. |
| 405 | 37 | Você chamou um método de escrita. |
| 429 | 25 | Acima do seu limite de requisições por minuto. Espere os segundos indicados em Retry-After. |
| 500 | 11 | Um page fora do intervalo de 1 a 500. |
| 504 | 24 | O backend não respondeu a tempo. Tente de novo uma vez. |
Um conjunto de filtros sem nenhuma correspondência não é um erro. Você recebe HTTP 200 com um array results vazio e total_results igual a 0. Veja erros e limites de requisições.
Notas práticas
- A borda guarda em cache cada conjunto distinto de filtros por 30 minutos e o compartilha entre as chaves. A chave do cache usa a consulta ordenada, então a ordem dos seus parâmetros não importa.
- Uma página tem 20 entradas e a última é a 500, então um conjunto de filtros chega a 10,000 entradas. Divida por janelas de datas para ir mais fundo. Um filtro amplo informa
total_resultsigual a 20001, que é um teto e não uma contagem real. - Combine sempre
sort_comby= vote_ average.desc vote_count.gte. Sem isso, títulos com poucos votos lotam o topo. - Os ids nos filtros são numéricos. Pegue ids de pessoa na busca, e ids de gênero e de provedor em gêneros e listas de consulta.
- Para listas prontas, como populares ou em cartaz, veja em alta e listas.