# Letterboxd Scraper — Films, Ratings, Watchlists & Lists (`hipersoft/letterboxd-scraper`) Actor

Scrape Letterboxd films with ratings, rating counts, genres, director, cast, runtime and synopsis. Feed it film pages, a user's films/watchlist/diary, any list URL, or browse pages. For film data, recommendations and research.

- **URL**: https://apify.com/hipersoft/letterboxd-scraper.md
- **Developed by:** [hiper soft](https://apify.com/hipersoft) (community)
- **Categories:** Videos, Social media
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.00212 / film scraped

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Letterboxd Scraper — Films, Ratings, Watchlists, Lists & More

Extract rich film data from **Letterboxd** — **average rating, number of ratings, watches, likes, fans, genres, directors, cast, runtime, synopsis, countries, languages, studios, themes, streaming availability and poster** — into clean JSON, CSV or Excel. Point it at **individual films**, a **user's watchlist or diary**, any **list**, a **director or actor**, a **genre**, a **browse page**, or just a **search term**. Fast and reliable.

Great for **film datasets, recommendation engines, ranking & analytics, watchlist backups and research**.

![Letterboxd Scraper input — start URLs, search and film limit in the Apify Console](https://api.apify.com/v2/key-value-stores/SUfvnaFLd9z9eBCtV/records/letterboxd-scraper-input.png?v=2)

### What you can scrape

- 🎬 **Single films** — `letterboxd.com/film/parasite-2019/` (or a bare slug like `parasite-2019`)
- 👤 **A user's watchlist or diary** — `letterboxd.com/USERNAME/watchlist/`, `.../films/diary/`
- 📋 **Any list** — `letterboxd.com/USERNAME/list/LIST-NAME/`
- 🎬 **A director or actor's films** — `letterboxd.com/director/greta-gerwig/`, `/actor/NAME/`
- 🎭 **A genre** — `letterboxd.com/films/genre/horror/`, or the Genre field
- 🔥 **Browse pages** — popular this week, popular all-time, highest rated, newest
- 🔎 **Search** — pass a title or keyword and get matching films

Give it any mix as **Start URLs** (plus optional search/genre) and it pulls full metadata for every film.

### Example input

```json
{
  "startUrls": [
    "https://letterboxd.com/films/popular/this/week/",
    "https://letterboxd.com/schaffrillas/watchlist/",
    "https://letterboxd.com/film/parasite-2019/"
  ],
  "search": "blade runner",
  "sort": "FilmPopularityThisWeek",
  "maxFilms": 200,
  "includeStatistics": true
}
```

### What you get

![Letterboxd Scraper output example — film records with ratings, cast and genres as structured JSON](https://api.apify.com/v2/key-value-stores/SUfvnaFLd9z9eBCtV/records/letterboxd-scraper-output.png?v=5)

One row per film:

```json
{
  "title": "Parasite",
  "year": 2019,
  "rating": 4.52,
  "ratingCount": 5664177,
  "watches": 8600000,
  "likes": 4200000,
  "fans": 210000,
  "reviewCount": 480000,
  "director": ["Bong Joon Ho"],
  "genres": ["Thriller", "Comedy", "Drama"],
  "runtimeMinutes": 133,
  "cast": ["Song Kang-ho", "Lee Sun-kyun", "Cho Yeo-jeong", "…"],
  "countries": ["South Korea"],
  "languages": ["Korean", "English"],
  "studios": ["Barunson E&A"],
  "themes": ["…"],
  "synopsis": "…",
  "poster": "https://a.ltrbxd.com/resized/film-poster/%E2%80%A6jpg",
  "imdbUrl": "https://www.imdb.com/title/tt6751668/",
  "tmdbUrl": "https://www.themoviedb.org/movie/496243",
  "url": "https://letterboxd.com/film/parasite-2019/"
}
```

#### Output schema

| Field | Type | Description |
| --- | --- | --- |
| `slug` | string | Letterboxd film slug (e.g. `parasite-2019`) |
| `lid` | string | Letterboxd internal film ID |
| `title` | string | Film title |
| `year` | string | Release year |
| `rating` | string | Average Letterboxd rating (out of 5) |
| `ratingCount` | integer | Number of ratings |
| `bestRating` | integer | Maximum possible rating on the scale |
| `director` | array | Director(s) |
| `genres` | array | Genre tags |
| `runtimeMinutes` | string | Runtime in minutes |
| `tagline` | string | Film tagline |
| `synopsis` | string | Plot synopsis |
| `cast` | array | Cast members |
| `countries` | array | Production countries |
| `languages` | array | Spoken languages |
| `studios` | array | Production studios |
| `poster` | string | Poster image URL |
| `imdbUrl` | string | Link to the film on IMDb |
| `tmdbUrl` | string (URL) | Link to the film on TMDB |
| `watches` | integer | Number of users who logged a watch |
| `likes` | integer | Number of likes |
| `fans` | integer | Number of fans |
| `listAppearances` | integer | Number of lists the film appears on |
| `reviewCount` | integer | Number of written reviews |
| `themes` | array | Theme tags |
| `url` | string (URL) | Link to the film's Letterboxd page |
| `streaming` | array | Where the film is available to stream/rent/buy (when `includeAvailability` is on) |

### Input fields

| Field | Description |
|-------|-------------|
| `startUrls` | Film pages, a user's `watchlist/` or `films/diary/`, a `list/`, a `director/`/`actor/` page, a `films/genre/` page, or browse/popular pages. Bare film slugs also work. |
| `search` | Optional free-text film search (title or keyword). |
| `genre` | Optional genre to browse (e.g. horror, comedy, drama, science fiction, documentary). |
| `sort` | Sort order for browse/genre pages: popular this week, popular all-time, highest rated, newest, or name. |
| `maxFilms` | Max films to scrape in total across all inputs (up to 100,000). |
| `includeStatistics` | Include rating count, watches, likes, fans, review and list counts (on by default). |
| `includeAvailability` | Include where each film is available to stream/rent/buy (adds a `streaming` field). |

### Use cases

- **Build a film dataset** — ratings, rating counts, genres and crew for thousands of titles
- **Recommendation & ranking** — use real Letterboxd ratings, rating counts and popularity as signal
- **Watchlist backup** — export a user's watchlist to a spreadsheet
- **Popularity & rating analysis** — scrape a browse page and crunch the numbers
- **Enrich your movie app** — pull posters, runtime, cast, synopsis and IMDb/TMDB links by title or URL

### FAQ

**How many films can I scrape?**
Set `maxFilms` up to 100,000. Browse pages and watchlists are paged through automatically.

**Can I scrape a specific user's watchlist?**
Yes — use their `watchlist/` URL as a start URL.

**How does billing work?**
Pay per film scraped — you only pay for the films you actually get.

**Do I need any setup?**
No — just add your inputs and run. Fast and reliable.

**Is this only public data?**
Yes. It returns only publicly available Letterboxd data.

**Can I connect this to other tools?**
The Letterboxd Scraper can be connected with almost any cloud service or web app thanks to [integrations on the Apify platform](https://apify.com/integrations). It works with [Make](https://apify.com/integrations/make), [Zapier](https://apify.com/integrations/zapier), [Slack](https://docs.apify.com/platform/integrations/slack), [Airbyte](https://docs.apify.com/platform/integrations/airbyte), [GitHub](https://docs.apify.com/platform/integrations/github), [Google Drive](https://docs.apify.com/platform/integrations/drive) and [many more](https://apify.com/integrations), plus the [Apify API](https://docs.apify.com/api/v2), JavaScript/Python clients and MCP. Or use [webhooks](https://docs.apify.com/platform/integrations/webhooks) to trigger an action whenever a run finishes.

### Related Actors

- [TVmaze Scraper](https://apify.com/hipersoft/tvmaze-scraper) — TV shows, episodes and cast
- [Steam Games Scraper](https://apify.com/hipersoft/steam-games-scraper) — game catalog, prices and reviews
- [Google Trends Scraper](https://apify.com/hipersoft/google-trends-scraper) — interest over time for any title

### Notes

Original clean-room implementation. Returns only public Letterboxd data; you are responsible for how you use the data and for complying with Letterboxd's terms. This is an independent tool and is not affiliated with or endorsed by Letterboxd.

# Actor input Schema

## `startUrls` (type: `array`):

Letterboxd URLs to scrape. Each can be a film page (letterboxd.com/film/parasite-2019/), a user's watchlist (letterboxd.com/USER/watchlist/) or diary (letterboxd.com/USER/films/diary/), a list (letterboxd.com/USER/list/NAME/), a director/actor page (letterboxd.com/director/greta-gerwig/, /actor/NAME/), a genre page (letterboxd.com/films/genre/horror/), or a browse/popular page (letterboxd.com/films/popular/this/week/, /films/by/rating/). Bare film slugs also work.

## `search` (type: `string`):

Optional: a free-text film search (title, keyword). Returns matching films with full details.

## `genre` (type: `string`):

Optional: browse a genre (e.g. horror, comedy, drama, science fiction, documentary). Combined with the sort order below.

## `sort` (type: `string`):

Sort order for browse pages (or when only a search/sort is given).

## `maxFilms` (type: `integer`):

Maximum number of films to scrape in total across all inputs.

## `includeStatistics` (type: `boolean`):

Include rating count, watches, likes, fans, review and list counts for each film (one extra lookup per film).

## `includeAvailability` (type: `boolean`):

Include where each film is available to stream/rent/buy (adds a 'streaming' field; one extra lookup per film).

## Actor input object example

```json
{
  "startUrls": [
    "https://letterboxd.com/schaffrillas/watchlist/",
    "https://letterboxd.com/film/parasite-2019/",
    "https://letterboxd.com/director/greta-gerwig/"
  ],
  "sort": "",
  "maxFilms": 100,
  "includeStatistics": true,
  "includeAvailability": false
}
```

# Actor output Schema

## `results` (type: `string`):

The scraped results as dataset items.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        "https://letterboxd.com/films/popular/this/week/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("hipersoft/letterboxd-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": ["https://letterboxd.com/films/popular/this/week/"] }

# Run the Actor and wait for it to finish
run = client.actor("hipersoft/letterboxd-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://letterboxd.com/films/popular/this/week/"
  ]
}' |
apify call hipersoft/letterboxd-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hipersoft/letterboxd-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/nS4IzBxzjLCC9dQnN/builds/BVWYIWcaZLycRPAX2/openapi.json
