International Showtimes API
Version: 5
Base URI: https://api.internationalshowtimes.com/v5
Introduction
Welcome
Welcome to the Documentation for the International Showtimes API. We include movie metadata, showtimes data, ticket deep linking in one simple API for your online or offline content, apps or services. We are delivering best data for Europe, USA, Oceania, Asia Pacific, South America and other planets you might be looking for.
Support
Please raise any questions or report issues regarding the API via our JIRA Service Desk System.
Authentication
An apikey
must be sent with every request. To get your API-Key sign up for a free trial.
There are multiple options to send the apikey
:
- HTTP Authentication: Token Access Authentication
- Example:
curl "https://api.internationalshowtimes.com/v5/cinemas/" -H "Authorization: Token token=YOUR_API_KEY"
- Example:
- HTTP Header 'X-API-Key'
- Example:
curl "https://api.internationalshowtimes.com/v5/cinemas/" -H "X-Api-Key: YOUR_API_KEY"
- Example:
- URL parameter
- Example:
curl "https://api.internationalshowtimes.com/v5/cinemas/?apikey=YOUR_API_KEY"
- Example:
Please avoid sending the apikey
via URL parameter if possible. Use one of the HTTP Headers options instead!
Example Requests
The following examples demonstrate the usage of basic query parameters for some use simple cases. Most of the available parameters work like filters and be combined according to your needs. Values in curly braces are placeholder.
Get all cinemas in a specific country
GET https://api.internationalshowtimes.com/v4/cinemas/?countries=DE
Get all cinemas at a specific coordinate within a distance of 30 kilometres.
GET https://api.internationalshowtimes.com/v4/cinemas/?location=52.5,13.37&distance=30
How to get all movies playing in a particular cinema
GET https://api.internationalshowtimes.com/v4/movies/?cinema_id={ID}
Search for a movie by german title
GET https://api.internationalshowtimes.com/v4/movies?search_query=Avengers&search_field=title&lang=de
Get a list of upcoming movies for Germany
GET https://api.internationalshowtimes.com/v4/movies?include_upcomings=true&countries=DE&release_date_from={DATE}
release_date_from
should be set to a date slightly in the future to exclude current movies, for example tomorrow or today + 1 week.
Fetch only a subset of available fields for a particular movie
GET https://api.internationalshowtimes.com/v4/movies/30767?fields=id,title,original_title,release_dates,imdb_id
Get all showtimes of a movie playing in all theatres within a radius of 30 kilometres around a certain coordinate
GET https://api.internationalshowtimes.com/v4/showtimes?movie_id=18047&location=52.331705,13.37&distance=30
Get all showtimes per movie in a specific City
GET https://api.internationalshowtimes.com/v4/showtimes?city_ids=1&movie_id=12345
Localization
Movie metadata is available in different languages and locales. To specify the locale for retrieving movie metadata include a supported locale via one of the following ways. The locale can be specified for any requests which include movie data (such as the movies or the showtimes endpoints).
URL parameter lang
- Example:
curl "https://api.internationalshowtimes.com/v5/movies/?lang=de"
HTTP Header Accept-Language
Any valid value as specified in RFC2616 will be handled.
- Example:
curl "https://api.internationalshowtimes.com/v5/movies/" -H "Accept-Language: de"
Fetch the Locale - index endpoint to see which locales are available.
Miscellaneous
Identifiers
All identifiers are of type string
even if they could actually also be integer
. The reason for that is simply the role of these values being nothing but identifiers. This means even if the strings are serial numbers or any other logic, there is no guarantee it will stay the same. Hence, building anything based on any identifier structure may break in the future.
JSON Keys
When comes to naming JSON keys there are many debates about CamelCase vs underscores. Considering JSON actually standing for JavaScript Object Notation means it should be CamelCase - as that's native to JavaScript, we think underscores have a better readability.
API Updates
As of mid 2019 the API has been updated with a new major version. Click over here if you need to access the documentation for the previous version.
2023-01-18:
New
- Showtimes endpoint
- Added new filter for
attribute_codes
property to retrieve showtimes
- Added new filter for
2021-01-14:
New
- Showtimes endpoint
- Added
changed_since
query parameter, that allows to fetch incremental showtimes updates.
- Added
2019-05-05: V4 → V5
New
- new Attribute endpoint
Model Updates
Country Model Updates
change | description |
---|---|
new | continent property |
Showtimes Model Updates
change | description |
---|---|
new | attribute_codes property |
removed | is_3d is now covered via of new attributes property |
removed | is_imax is now covered via of new attributes property |
API Endpoints
Attributes
Movie screenings are held in a variety of differnt experiences by showing different version of the movies (e.g. 3D or IMAX) or adding other features to the event. Each experience added to a showtime is considered an attribute of it.
Retrieve the list of all attributes.
Use HEAD requests to query total number / count of a attributes. Allows to apply all filters as available via GET.
Locales
Countries
Cinema data, as well as showtime data, is available in many countries. However, access may be only granted to a limited subset for a given API-key. Use this endpoint to see which countries are available in general and to your apikey.
Retrieve the list of all countries.
Use HEAD requests to query total number / count of a countries. Allows to apply all filters as available via GET.
Cities
Cinemas
The collection of cinemas.
Retrieve the list of all cinemas, optionally filtered.
Use HEAD requests to query total number / count of a cinemas. Allows to apply all filters as available via GET.
Cinema Chains
Movies
The collection of movies.
Retrieve a shallow list of movies (in theatres if not specified otherwise). See the fields
query parameters default value for the list of included fields.
Use HEAD requests to query total number / count of a movies. Allows to apply all filters as available via GET.
Genres
Showtimes
The collection of showtimes.
Retrieve the list of all showtimes, optionally filtered.
Use HEAD requests to query total number / count of a showtimes. Allows to apply all filters as available via GET.
Advanced
Connectivity
HTTPS only
The API uses TLS to provide a secure way to deliver its data. Even though the API just supplies cinema and showtime data, we think that it's the right thing to do to encrypt the entire traffic. Furthermore, we only support TLS v1.0, v1.1 and v1.2. We do not support SSL v2 or v3 for a good reason. If your client uses HTTP to connect, the API redirects (HTTP code 301) to https://api.internationalshowtimes.com/v5/.
IPv6 ready
We enabled IPv6 on api.internationalshowtimes.com and videos.internationalshowtimes.com improve connectivity and have your API client ready for the future. Read more about IPv6.
Get DNS AAAA records (IPv6) using dig: dig AAAA api.internationalshowtimes.com
What is IPv6 and why do we need it?
The Internet operates by transferring data between networks in packets. In order to communicate and send/receive packets of data, each host, computer or other device connected to the Internet must be identified by a unique IP address. IPv4 has approximately four billion IP addresses (the sequence of numbers assigned to each Internet-connected device). The explosion in the number of people, devices, and web services on the Internet means that IPv4 is running out of space. IPv6, the next-generation Internet protocol which provides more than 340 trillion, trillion, trillion addresses, will connect the billions of people not connected today, allow a huge range of devices to connect directly with one another, and help ensure the Internet can continue its current growth rate indefinitely. Both IPv4 and IPv6 (and many other protocols at the core of the Internet) were developed by the Internet Engineering Task Force (IETF).
HTTP Caching
This API supports HTTP caching, which is highly recommended to take advantage of in order to avoid unnecessary transfer of data.
The main idea is that data will only be sent to the client, if something has changed. To make use of this approach this API provides a Last-Modified
header for each response. Once the client receives it, it should save the modification date to pass it to subsequent requests using If-Modified-Since
header. This header makes a request (GET or HEAD) conditional: the server will send back the requested data only if it has been modified after the given timestamp. Otherwise, an empty response with a 304 Not Modified status code will be returned. This is especially useful for checking about showtime updates frequently.
Learn more:
- Understanding HTTP/304 Responses
- HTTP Caching by Mozilla
Errors
Errors may be returned with a JSON payload which is structured as followed:
{
"error": {
"code": <Numeric error code>,
"user_message": <string message ready to be display to the user>
"debug_message": <string message intended for the developer to help resolving the error>
}
}
The internal_message
is not present for all errors and may not be exposed according to the apikey
's permissions.
Error codes are structured by error domains:
Range | Error Domain |
---|---|
10000 | General: Retrieving data (Cinemas, Movies, Showtimes etc.) |
20000 | Ticketing |
30000 | User management |
Error Codes
Code | Error |
---|---|
10001 | Service unavailable for maintenance |
10002 | Unauthorized due to missing apikey |
10003 | Unauthorized due to unknown apikey |
10004 | Requested countries are forbidden for given apikey |
10005 | Unauthorized due to expired apikey |
10006 | Parameter validation failed |
10007 | Resource not found |
10008 | Undefined route / endpoint |
10009 | Resource was deleted due to duplicate. |
10010 | No permission to access requested resource. |
Maintenance
In case of maintenance either all calls or specific calls will return a 503
response with the following payload (body). Make sure you also check the error code 10001
given with the response payload.
{
"error": {
"code": 10001,
"user_message": "service unavailable for maintenance"
}
}
Code Examples
The following code examples fetch a list of movies from Great Britains cinemas.
cURL
curl -X "GET" "https://api.internationalshowtimes.com/v4/movies/?countries=GB" -H "X-API-Key: YOUR_API_KEY"
GO
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func sendList() {
// Create client
client := &http.Client{}
// Create request
req, err := http.NewRequest("GET", "https://api.internationalshowtimes.com/v4/movies/?countries=GB", nil)
// Headers
req.Header.Add("X-API-Key", "YOUR_API_KEY")
parseFormErr := req.ParseForm()
if parseFormErr != nil {
fmt.Println(parseFormErr)
}
// Fetch Request
resp, err := client.Do(req)
if err != nil {
fmt.Println("Failure : ", err)
}
// Read Response Body
respBody, _ := ioutil.ReadAll(resp.Body)
// Display Results
fmt.Println("response Status : ", resp.Status)
fmt.Println("response Headers : ", resp.Header)
fmt.Println("response Body : ", string(respBody))
}
JavaScript + jQuery
jQuery.ajax({
url: "https://api.internationalshowtimes.com/v4/movies/",
type: "GET",
data: {
"countries": "GB",
},
headers: {
"X-API-Key": "YOUR_API_KEY",
},
})
.done(function(data, textStatus, jqXHR) {
console.log("HTTP Request Succeeded: " + jqXHR.status);
console.log(data);
})
.fail(function(jqXHR, textStatus, errorThrown) {
console.log("HTTP Request Failed");
})
.always(function() {
/* ... */
});
Java (Apache HttpClient via Fluent API)
import java.io.IOException;
import org.apache.http.client.fluent.*;
public class SendRequest
{
public static void main(String[] args) {
sendRequest();
}
private static void sendRequest() {
try {
// Create request
Content content = Request.Get("https://api.internationalshowtimes.com/v4/movies/?countries=GB")
// Add headers
.addHeader("X-API-Key", "YOUR_API_KEY")
// Fetch request and return content
.execute().returnContent();
// Print content
System.out.println(content);
}
catch (IOException e) { System.out.println(e); }
}
}
Node.js
(function(callback) {
'use strict';
const httpTransport = require('https');
const responseEncoding = 'utf8';
const httpOptions = {
hostname: 'api.internationalshowtimes.com',
port: '443',
path: '/v4/movies/?countries=GB',
method: 'GET',
headers: {"X-API-Key":"YOUR_API_KEY"}
};
httpOptions.headers['User-Agent'] = 'node ' + process.version;
// Paw Store Cookies option is not supported
const request = httpTransport.request(httpOptions, (res) => {
let responseBufs = [];
let responseStr = '';
res.on('data', (chunk) => {
if (Buffer.isBuffer(chunk)) {
responseBufs.push(chunk);
}
else {
responseStr = responseStr + chunk;
}
}).on('end', () => {
responseStr = responseBufs.length > 0 ?
Buffer.concat(responseBufs).toString(responseEncoding) : responseStr;
callback(null, res.statusCode, res.headers, responseStr);
});
})
.setTimeout(120000)
.on('error', (error) => {
callback(error);
});
request.write("")
request.end();
})((error, statusCode, headers, body) => {
console.log('ERROR:', error);
console.log('STATUS:', statusCode);
console.log('HEADERS:', JSON.stringify(headers));
console.log('BODY:', body);
});
PHP + cURL
<?php
// Get cURL resource
$ch = curl_init();
// Set url
curl_setopt($ch, CURLOPT_URL, 'https://api.internationalshowtimes.com/v4/movies/?countries=GB');
// Set method
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
// Set options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Set headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"X-API-Key: YOUR_API_KEY",
]
);
// Send the request & save response to $resp
$resp = curl_exec($ch);
if(!$resp) {
die('Error: "' . curl_error($ch) . '" - Code: ' . curl_errno($ch));
} else {
echo "Response HTTP Status Code : " . curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo "\nResponse HTTP Body : " . $resp;
}
// Close request to clear up some resources
curl_close($ch);
Python + Requests
# Install the Python Requests library:
# `pip install requests`
import requests
def send_request():
try:
response = requests.get(
url="https://api.internationalshowtimes.com/v4/movies/",
params={
"countries": "GB",
},
headers={
"X-API-Key": "YOUR_API_KEY",
},
)
print('Response HTTP Status Code: {status_code}'.format(
status_code=response.status_code))
print('Response HTTP Response Body: {content}'.format(
content=response.content))
except requests.exceptions.RequestException:
print('HTTP Request failed')
Ruby
require 'net/http'
require 'net/https'
def send_request
uri = URI('https://api.internationalshowtimes.com/v4/movies/?countries=GB')
# Create client
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
# Create Request
req = Net::HTTP::Get.new(uri)
# Add headers
req.add_field "X-API-Key", "YOUR_API_KEY"
# Fetch Request
res = http.request(req)
puts "Response HTTP Status Code: #{res.code}"
puts "Response HTTP Response Body: #{res.body}"
rescue StandardError => e
puts "HTTP Request failed (#{e.message})"
end
Swift
class MyRequestController {
func sendRequest() {
/* Configure session, choose between:
* defaultSessionConfiguration
* ephemeralSessionConfiguration
* backgroundSessionConfigurationWithIdentifier:
And set session-wide properties, such as: HTTPAdditionalHeaders,
HTTPCookieAcceptPolicy, requestCachePolicy or timeoutIntervalForRequest.
*/
let sessionConfig = URLSessionConfiguration.default
/* Create session, and optionally set a URLSessionDelegate. */
let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
guard var URL = URL(string: "https://api.internationalshowtimes.com/v4/movies/") else {return}
let URLParams = [
"countries": "GB",
]
URL = URL.appendingQueryParameters(URLParams)
var request = URLRequest(url: URL)
request.httpMethod = "GET"
// Headers
request.addValue("YOUR_API_KEY", forHTTPHeaderField: "X-API-Key")
/* Start a new Task */
let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
if (error == nil) {
// Success
let statusCode = (response as! HTTPURLResponse).statusCode
print("URL Session Task Succeeded: HTTP \(statusCode)")
}
else {
// Failure
print("URL Session Task Failed: %@", error!.localizedDescription);
}
})
task.resume()
session.finishTasksAndInvalidate()
}
}
protocol URLQueryParameterStringConvertible {
var queryParameters: String {get}
}
extension Dictionary : URLQueryParameterStringConvertible {
/**
This computed property returns a query parameters string from the given NSDictionary. For
example, if the input is @{@"day":@"Tuesday", @"month":@"January"}, the output
string will be @"day=Tuesday&month=January".
@return The computed parameters string.
*/
var queryParameters: String {
var parts: [String] = []
for (key, value) in self {
let part = String(format: "%@=%@",
String(describing: key).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!,
String(describing: value).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
parts.append(part as String)
}
return parts.joined(separator: "&")
}
}
extension URL {
/**
Creates a new URL by adding the given query parameters.
@param parametersDictionary The query parameter dictionary to add.
@return A new URL.
*/
func appendingQueryParameters(_ parametersDictionary : Dictionary<String, String>) -> URL {
let URLString : String = String(format: "%@?%@", self.absoluteString, parametersDictionary.queryParameters)
return URL(string: URLString)!
}
}