# 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.

## Endpoint

`GET /3/movie/{movie_id}/showtimes`

```bash
curl "https://api.amodb.dev/3/movie/550/showtimes?country=RU" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Resposta:

```json
{
  "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-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
        },
        {
          "date": "2026-10-20",
          "start": "2026-10-20T21: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/7f18e423-4a40-40f3-b68f-8664f4e3fa75/",
          "sold_out": false
        },
        {
          "date": "2026-10-21",
          "start": "2026-10-21T21: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/5ad6b82b-82b3-4ea6-9e65-79388d71b230/",
          "sold_out": false
        }
      ]
    },
    {
      "id": 1115,
      "name": "Мираж Синема ПИК",
      "chain": {
        "key": "mirage-ru",
        "name": "Мираж Синема"
      },
      "city": "Санкт-Петербург",
      "region": null,
      "address": "ул. Ефимова, д.2",
      "postal_code": null,
      "country": "RU",
      "timezone": "Europe/Moscow",
      "latitude": null,
      "longitude": null,
      "phone": null,
      "url": "https://www.mirage.ru/spb/cinema/27/",
      "showtimes": [
        {
          "date": "2026-10-19",
          "start": "2026-10-19T20:10",
          "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/1d143ca6-1bbe-48ee-954a-063b6088a32a/",
          "sold_out": false
        },
        {
          "date": "2026-10-20",
          "start": "2026-10-20T20:10",
          "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/8b2e0f6a-5b62-41eb-a398-1b709539f03d/",
          "sold_out": false
        },
        {
          "date": "2026-10-21",
          "start": "2026-10-21T20:10",
          "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/3723875b-a7df-426f-968a-4bdaa1a8bdd7/",
          "sold_out": false
        }
      ]
    }
  ],
  "countries": [
    {
      "country": "RU",
      "name": "Russia",
      "venues": 2,
      "cities": 1,
      "showtimes": 6,
      "first_day": "2026-10-19",
      "last_day": "2026-10-21"
    }
  ]
}
```

## Obter os horários de sessões de um filme

`GET /3/movie/{movie_id}/showtimes?country=RU` 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.

```bash
curl -sf "https://api.amodb.dev/3/movie/550/showtimes?country=RU" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```js
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);
  }
}
```

```python
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
<?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;
    }
}
```

```go
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

| Parâmetro  | Em       | Obrigatório | Descrição                                                                                                 |
| ---------- | -------- | ----------- | --------------------------------------------------------------------------------------------------------- |
| `movie_id` | caminho  | sim         | Id numérico do filme, por exemplo `550`.                                                                  |
| `country`  | consulta | não         | Código de país de duas letras, como `RU`. Sem ele, você recebe só o resumo por país. `region` é um alias. |
| `api_key`  | consulta | um dos dois | Sua chave. Use este parâmetro ou o header `Authorization: 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_url`                    | string ou null        | Link para reservar o lugar.                                                                                                                     |
| `results[].showtimes[].sold_out`                       | 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

```json
{
  "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.

```bash
curl -sf "https://api.amodb.dev/3/movie/550/showtimes" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```json
{
  "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_to_response=showtimes` 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                                                 |
| -------------------------------------------------------------- | --------------------------------------------------------- |
| `/3/movie/550?append_to_response=showtimes&country=RU`         | Registro do filme mais um bloco `showtimes` para a Rússia |
| `/3/movie/550?append_to_response=credits,showtimes&country=RU` | 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 /3/tv/{tv_id}/showtimes`.

## 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 /3/movie/now_playing?region=RU&page=1`           | Até 20 filmes por página, com cache de 30 minutos |
| 2     | `GET /3/movie/{id}/showtimes?country=RU` 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`.

```js
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](https://amodb.dev/pt/trending-lists/) 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](https://amodb.dev/pt/errors/) e [limites de requisições](https://amodb.dev/pt/rate-limits/).

## Notas práticas

- A cobertura varia por país e título. Trate um array `results` vazio como desconhecido, e não como fora de cartaz.
- Mostre `start` exatamente 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_url` para enviar o visitante à página de reservas do local de exibição. Ele é `null` quando 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](https://amodb.dev/pt/cinema-showtimes-api/), e para os outros dados de um filme, veja [filmes](https://amodb.dev/pt/movies/).

## Perguntas e respostas

### O parâmetro country é obrigatório?

Não, mas você precisa dele para receber os locais de exibição. Envie um código de duas letras, como RU ou DE. Sem country, ou com um código que não tem duas letras, results fica vazio e a lista countries mostra onde existem sessões. O parâmetro region funciona como alias.

### O que significa um array results vazio?

Significa que nenhuma sessão é conhecida para esse título nesse país a partir de hoje. Isso não prova que o filme está fora de cartaz. A lista countries ainda mostra os outros países com dados. Ofereça a data de lançamento dos detalhes do filme no lugar.

### Como encontro os filmes que estão em cartaz agora?

Chame GET /3/movie/now_playing com o parâmetro region e depois peça as sessões dos ids que interessam. A lista tem cache de 30 minutos, então você pode reutilizá-la para todos os visitantes.

### Os horários seguem o fuso horário do meu visitante?

Não. O valor de start é a hora local do cinema e não traz deslocamento UTC. Cada local de exibição também tem um timezone, como Europe/Moscow. Mostre start como foi retornado e não o converta para o fuso horário do visitante.

## Páginas relacionadas

- [API de horários de sessões de cinema](https://amodb.dev/pt/cinema-showtimes-api/): API de horários de sessões: GET /3/movie/{movie_id}/showtimes com código de país retorna cinemas, horários e formatos, quando conhecidos. Use com now_playing.
- [Endpoints de em alta e de listas](https://amodb.dev/pt/trending-lists/): API de filmes em alta com caminhos do TMDB v3: rankings do dia e da semana, listas em cartaz, populares, mais bem avaliados e em breve. Cache de 30 minutos.
- [API de detalhes de filmes](https://amodb.dev/pt/movies/): API de detalhes de filmes com caminhos e JSON do TMDB v3. Busque um filme por id e junte créditos, avaliações e moods com append_to_response, em 14 idiomas.
- [Avaliações de filmes e séries](https://amodb.dev/pt/ratings/): API de avaliações de filmes com as notas do IMDb, Kinopoisk, Metacritic, Rotten Tomatoes e TMDB em uma só chamada, com null se a fonte for desconhecida.
- [Limites de requisições](https://amodb.dev/pt/rate-limits/): O amodb limita cada chave por requisições por minuto em uma janela de 60 segundos: 20, 40 ou 120 por plano. Leia os cabeçalhos e trate o 429 com Retry-After.
- [Início rápido](https://amodb.dev/pt/quickstart/): Faça sua primeira chamada ao amodb: obtenha uma chave, peça um filme em curl, JavaScript, Python, PHP ou Go e carregue o pôster. Menos de 2 minutos.

Atualizado: 2026-10-18. Source: https://amodb.dev/pt/showtimes/
