Skip to content

Usage

This library provides multiple functions for accessing JustWatch:

  • search - search for entries based on title
  • popular - get a list of currently popular titles
  • details - get details for a title based on its ID
  • seasons - get information about all seasons of a show
  • episodes - get information about all episodes of a season
  • offers_for_countries - get offers for a title for multiple countries simultaneously
  • providers - get data about all available providers (like Netflix) in a country

All functions return response from JustWatch API parsed into a NamedTuple, check Data structures page for more details.

All needed functions, data structures, raised exceptions are available through single module - simplejustwatchapi.

Examples of parsed responses are in the GitHub repository in examples/.


Each function can raise two exceptions:

You can check Exceptions page for more details.


Functions

Common arguments

Most functions have a number of common arguments (in addition to function-specific ones, like title to search for):

Name Description
country 2-letter country code for which offers will be returned, e.g., US, GB, DE.
language Code for language in responses. It consists of 2 lowercase letters with optional uppercase alphanumeric suffix (e.g., en, en-US, de, de-CH1901).
best_only Whether to return only "best" offers for each provider instead of, e.g., separate offers for SD, HD, and 4K.

Functions returning data for multiple titles (search, popular) also allow for specifying number of elements, basic pagination, and filtering for specific providers:

Name Description
count How many entries should be returned.
offset Basic "pagination". Offset for the first returned result, i.e. how many first entries should be skipped. Everything is handled on API side, this library isn't doing any filtering.
providers Providers (like Netflix, Amazon Prime Video) for which offers should returned. Requires 3-letter "short name". Check Provider codes page for an example of how you can get that value.

Search for a title

search function allows for searching entries based on a given title.

from simplejustwatchapi import search

results = search("The Matrix", "US", "en", 5, True, 0, ["nfx", "apv"])

for entry in results:
    print(entry.title, entry.offers)

Whitespaces in title

Value of the given title isn't stripped, so passing a string with multiple spaces will look them up. For more than 1 space it will probably return an empty list.

All arguments are optional.

First argument is just a string to look up. If empty, or not provided, you'll get a selection of popular titles, similar to popular function.

For very large searches (high count value) I recommend using default best_only=True to avoid issues with operation complexity. Alternatively you can offset for basic pagination.

Example function call and its output is in examples/search_output.py.

popular function allows for getting a list of currently popular titles.

from simplejustwatchapi import popular

results = popular("US", "en", 5, True, 0, ["nfx", "apv"])

for entry in results:
    print(entry.title, entry.offers)

All arguments are optional.

The usage and output will be similar to search, function without any titles specified.

No arguments are required.

For very large searches (high count value) I recommend using default best_only=True to avoid issues with operation complexity. Alternatively you can offset for basic pagination.

Example function call and its output is in examples/popular_output.py.

Details for a title based on its ID

details function allows for looking up details for a single entry via its node ID.

from simplejustwatchapi import details

result = details("tm19698", "US", "en", False)

print(result.title, result.short_description)

Node ID can be taken from output of the search function.

Usefulness versus search

This function is only useful if you have node ID already stored. There's no reason to first use the search, then use node ID from one of entries for details, you won't get any additional information.

Only the first argument is required - the node ID of element to look up details for.

This function can be used for all types of media - shows, movies, episodes, seasons (the last two having their dedicated functions described below), for all types the result is a single MediaEntry. Some fields are specific for one of the media types and will be None for others - for example:

  • total_episode_count is only present for seasons
  • season_number is present for seasons and episodes
  • episode_number is present only for episodes
  • age_certification is present only for movies and shows

For episodes specifically most of the fields will be empty (which is why episodes function returns different structure).

Example function call and its output is in examples/details_output.py.

Details for all seasons of a TV show

seasons function allows for looking up details for all seasons of a TV show based on its node ID.

from simplejustwatchapi import seasons

results = seasons("tss20091", "US", "en", True)

for season in results:
    print(season.season_number, season.total_episode_count)

Only the first argument is required - the node ID of a TV show to look up season details for.

Example function call and its output is in examples/seasons_output.py.

Details for all episodes of a TV show

episodes function allows for looking up details for all episodes of a single TV show season based on its node ID.

from simplejustwatchapi import episodes

results = episodes("tse334769", "US", "en", False)

for episode in results:
    print(episode.episode_id, episode.episode_number, episode.offers)

Only the first argument is required - the node ID of a season to look up episode details for.

Returned value is a list of Episode, which contains only a small subset of fields from the MediaEntry. JustWatch API doesn't return "full" data for individual episodes.

Example function call and its output is in examples/episodes_output.py.

Get offers for multiple countries for a single title

offers_for_countries function allows for looking up offers for a single entry, but for multiple countries at once. Only offers are returned.

from simplejustwatchapi import offers_for_countries

results = offers_for_countries("tm10", {"US", "UK", "CA"}, "en", True)

for country, offers in results.items():
    print(f"Offers for {country}:")
    for offer in offers:
        print(f"  - {offer.package.name}: {offer.monetization_type}")

First two arguments are required - ID, and a set of country codes.

Example function call and its output is in examples/offers_for_countries_output.py.

Get all available providers for a country

providers function allows for looking up all available service providers (such as "Netflix", "Amazon Prime Video", etc.) for a given country.

from simplejustwatchapi import providers

results = providers("US")

netflix_apple_only = [
    provider
    for provider in all_providers
    if provider.name in ("Netflix", "Apple TV")
]

Returned value is a list of OfferPackage. Initially they were meant to be used for Offer in MediaEntry/Episode, however the data structure matches output here, so it's reused.

You can use this function to get values for providers for search and popular functions, the short_name field in OfferPackage is the exact 3-letter code needed there.

Example function call and its output is in examples/providers_output.py.


Error handling

HTTP errors

JustWatchHttpError is raised when HTTP-related error occurs, e.g., JustWatch API responds with non-2xx status code.

Non-2xx response status codes can happen when trying to use incorrect type for parameters, e.g., trying to use a non-numeric string for count:

from simplejustwatchapi import search, JustWatchHttpError

try:
    results = search("The Matrix", count="five")
except JustWatchHttpError as e:
    print(str(e), e.response)

Aside from exception message, the error can also contains optional field response with full response text as string. This will only contain data if error is related to the response message, otherwise it's None. Usually it is a JSON (in string form) with API errors, if these specific errors are also causing non-2xx status codes.

Numeric strings instead of int

Since requests are send as a JSON you can use strings for int arguments, as long as they are numeric strings, like 5, instead of five:

from simplejustwatchapi import search

results = search("The Matrix", count="5")
# No exception is raised.

API errors

JustWatchApiError is raised when no HTTP-related errors occur, but the internal JSON response contain errors.

API errors can occur for invalid country code:

from simplejustwatchapi import search, JustWatchApiError

try:
    # Country code matches 2-letter pattern, but isn't a valid code for any country.
    results = search("The Matrix", country="xx")
except JustWatchApiError as e:
    # Print all error messages.
    error_messages = [error.get("message") for error in e.errors]
    print(",".join(error_messages))

It can occur for language codes not matching expected pattern:

from simplejustwatchapi import search, JustWatchApiError

try:
    # Language code "xx" also isn't valid for any languages, but since it matches the
    # pattern it would default to English.
    results = search("The Matrix", language="xxx")
except JustWatchApiError as e:
    # Print only error codes.
    # Codes are collected to a set, as the API will return an error for each place,
    # where language code is used, in all offers, descriptions, etc.
    error_codes = {error["extensions"]["code"] for error in e.errors}
    print(",".join(error_codes))

Using title, instead of ID in details function:

from simplejustwatchapi import details, JustWatchError

try:
    # "details" expects an ID, not a title.
    results = details("The Matrix")
except JustWatchError as e:
    # JustWatchError will catch both API and HTTP exceptions.
    print(e.errors)

Too high operation complexity due to too large count:

from simplejustwatchapi import search, JustWatchApiError

try:
    results = search("The Matrix", count=500)
except JustWatchApiError as e:
    error_messages = [error.get("message") for error in e.errors]
    print(",".join(error_messages))

These are just examples of internal API errors, which cause JustWatchApiError exception.


More complicated examples

You can combine providers and popular functions:

from simplejustwatchapi import popular, providers

# Get all providers in the US.
all_providers = providers("US")

# Filter only required providers by name.
netflix_apple_only = [
    provider.short_name  # We only need the codes for filtering.
    for provider in all_providers
    if provider.name in ("Netflix", "Apple TV")  # Get providers we need.
]

# Use found codes for filtering.
filtered_popular = popular("US", providers=netflix_apple_only)

Get offers for each episode of a TV show based on title

You can combine search, seasons and episodes functions:

from simplejustwatchapi import episodes, search, seasons

title = "True Detective"

# Search for a title.
search_results = search(title)

# Look for a first match with the expected title.
first_match = next(
    result
    for result in search_results
    if result.title == title and result.object_type == "SHOW"
)

# Get all seasons.
all_seasons = seasons(first_match.entry_id)

# Create a dict with episode offers.
id_to_episodes_offers = {
    season.season_number: {
        episode.episode_number: episode.offers
        for episode in episodes(season.entry_id)
    }
    for season in all_seasons
}

Get offers for multiple countries for all seasons of a TV show

You can combine search, seasons and offers_for_countries functions:

from simplejustwatchapi import offers_for_countries, search, seasons

title = "Andor"

# Search for a title.
search_results = search(title)

# Look for a first match with the expected title.
first_match = next(
    result
    for result in search_results
    if result.title == title and result.object_type == "SHOW"
)

# Get all seasons.
all_seasons = seasons(first_match.entry_id)

# Get offers for each season for each country.
countries = {"US", "DE"}
season_offers = [
    offers_for_countries(season.entry_id, countries)
    for season in all_seasons
]

# Convert to a dict of country codes to list of offers.
season_offers_per_country = {
    country: [
        season[country]
        for season in season_offers
    ]
    for country in countries
}

Pagination through offset

When trying to get as much data as possible with search or popular functions and avoid issues with operation complexity you can use offset parameter to set up a basic pagination:

from simplejustwatchapi import popular

i = 0
page = 99
all_results = []
while results := popular(count=page, offset=i):
    i += page
    all_results.extend(results)
# len(all_results) == 1980

Maximum number of responses

1999 is the limit of number of entries you can get from the JustWatch API using this method. Check Maximum number of entries page for more details.