# Сеансы ў кінатэатрах

> 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`  | запыт | не           | Двухлітарны код краіны, напрыклад `RU`. Без яго вы атрымліваеце толькі зводку па краінах. `region` гэта псеўданім. |
| `api_key`  | запыт | адзін з двух | Ваш ключ. Выкарыстоўвайце яго або загаловак `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/be/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/be/errors/) і [ліміты запытаў](https://amodb.dev/be/rate-limits/).

## Практычныя заўвагі

- Пакрыццё залежыць ад краіны і назвы. Лічыце пусты масіў `results` невядомасцю, а не адсутнасцю ў пракаце.
- Паказвайце `start` дакладна так, як вярнулася. Гэта мясцовы час кінатэатра без зруху UTC, а гадзіннік самога кінатэатра і чакаюць наведвальнікі.
- Сеансы кэшуюцца на edge на 30 хвілін. Не запытвайце іх на кожны прагляд старонкі і трымайце ўласны кэш кароткім.
- Выкарыстоўвайце адзін спіс now playing для ўсіх наведвальнікаў рэгіёна. Ён таксама кэшуецца на edge на 30 хвілін.
- Выкарыстоўвайце `booking_url`, каб адправіць наведвальніка на старонку бранавання кінатэатра. Ён роўны `null`, калі кінатэатр не дае спасылкі.
- Агляд з боку выпадку выкарыстання гл. на старонцы [API сеансаў у кінатэатрах](https://amodb.dev/be/cinema-showtimes-api/), а іншыя даныя фільма на старонцы [фільмы](https://amodb.dev/be/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/be/cinema-showtimes-api/): API сеансаў: GET /3/movie/{movie_id}/showtimes з кодам краіны вяртае кінатэатры, час пачатку і фарматы, дзе вядомыя. Спалучайце з now_playing.
- [Эндпоінты трэндаў і спісаў](https://amodb.dev/be/trending-lists/): API трэндавых фільмаў з шляхамі TMDB v3: чарты за дзень і тыдзень, спісы зараз у пракаце, папулярных, лепшых і хутка ў пракаце, кэш 30 хвілін.
- [API дэталяў фільма](https://amodb.dev/be/movies/): API дэталяў фільма з тымі ж шляхамі і JSON, што ў TMDB v3. Адзін фільм па id, а акцёры, рэйтынгі і настрой праз append_to_response, на 14 мовах.
- [Рэйтынгі фільмаў і серыялаў](https://amodb.dev/be/ratings/): API рэйтынгаў фільмаў вяртае ацэнкі IMDb, Kinopoisk, Metacritic, Rotten Tomatoes і TMDB для назвы адным выклікам, з null для крыніцы, якая невядомая.
- [Ліміты запытаў](https://amodb.dev/be/rate-limits/): amodb абмяжоўвае ключ па запытах у хвіліну ў слізгальным акне 60 секунд: 20, 40 або 120 па плане. Чытайце загалоўкі лімітаў і апрацоўвайце 429 праз Retry-After.
- [Хуткі старт](https://amodb.dev/be/quickstart/): Першы выклік да amodb: атрымайце ключ, запытайце дэталі фільма ў curl, JavaScript, Python, PHP або Go і загрузіце постэр з img.amodb.dev. Менш за 2 хвіліны.

Абноўлена: 2026-10-18. Source: https://amodb.dev/be/showtimes/
