# Cinema showtimes

> GET /3/movie/{movie_id}/showtimes?country=RU returns the venues that show a movie in one country, with dated showtimes at each. Without country it returns only per-country counts in a countries list. Coverage varies by country and title, and an empty results array means nothing is known for that pair.

## Endpoint

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

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

Response:

```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
        },
        {
          "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
        }
      ]
    },
    {
      "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 showtimes for a movie

`GET /3/movie/{movie_id}/showtimes?country=RU` returns the venues that show a movie in one country, with the dated showtimes at each. The `country` parameter takes a two letter code, in upper or lower case. Coverage varies by country and title, so the data is present where it is known and missing where it is not. Only days from today on are returned.

The sample asks for Fight Club in Russia and handles an empty answer.

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

### Parameters

| Parameter  | In    | Required   | Description                                                                                                  |
| ---------- | ----- | ---------- | ------------------------------------------------------------------------------------------------------------ |
| `movie_id` | path  | yes        | Numeric movie id, for example `550`.                                                                         |
| `country`  | query | no         | Two letter country code such as `RU`. Without it you get the per-country summary only. `region` is an alias. |
| `api_key`  | query | one of two | Your key. Use this or the `Authorization: Bearer` header.                                                    |

### Response fields

| Field                                                  | Type             | Notes                                                                                                                        |
| ------------------------------------------------------ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `id`                                                   | integer          | Movie id.                                                                                                                    |
| `country`                                              | string or null   | The upper case code you asked for, or `null` when `country` is missing or not two letters.                                   |
| `results`                                              | array            | One object per venue, ordered by venue. Empty when nothing is known or no country was sent. At most 1500 showtimes in total. |
| `results[].id`                                         | integer          | Venue id.                                                                                                                    |
| `results[].name`                                       | string           | Venue name.                                                                                                                  |
| `results[].chain`                                      | object           | `key` is the chain key, `name` is the chain name or `null`.                                                                  |
| `results[].city`                                       | string or null   | City.                                                                                                                        |
| `results[].region`                                     | string or null   | Region.                                                                                                                      |
| `results[].address`                                    | string or null   | Street address.                                                                                                              |
| `results[].postal_code`                                | string or null   | Postal code.                                                                                                                 |
| `results[].country`                                    | string           | Country code of the venue.                                                                                                   |
| `results[].timezone`                                   | string or null   | IANA time zone such as `Europe/Moscow`.                                                                                      |
| `results[].latitude`, `results[].longitude`            | number or null   | Venue position.                                                                                                              |
| `results[].phone`                                      | string or null   | Phone number.                                                                                                                |
| `results[].url`                                        | string or null   | Venue page.                                                                                                                  |
| `results[].showtimes`                                  | array            | Screenings at that venue, ordered by start.                                                                                  |
| `results[].showtimes[].date`                           | string           | Day as `2026-10-18`.                                                                                                         |
| `results[].showtimes[].start`                          | string           | Start in venue local time like `2026-10-18T21:40`, with no UTC offset.                                                       |
| `results[].showtimes[].end`                            | string or null   | End in venue local time.                                                                                                     |
| `results[].showtimes[].auditorium`                     | string or null   | Hall name.                                                                                                                   |
| `results[].showtimes[].formats`                        | array of strings | Formats such as `2D`.                                                                                                        |
| `results[].showtimes[].tags`                           | array of strings | Extra labels. Often empty.                                                                                                   |
| `results[].showtimes[].audio`, `subtitles`, `language` | string or null   | Audio, subtitle and language details when known.                                                                             |
| `results[].showtimes[].price`                          | number or null   | Ticket price.                                                                                                                |
| `results[].showtimes[].currency`                       | string or null   | Currency of `price`.                                                                                                         |
| `results[].showtimes[].prices`                         | any or null      | Price details when a venue has several.                                                                                      |
| `results[].showtimes[].booking_url`                    | string or null   | Link to book the seat.                                                                                                       |
| `results[].showtimes[].sold_out`                       | boolean          | `true` when the screening is sold out.                                                                                       |
| `countries`                                            | array            | Per-country summary, see below.                                                                                              |

Read the keys you use by name and skip extra keys inside a venue or showtime object. Many fields are `null` today because not every venue sends them.

### Example response

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

The list is cut to 1 of 2 venues and 2 of 4 showtimes. Showtimes only exist for days that have not passed, so this answer changes every day.

## Get the per-country summary

Leave `country` out and the reply holds counts only. `results` stays empty and `country` is `null`. The `countries` array lists up to 60 countries that still have a screening, the one with the most showtimes first. Use it to learn where a title is on screen before you ask for venues.

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

| Field                                           | Type    | Notes                                                     |
| ----------------------------------------------- | ------- | --------------------------------------------------------- |
| `countries[].country`                           | string  | Two letter code, ready to use as the `country` parameter. |
| `countries[].name`                              | string  | English country name.                                     |
| `countries[].venues`                            | integer | Venues with a screening.                                  |
| `countries[].cities`                            | integer | Cities with a screening.                                  |
| `countries[].showtimes`                         | integer | Screenings from today on.                                 |
| `countries[].first_day`, `countries[].last_day` | string  | First and last day with a screening.                      |

A country code with no data, such as `country=US` for this film, answers `country` as `US`, an empty `results` and the same `countries` list. A title with no showtimes anywhere, such as the series 1396, has `"countries": []`.

## Add showtimes to a details call

`append_to_response=showtimes` merges the same block into a details reply under the `showtimes` key. Send the `country` code in the same request. The block keeps its own `id`, `country`, `results` and `countries` keys.

| Request                                                        | Result                                           |
| -------------------------------------------------------------- | ------------------------------------------------ |
| `/3/movie/550?append_to_response=showtimes&country=RU`         | Movie record plus a `showtimes` block for Russia |
| `/3/movie/550?append_to_response=credits,showtimes&country=RU` | Adds credits to the same call                    |

It counts as one request, so a movie page that shows cast and screenings needs a single call. The same endpoint exists for series as `GET /3/tv/{tv_id}/showtimes`.

## Combine with now_playing and region

The now playing list gives you titles. The showtimes endpoint gives you screenings for one title. Join them in your code.

| Step | Request                                              | Result                                          |
| ---- | ---------------------------------------------------- | ----------------------------------------------- |
| 1    | `GET /3/movie/now_playing?region=RU&page=1`          | Up to 20 movies per page, cached for 30 minutes |
| 2    | `GET /3/movie/{id}/showtimes?country=RU` for each id | Venues and times, where known                   |

The loop below retries once or twice when the plan limit is reached, waiting the number of seconds in `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');
}
```

A page of 20 titles is 20 showtime requests. On the 20 requests per minute plan that uses the whole window, so cache the result on your side. See [trending and lists](https://amodb.dev/trending-lists/) for the list parameters.

## Errors

The error body follows TMDB: `success`, `status_code` and `status_message`. A bad key shows `status_code` 7.

| HTTP | status_code | When                                                               |
| ---- | ----------- | ------------------------------------------------------------------ |
| 401  | 7           | The key is missing or wrong.                                       |
| 402  | 36          | The plan period has ended.                                         |
| 404  | 34          | No movie with that id.                                             |
| 429  | 25          | Over your requests per minute. Wait for the `Retry-After` seconds. |

No showtimes is not an error: expect status 200 and an empty `results` array. A missing or invalid `country` is not an error either. See [errors](https://amodb.dev/errors/) and [rate limits](https://amodb.dev/rate-limits/).

## Practical notes

- Coverage varies by country and title. Treat an empty `results` array as unknown, not as not showing.
- Show `start` exactly as returned. It is the venue's local time with no UTC offset, and the venue's own clock is what visitors expect.
- Showtimes are cached at the edge for 30 minutes. Do not request them for every page view, and keep your own cache short.
- Reuse one now playing list for all visitors in a region. It is cached for 30 minutes at the edge too.
- Use `booking_url` to send a visitor to the venue's booking page. It is `null` when the venue gives no link.
- For the use case overview, see [cinema showtimes API](https://amodb.dev/cinema-showtimes-api/), and for the other data on a movie, see [movies](https://amodb.dev/movies/).

## Questions and answers

### Is the country parameter required?

No, but you need it to get venues. Send a two letter code such as RU or DE. Without country, or with a code that is not two letters, results is empty and the countries list shows where showtimes exist. The region parameter works as an alias.

### What does an empty results array mean?

It means no showtimes are known for that title in that country from today on. It does not prove the film is not on screen. The countries list still shows other countries with data. Offer the release date from the movie details instead.

### How do I find movies that are in cinemas now?

Call GET /3/movie/now_playing with the region parameter, then request showtimes for the ids you care about. The list is cached for 30 minutes, so you can reuse it for every visitor.

### Are the times in my visitor's time zone?

No. The start value is the local time at the venue and has no UTC offset. Each venue also has a timezone such as Europe/Moscow. Show start as returned and do not convert it with the visitor's time zone.

## Related pages

- [Cinema showtimes API](https://amodb.dev/cinema-showtimes-api/): Cinema showtimes API: GET /3/movie/{movie_id}/showtimes with a country code returns cinemas, start times and formats where known. Pair it with now_playing.
- [Trending and list endpoints](https://amodb.dev/trending-lists/): Trending movies API with TMDB v3 paths: day and week charts, plus now playing, popular, top rated and upcoming lists for movies and TV, cached for 30 minutes.
- [Movie details API](https://amodb.dev/movies/): Movie details API with the same paths and JSON as TMDB v3. Get one movie by id, add credits, ratings and moods with append_to_response, in 14 languages.
- [Movie and TV ratings](https://amodb.dev/ratings/): Movie ratings API that returns IMDb, Kinopoisk, Metacritic, Rotten Tomatoes and TMDB scores for a title in one call, with null for any source not known.
- [Rate limits](https://amodb.dev/rate-limits/): amodb limits each key by requests per minute in a sliding 60 second window: 20, 40 or 120 by plan. Read the rate limit headers and handle 429 with Retry-After.
- [Quickstart](https://amodb.dev/quickstart/): Make your first amodb call: get a key, request movie details in curl, JavaScript, Python, PHP or Go, then load the poster from img.amodb.dev. Under 2 minutes.

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