# Сеанси в кінотеатрах

> GET /3/movie/{movie_id}/showtimes?country=RU повертає кінотеатри, де йде фільм в одній країні, з датованими сеансами в кожному. Без country повертається лише кількість по країнах у списку countries. Покриття залежить від країни та назви, а порожній масив results означає, що для цієї пари нічого не відомо.

## Ендпоінт

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

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

Відповідь:

```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"
    }
  ]
}
```

## Отримання сеансів фільму

`GET /3/movie/{movie_id}/showtimes?country=RU` повертає кінотеатри, де йде фільм в одній країні, з датованими сеансами в кожному. Параметр `country` приймає двобуквений код у верхньому або нижньому регістрі. Покриття залежить від країни та назви, тож дані є там, де вони відомі, і відсутні там, де ні. Повертаються лише дні від сьогодні.

Приклад запитує Fight Club у Росії та обробляє порожню відповідь.

```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, ","))
		}
	}
}
```

### Параметри

| Параметр   | Де    | Обов'язковий | Опис                                                                                                            |
| ---------- | ----- | ------------ | --------------------------------------------------------------------------------------------------------------- |
| `movie_id` | шлях  | так          | Числовий id фільму, наприклад `550`.                                                                            |
| `country`  | query | ні           | Двобуквений код країни, наприклад `RU`. Без нього ви отримаєте лише зведення по країнах. `region` це псевдонім. |
| `api_key`  | query | один із двох | Ваш ключ. Використовуйте його або заголовок `Authorization: Bearer`.                                            |

### Поля відповіді

| Поле                                                   | Тип              | Примітки                                                                                                                                       |
| ------------------------------------------------------ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                                   | ціле число       | ID фільму.                                                                                                                                     |
| `country`                                              | рядок або null   | Код у верхньому регістрі, який ви запитали, або `null`, якщо `country` відсутній або складається не з двох літер.                              |
| `results`                                              | масив            | Один об'єкт на кінотеатр, упорядковані за кінотеатром. Порожній, якщо нічого не відомо або країну не передано. Не більше 1500 сеансів загалом. |
| `results[].id`                                         | ціле число       | ID кінотеатру.                                                                                                                                 |
| `results[].name`                                       | рядок            | Назва кінотеатру.                                                                                                                              |
| `results[].chain`                                      | об'єкт           | `key` це ключ мережі, `name` це назва мережі або `null`.                                                                                       |
| `results[].city`                                       | рядок або null   | Місто.                                                                                                                                         |
| `results[].region`                                     | рядок або null   | Регіон.                                                                                                                                        |
| `results[].address`                                    | рядок або null   | Вулична адреса.                                                                                                                                |
| `results[].postal_code`                                | рядок або null   | Поштовий індекс.                                                                                                                               |
| `results[].country`                                    | рядок            | Код країни кінотеатру.                                                                                                                         |
| `results[].timezone`                                   | рядок або null   | Часовий пояс IANA, наприклад `Europe/Moscow`.                                                                                                  |
| `results[].latitude`, `results[].longitude`            | число або null   | Розташування кінотеатру.                                                                                                                       |
| `results[].phone`                                      | рядок або null   | Номер телефону.                                                                                                                                |
| `results[].url`                                        | рядок або null   | Сторінка кінотеатру.                                                                                                                           |
| `results[].showtimes`                                  | масив            | Покази в цьому кінотеатрі, упорядковані за початком.                                                                                           |
| `results[].showtimes[].date`                           | рядок            | День у форматі `2026-10-18`.                                                                                                                   |
| `results[].showtimes[].start`                          | рядок            | Початок за місцевим часом кінотеатру, наприклад `2026-10-18T21:40`, без зсуву UTC.                                                             |
| `results[].showtimes[].end`                            | рядок або null   | Кінець за місцевим часом кінотеатру.                                                                                                           |
| `results[].showtimes[].auditorium`                     | рядок або null   | Назва залу.                                                                                                                                    |
| `results[].showtimes[].formats`                        | масив рядків     | Формати, наприклад `2D`.                                                                                                                       |
| `results[].showtimes[].tags`                           | масив рядків     | Додаткові мітки. Часто порожній.                                                                                                               |
| `results[].showtimes[].audio`, `subtitles`, `language` | рядок або null   | Дані про звук, субтитри та мову, якщо вони відомі.                                                                                             |
| `results[].showtimes[].price`                          | число або null   | Ціна квитка.                                                                                                                                   |
| `results[].showtimes[].currency`                       | рядок або null   | Валюта `price`.                                                                                                                                |
| `results[].showtimes[].prices`                         | будь-що або null | Деталі цін, якщо в кінотеатру їх кілька.                                                                                                       |
| `results[].showtimes[].booking_url`                    | рядок або null   | Посилання для бронювання місця.                                                                                                                |
| `results[].showtimes[].sold_out`                       | булеве значення  | `true`, якщо квитки на сеанс розпродано.                                                                                                       |
| `countries`                                            | масив            | Зведення по країнах, див. нижче.                                                                                                               |

Читайте потрібні ключі за іменем і пропускайте зайві ключі всередині об'єкта кінотеатру чи сеансу. Багато полів сьогодні мають значення `null`, бо не кожен кінотеатр їх надсилає.

### Приклад відповіді

```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"
    }
  ]
}
```

Список скорочено до 1 із 2 кінотеатрів і 2 із 4 сеансів. Сеанси існують лише для днів, які ще не минули, тож ця відповідь щодня змінюється.

## Зведення по країнах

Не передавайте `country`, і відповідь міститиме лише лічильники. `results` залишається порожнім, а `country` дорівнює `null`. Масив `countries` містить до 60 країн, де ще є покази, першою йде країна з найбільшою кількістю сеансів. Скористайтеся ним, щоб дізнатися, де йде фільм, перш ніж запитувати кінотеатри.

```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"
    }
  ]
}
```

| Поле                                            | Тип        | Примітки                                                              |
| ----------------------------------------------- | ---------- | --------------------------------------------------------------------- |
| `countries[].country`                           | рядок      | Двобуквений код, який можна одразу використати як параметр `country`. |
| `countries[].name`                              | рядок      | Назва країни англійською.                                             |
| `countries[].venues`                            | ціле число | Кінотеатри з показами.                                                |
| `countries[].cities`                            | ціле число | Міста з показами.                                                     |
| `countries[].showtimes`                         | ціле число | Покази від сьогодні.                                                  |
| `countries[].first_day`, `countries[].last_day` | рядок      | Перший і останній день з показом.                                     |

Код країни без даних, як-от `country=US` для цього фільму, повертає `country` зі значенням `US`, порожній `results` і той самий список `countries`. Назва без сеансів ніде, наприклад серіал 1396, має `"countries": []`.

## Додавання сеансів до виклику деталей

`append_to_response=showtimes` додає такий самий блок до відповіді з деталями під ключем `showtimes`. Передайте код `country` у тому самому запиті. Блок зберігає власні ключі `id`, `country`, `results` і `countries`.

| Запит                                                          | Результат                                                       |
| -------------------------------------------------------------- | --------------------------------------------------------------- |
| `/3/movie/550?append_to_response=showtimes&country=RU`         | Запис фільму плюс блок `showtimes` для Росії                    |
| `/3/movie/550?append_to_response=credits,showtimes&country=RU` | Додає акторський склад і знімальну групу до того самого виклику |

Це лічиться як один запит, тож сторінці фільму з акторським складом і сеансами вистачить одного виклику. Для серіалів існує такий самий ендпоінт: `GET /3/tv/{tv_id}/showtimes`.

## Поєднання з now_playing і region

Список фільмів у прокаті (now playing) дає вам назви. Ендпоінт сеансів дає покази однієї назви. З'єднайте їх у своєму коді.

| Крок | Запит                                                   | Результат                                   |
| ---- | ------------------------------------------------------- | ------------------------------------------- |
| 1    | `GET /3/movie/now_playing?region=RU&page=1`             | До 20 фільмів на сторінку, кеш на 30 хвилин |
| 2    | `GET /3/movie/{id}/showtimes?country=RU` для кожного id | Кінотеатри й час, де відомо                 |

Цикл нижче робить одну-дві повторні спроби, коли досягнуто ліміт тарифу, і чекає кількість секунд із `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');
}
```

Сторінка з 20 назв це 20 запитів сеансів. На тарифі з 20 запитами на хвилину це займає все вікно, тому кешуйте результат у себе. Параметри списків дивіться в розділі [списки трендів](https://amodb.dev/uk/trending-lists/).

## Помилки

Тіло помилки відповідає формату TMDB: `success`, `status_code` і `status_message`. Хибний ключ дає `status_code` 7.

| HTTP | status_code | Коли                                                                                            |
| ---- | ----------- | ----------------------------------------------------------------------------------------------- |
| 401  | 7           | Ключ відсутній або хибний.                                                                      |
| 402  | 36          | Термін дії тарифу закінчився.                                                                   |
| 404  | 34          | Фільму з таким id немає.                                                                        |
| 429  | 25          | Перевищено ліміт запитів на хвилину. Зачекайте стільки секунд, скільки вказано в `Retry-After`. |

Відсутність сеансів не є помилкою: очікуйте статус 200 і порожній масив `results`. Відсутній або недійсний `country` теж не помилка. Див. [помилки](https://amodb.dev/uk/errors/) та [ліміти запитів](https://amodb.dev/uk/rate-limits/).

## Практичні нотатки

- Покриття залежить від країни та назви. Порожній масив `results` розглядайте як «невідомо», а не як «не йде».
- Показуйте `start` саме так, як він повернувся. Це місцевий час кінотеатру без зсуву UTC, а відвідувачі очікують саме годинник кінотеатру.
- Сеанси кешуються на edge на 30 хвилин. Не запитуйте їх на кожен перегляд сторінки й тримайте власний кеш коротким.
- Використовуйте один список now playing для всіх відвідувачів регіону. Він також кешується на edge на 30 хвилин.
- Використовуйте `booking_url`, щоб надіслати відвідувача на сторінку бронювання кінотеатру. Це `null`, якщо кінотеатр не дає посилання.
- Огляд сценарію використання дивіться в [API сеансів у кінотеатрах](https://amodb.dev/uk/cinema-showtimes-api/), а про інші дані фільму читайте в розділі [фільми](https://amodb.dev/uk/movies/).

## Запитання й відповіді

### Чи обов'язковий параметр country?

Ні, але без нього кінотеатрів не буде. Передайте двобуквений код, наприклад RU або DE. Без country або з кодом не з двох літер results порожній, а список countries показує, де сеанси є. Параметр region працює як псевдонім.

### Що означає порожній масив results?

Це означає, що для цієї назви в цій країні немає відомих сеансів від сьогодні. Це не доводить, що фільму немає в прокаті. Список countries усе одно показує інші країни з даними. Натомість покажіть дату виходу з деталей фільму.

### Як знайти фільми, що зараз йдуть у кінотеатрах?

Викличте GET /3/movie/now_playing з параметром region, а потім запитайте сеанси для потрібних id. Список кешується на 30 хвилин, тож його можна повторно використовувати для кожного відвідувача.

### Чи час подано в часовому поясі відвідувача?

Ні. Значення start це місцевий час кінотеатру без зсуву UTC. У кожного кінотеатру також є timezone, наприклад Europe/Moscow. Показуйте start як є й не переводьте його в часовий пояс відвідувача.

## Пов'язані сторінки

- [API сеансів кінотеатрів](https://amodb.dev/uk/cinema-showtimes-api/): API сеансів кінотеатрів: GET /3/movie/{movie_id}/showtimes із кодом країни повертає кінотеатри, час початку й формати, де відомо. Поєднуйте з now_playing.
- [Ендпоінти трендів і списків](https://amodb.dev/uk/trending-lists/): API трендів фільмів зі шляхами TMDB v3: чарти за день і тиждень, а також списки в прокаті, популярних, найкращих і майбутніх фільмів та серіалів, кеш 30 хвилин.
- [API деталей фільму](https://amodb.dev/uk/movies/): API деталей фільму з тими самими шляхами та JSON, що в TMDB v3. Отримайте фільм за id, додайте акторів, рейтинги й настрої через append_to_response, 14 мовами.
- [Рейтинги фільмів і серіалів](https://amodb.dev/uk/ratings/): API рейтингів фільмів повертає оцінки IMDb, Kinopoisk, Metacritic, Rotten Tomatoes і TMDB для фільму чи серіалу одним викликом, з null для невідомих джерел.
- [Ліміти запитів](https://amodb.dev/uk/rate-limits/): amodb обмежує кожен ключ запитами на хвилину в ковзному вікні 60 секунд: 20, 40 або 120 за тарифом. Читайте заголовки ліміту й обробляйте 429 із Retry-After.
- [Швидкий старт](https://amodb.dev/uk/quickstart/): Перший виклик amodb: отримайте ключ, запросіть деталі фільму в curl, JavaScript, Python, PHP чи Go і завантажте постер з img.amodb.dev. Менш ніж за 2 хвилини.

Оновлено: 2026-10-18. Source: https://amodb.dev/uk/showtimes/
