Horários de sessões de cinema
GET /3/movie/{movie_id}/showtimes?country=RU retorna os locais que exibem um filme em um país, com as sessões datadas de cada um. Sem country, retorna só as contagens por país em uma lista countries. A cobertura varia por país e título, e um array results vazio significa que nada é conhecido para esse par.
Obter os horários de sessões de um filme
GET / retorna os locais de exibição que mostram um filme em um país, com as sessões datadas de cada um. O parâmetro country recebe um código de duas letras, em maiúsculas ou minúsculas. A cobertura varia por país e título, então o dado aparece onde é conhecido e falta onde não é. Só voltam os dias a partir de hoje.
O exemplo pede Fight Club na Rússia e trata uma resposta vazia.
curl -sf "https://api.amodb.dev/3/movie/550/showtimes?country=RU" \
-H "Authorization: Bearer $AMODB_KEY"const url = 'https://api.amodb.dev/3/movie/550/showtimes?country=RU';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const data = await res.json();
if (data.results.length === 0) console.log('no showtimes known');
for (const venue of data.results) {
for (const s of venue.showtimes) {
console.log(venue.name, venue.city, s.start, s.formats.join(','), s.booking_url);
}
}import os
import requests
r = requests.get(
"https://api.amodb.dev/3/movie/550/showtimes",
params={"country": "RU"},
headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
timeout=10,
)
r.raise_for_status()
results = r.json()["results"]
if not results:
print("no showtimes known")
for venue in results:
for s in venue["showtimes"]:
print(venue["name"], venue["city"], s["start"], ",".join(s["formats"]))<?php
$url = 'https://api.amodb.dev/3/movie/550/showtimes?country=RU';
$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");
}
$results = json_decode($body, true)['results'];
if (!$results) {
echo 'no showtimes known', PHP_EOL;
}
foreach ($results as $venue) {
foreach ($venue['showtimes'] as $s) {
echo $venue['name'], ' ', $s['start'], ' ', implode(',', $s['formats']), PHP_EOL;
}
}package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"time"
)
type Venue struct {
Name string `json:"name"`
City string `json:"city"`
Showtimes []struct {
Start string `json:"start"`
Formats []string `json:"formats"`
BookingURL string `json:"booking_url"`
} `json:"showtimes"`
}
func main() {
url := "https://api.amodb.dev/3/movie/550/showtimes?country=RU"
req, _ := http.NewRequest("GET", url, 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 body struct {
Results []Venue `json:"results"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
panic(err)
}
if len(body.Results) == 0 {
fmt.Println("no showtimes known")
}
for _, v := range body.Results {
for _, s := range v.Showtimes {
fmt.Println(v.Name, v.City, s.Start, strings.Join(s.Formats, ","))
}
}
}Parâmetros
movie_idcaminhoobrigatórioId numérico do filme, por exemplo550.countryconsultaCódigo de país de duas letras, comoRU. Sem ele, você recebe só o resumo por país.regioné um alias.api_keyconsultaum dos doisSua chave. Use este parâmetro ou o headerAuthorization: Bearer.
Campos da resposta
| Campo | Tipo | Observações |
|---|---|---|
id | inteiro | Id do filme. |
country | string ou null | O código em maiúsculas que você pediu, ou null quando country falta ou não tem duas letras. |
results | array | Um objeto por local de exibição, ordenado por local. Vazio quando nada é conhecido ou nenhum país foi enviado. No máximo 1500 sessões no total. |
results[].id | inteiro | Id do local de exibição. |
results[].name | string | Nome do local de exibição. |
results[].chain | objeto | key é a chave da rede, name é o nome da rede ou null. |
results[].city | string ou null | Cidade. |
results[].region | string ou null | Região. |
results[].address | string ou null | Endereço. |
results[].postal_code | string ou null | Código postal. |
results[].country | string | Código de país do local de exibição. |
results[].timezone | string ou null | Fuso horário IANA, como Europe/Moscow. |
results[].latitude, results[].longitude | número ou null | Posição do local de exibição. |
results[].phone | string ou null | Número de telefone. |
results[].url | string ou null | Página do local de exibição. |
results[].showtimes | array | Sessões desse local, ordenadas pelo início. |
results[].showtimes[].date | string | Dia no formato 2026-10-18. |
results[].showtimes[].start | string | Início na hora local do cinema, como 2026-10-18T21:40, sem deslocamento UTC. |
results[].showtimes[].end | string ou null | Fim na hora local do cinema. |
results[].showtimes[].auditorium | string ou null | Nome da sala. |
results[].showtimes[].formats | array de strings | Formatos, como 2D. |
results[].showtimes[].tags | array de strings | Rótulos extras. Muitas vezes vazio. |
results[].showtimes[].audio, subtitles, language | string ou null | Detalhes de áudio, legenda e idioma, quando conhecidos. |
results[].showtimes[].price | número ou null | Preço do ingresso. |
results[].showtimes[].currency | string ou null | Moeda de price. |
results[].showtimes[].prices | qualquer tipo ou null | Detalhes de preço quando um local tem vários. |
results[].showtimes[].booking_ | string ou null | Link para reservar o lugar. |
results[].showtimes[].sold_ | booleano | true quando a sessão está esgotada. |
countries | array | Resumo por país, veja abaixo. |
Leia pelo nome as chaves que você usa e ignore chaves extras dentro de um objeto de local ou de sessão. Hoje muitos campos são null, porque nem todo local os envia.
Exemplo de resposta
{
"id": 550,
"country": "RU",
"results": [
{
"id": 1114,
"name": "Мираж Синема НА БОЛЬШОМ",
"chain": {
"key": "mirage-ru",
"name": "Мираж Синема"
},
"city": "Санкт-Петербург",
"region": null,
"address": "Большой пр. П.С., д. 35А",
"postal_code": null,
"country": "RU",
"timezone": "Europe/Moscow",
"latitude": null,
"longitude": null,
"phone": null,
"url": "https://www.mirage.ru/spb/cinema/1/",
"showtimes": [
{
"date": "2026-10-18",
"start": "2026-10-18T21:40",
"end": null,
"auditorium": null,
"formats": ["2D"],
"tags": [],
"audio": null,
"subtitles": null,
"language": null,
"price": null,
"currency": null,
"prices": null,
"booking_url": "https://www.mirage.ru/ticket_new/aca7b114-d587-4fc5-9df6-28568e8fa9b3/",
"sold_out": false
},
{
"date": "2026-10-19",
"start": "2026-10-19T22:20",
"end": null,
"auditorium": "Зал №4",
"formats": ["2D"],
"tags": [],
"audio": null,
"subtitles": null,
"language": null,
"price": null,
"currency": null,
"prices": null,
"booking_url": "https://www.mirage.ru/ticket_new/0c32e190-890a-4c81-a754-3300fefc4d5e/",
"sold_out": false
}
]
}
],
"countries": [
{
"country": "RU",
"name": "Russia",
"venues": 2,
"cities": 1,
"showtimes": 7,
"first_day": "2026-10-18",
"last_day": "2026-10-21"
}
]
}A lista foi cortada para 1 de 2 locais e 2 de 4 sessões. As sessões só existem para dias que ainda não passaram, então essa resposta muda todo dia.
Obter o resumo por país
Omita country e a resposta traz só contagens. results continua vazio e country é null. O array countries lista até 60 países que ainda têm uma sessão, com o de mais sessões primeiro. Use-o para saber onde um título está em cartaz antes de pedir os locais de exibição.
curl -sf "https://api.amodb.dev/3/movie/550/showtimes" \
-H "Authorization: Bearer $AMODB_KEY"{
"id": 550,
"country": null,
"results": [],
"countries": [
{
"country": "RU",
"name": "Russia",
"venues": 2,
"cities": 1,
"showtimes": 7,
"first_day": "2026-10-18",
"last_day": "2026-10-21"
}
]
}| Campo | Tipo | Observações |
|---|---|---|
countries[].country | string | Código de duas letras, pronto para usar como parâmetro country. |
countries[].name | string | Nome do país em inglês. |
countries[].venues | inteiro | Locais de exibição com uma sessão. |
countries[].cities | inteiro | Cidades com uma sessão. |
countries[].showtimes | inteiro | Sessões a partir de hoje. |
countries[].first_day, countries[].last_day | string | Primeiro e último dia com uma sessão. |
Um código de país sem dados, como country=US para este filme, responde com country igual a US, um results vazio e a mesma lista countries. Um título sem sessões em lugar nenhum, como a série 1396, tem "countries": [].
Juntar os horários a uma chamada de detalhes
append_ junta o mesmo bloco a uma resposta de detalhes, sob a chave showtimes. Envie o código country na mesma requisição. O bloco mantém as próprias chaves id, country, results e countries.
| Requisição | Resultado |
|---|---|
/ | Registro do filme mais um bloco showtimes para a Rússia |
/ | Acrescenta os créditos à mesma chamada |
Conta como uma requisição, então uma página de filme que mostra elenco e sessões precisa de uma única chamada. O mesmo endpoint existe para séries, como GET /.
Combinar com now_playing e region
A lista de filmes em cartaz dá os títulos. O endpoint de horários dá as sessões de um título. Una os dois no seu código.
| Passo | Requisição | Resultado |
|---|---|---|
| 1 | GET / | Até 20 filmes por página, com cache de 30 minutos |
| 2 | GET / para cada id | Locais de exibição e horários, onde conhecidos |
O laço abaixo tenta de novo uma ou duas vezes quando o limite do plano é atingido, esperando o número de segundos de Retry-After.
const base = 'https://api.amodb.dev/3';
const headers = { Authorization: `Bearer ${process.env.AMODB_KEY}` };
async function get(path, retries = 2) {
const res = await fetch(base + path, { headers });
if (res.status === 429 && retries > 0) {
const wait = Number(res.headers.get('Retry-After') ?? 60);
await new Promise((resolve) => setTimeout(resolve, wait * 1000));
return get(path, retries - 1);
}
if (!res.ok) throw new Error(`amodb returned ${res.status} for ${path}`);
return res.json();
}
const playing = await get('/movie/now_playing?region=RU&page=1');
for (const movie of playing.results) {
const data = await get(`/movie/${movie.id}/showtimes?country=RU`);
if (data.results.length > 0) console.log(movie.title, data.results.length, 'venues');
}Uma página de 20 títulos são 20 requisições de horários. No plano de 20 requisições por minuto isso usa a janela inteira, então guarde o resultado em cache do seu lado. Veja em alta e listas para os parâmetros das listas.
Erros
O corpo do erro segue o TMDB: success, status_code e status_message. Uma chave inválida mostra status_code 7.
| HTTP | status_code | Quando |
|---|---|---|
| 401 | 7 | A chave está ausente ou incorreta. |
| 402 | 36 | O período do plano terminou. |
| 404 | 34 | Nenhum filme com esse id. |
| 429 | 25 | Você passou do seu limite de requisições por minuto. Espere os segundos indicados em Retry-After. |
Não ter sessões não é um erro: espere o status 200 e um array results vazio. Um country ausente ou inválido também não é um erro. Veja erros e limites de requisições.
Notas práticas
- A cobertura varia por país e título. Trate um array
resultsvazio como desconhecido, e não como fora de cartaz. - Mostre
startexatamente como retornado. É a hora local do local de exibição, sem deslocamento UTC, e o relógio do próprio cinema é o que os visitantes esperam. - Os horários ficam em cache de borda por 30 minutos. Não os peça a cada visualização de página e mantenha seu próprio cache curto.
- Reutilize uma única lista de filmes em cartaz para todos os visitantes de uma região. Ela também tem cache de borda de 30 minutos.
- Use
booking_urlpara enviar o visitante à página de reservas do local de exibição. Ele énullquando o local não informa um link. - Para a visão do caso de uso, veja API de horários de sessões de cinema, e para os outros dados de um filme, veja filmes.