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

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

Обновлено Открыть в Markdown

Сеансы фильма

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

Пример запрашивает Fight Club в России и обрабатывает пустой ответ.

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

Параметры

  • movie_idпутьобязателен
    Числовой id фильма, например 550.
  • countryquery
    Двухбуквенный код страны, например RU. Без него вернется только сводка по странам. region работает как псевдоним.
  • api_keyqueryодно из двух
    Ваш ключ. Используйте его или заголовок 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 стран, где еще есть сеансы, первой идет страна с наибольшим числом сеансов. Используйте его, чтобы узнать, где фильм идет в кино, прежде чем запрашивать кинотеатры.

curl
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 дает названия фильмов. Эндпоинт сеансов дает показы одного фильма. Объедините их в своем коде.

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

Цикл ниже делает одну-две повторные попытки при достижении лимита тарифа, ожидая число секунд из Retry-After.

JavaScript
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 запросами в минуту это все окно, поэтому кэшируйте результат у себя. Параметры списков описаны в разделе списки трендов.

Ошибки

Тело ошибки соответствует TMDB: success, status_code и status_message. Неверный ключ дает status_code 7.

HTTPstatus_codeКогда
4017Ключ отсутствует или неверен.
40236Срок действия тарифа истек.
40434Нет фильма с таким id.
42925Превышено число запросов в минуту. Подождите число секунд из Retry-After.

Отсутствие сеансов не ошибка: ожидайте статус 200 и пустой массив results. Отсутствующий или неверный country тоже не ошибка. Подробнее: ошибки и лимиты запросов.

Практические заметки

  • Покрытие зависит от страны и фильма. Считайте пустой массив results признаком отсутствия данных, а не того, что фильм не идет.
  • Показывайте start ровно в том виде, как он пришел. Это местное время кинотеатра без смещения UTC, и именно по часам кинотеатра ориентируются посетители.
  • Сеансы кэшируются на CDN на 30 минут. Не запрашивайте их при каждом просмотре страницы и держите собственный кэш коротким.
  • Используйте один список now playing для всех посетителей региона. Он тоже кэшируется на CDN на 30 минут.
  • Через booking_url отправляйте посетителя на страницу бронирования кинотеатра. Он равен null, если кинотеатр не дает ссылку.
  • Обзор сценария использования смотрите в API сеансов кинотеатров, а остальные данные о фильме в разделе фильмы.