# Letterboxd Scraper — Movie Reviews, Films, Profiles & Lists (`zhorex/letterboxd-scraper`) Actor

Scrape Letterboxd movie reviews, films, user profiles and popular or trending lists. Extract ratings, cast, crew, and review text. 4 modes in one Actor. No API key, no browser; runs on Apify residential proxy by default. Built for film researchers and content teams.

- **URL**: https://apify.com/zhorex/letterboxd-scraper.md
- **Developed by:** [Sami](https://apify.com/zhorex) (community)
- **Categories:** Social media, News, Other
- **Features:** Limited permissions
- **Stats:** 108 total users, 7 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 item scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Letterboxd Scraper - Films, Reviews, Profiles & Lists

Scrape **film details**, **user reviews**, **public profiles**, and **popular/trending films** from [Letterboxd](https://letterboxd.com), the social network for film lovers with 15M+ members. Lightweight HTTP-only scraper; it runs on Apify residential proxy by default, so leave the default on.

### How to scrape Letterboxd data in 3 easy steps

1. **Go to the [Letterboxd Scraper](https://apify.com/zhorex/letterboxd-scraper) page** on Apify and click **"Try for free"**
2. **Configure your input** — choose a mode (`film_details`, `film_reviews`, `user_profile`, or `popular_films`), paste Letterboxd URLs or slugs, and set `maxResults`
3. **Click "Run"**, wait for the scraper to finish, and **download your data** in JSON, CSV, or Excel

No coding required. Works with Apify's free plan.

### What can this scraper do?

#### Mode 1: Film Details (`film_details`)

Extract complete metadata for any film on Letterboxd.

**Input example:**

```json
{
    "mode": "film_details",
    "urls": [
        "https://letterboxd.com/film/parasite-2019/",
        "https://letterboxd.com/film/everything-everywhere-all-at-once/",
        "the-godfather"
    ]
}
```

**Output per film:**

```json
{
    "filmUrl": "https://letterboxd.com/film/parasite-2019/",
    "title": "Parasite",
    "year": 2019,
    "director": ["Bong Joon-ho"],
    "cast": ["Song Kang-ho", "Lee Sun-kyun", "Cho Yeo-jeong"],
    "genres": ["Comedy", "Drama", "Thriller"],
    "countries": ["South Korea"],
    "languages": ["Korean"],
    "runtime": 132,
    "averageRating": 4.6,
    "totalRatings": 1250000,
    "totalReviews": 85000,
    "totalLists": 120000,
    "posterUrl": "https://...",
    "tagline": "Act like you own the place.",
    "description": "All unemployed, Ki-taek's family...",
    "studios": ["Barunson E&A"],
    "scrapedAt": "2026-04-09T15:00:00Z"
}
```

`totalRatings` and `totalReviews` are the counts Letterboxd publishes in the film page's own structured data. `totalLists` and `totalMembers` come from a second page that Letterboxd does not always serve: when it refuses that page they are `null`, and the run status says so.

> **Availability of modes 2–4.** Letterboxd can refuse (HTTP 403) its review, profile and popular-list pages for requests coming from Apify proxies; in our tests of November 2026 it refused all three. When that happens the run returns 0 items, charges nothing and says so in the run status. `film_details` reads the public film page and is the mode to rely on.

#### Mode 2: Film Reviews (`film_reviews`)

Extract reviews for any film with sorting and pagination.

**Input example:**

```json
{
    "mode": "film_reviews",
    "urls": ["https://letterboxd.com/film/parasite-2019/"],
    "maxResults": 100,
    "sortBy": "popular"
}
```

**Output per review:**

```json
{
    "filmTitle": "Parasite",
    "filmUrl": "https://letterboxd.com/film/parasite-2019/",
    "reviewerUsername": "john_doe",
    "reviewerDisplayName": "John",
    "reviewerUrl": "https://letterboxd.com/john_doe/",
    "rating": 4.5,
    "reviewText": "A masterclass in social commentary...",
    "reviewDate": "2026-03-15",
    "reviewUrl": "https://letterboxd.com/john_doe/film/parasite-2019/",
    "likes": 42,
    "isContainsSpoilers": false,
    "scrapedAt": "2026-04-09T15:00:00Z"
}
```

**Sort options:** `popular` (default), `recent`, `earliest`, `highest`, `lowest`

#### Mode 3: User Profile (`user_profile`)

Extract public profile information including stats, favorites, and recent activity.

**Input example:**

```json
{
    "mode": "user_profile",
    "urls": ["dave", "https://letterboxd.com/sally/"]
}
```

**Output per user:**

```json
{
    "username": "dave",
    "displayName": "Dave",
    "profileUrl": "https://letterboxd.com/dave/",
    "avatarUrl": "https://...",
    "bio": "Film lover from NYC",
    "location": "New York",
    "filmsWatched": 1250,
    "filmsThisYear": 87,
    "listsCount": 15,
    "followingCount": 200,
    "followersCount": 150,
    "favoriteFilms": [
        {"title": "Parasite", "url": "https://letterboxd.com/film/parasite-2019/"}
    ],
    "recentRatings": [
        {"title": "Dune: Part Two", "rating": 4.0, "url": "https://letterboxd.com/film/dune-part-two/"}
    ],
    "scrapedAt": "2026-04-09T15:00:00Z"
}
```

#### Mode 4: Popular Films (`popular_films`)

Scrape trending and popular films with optional genre filtering.

**Input example:**

```json
{
    "mode": "popular_films",
    "category": "this-week",
    "genre": "horror",
    "maxResults": 100
}
```

**Output per film:**

```json
{
    "title": "Nosferatu",
    "year": 2024,
    "url": "https://letterboxd.com/film/nosferatu-2024/",
    "posterUrl": "https://...",
    "averageRating": 3.8,
    "director": null,
    "scrapedAt": "2026-04-09T15:00:00Z"
}
```

**Categories:** `popular`, `this-week`, `this-month`, `this-year`

### URL Flexibility

You don't need to provide full URLs. The scraper accepts:

| Input | Interpreted as |
|---|---|
| `https://letterboxd.com/film/parasite-2019/` | Film URL (used directly) |
| `letterboxd.com/film/parasite-2019` | Film URL (https:// added) |
| `parasite-2019` | Film slug (full URL constructed) |
| `https://letterboxd.com/dave/` | User profile URL |
| `dave` | Username (full URL constructed) |

### Letterboxd API alternative

There is no official public Letterboxd API available to developers. This scraper is a **Letterboxd API alternative** — it gives you structured access to film details, reviews, user profiles, and trending data without needing API keys or authentication. It returns clean JSON data that you can integrate into any application, database, or workflow.

### Use Cases

- **Film industry research** — Analyze ratings and review trends across thousands of films
- **Content creator analytics** — Track film popularity and audience reception over time
- **Academic research** — Study film criticism patterns, audience behavior, and cultural trends
- **Recommendation engines** — Build datasets for ML-based movie recommendation systems
- **Entertainment journalism** — Monitor trending films and critical reception in real time

### Use with Python, JavaScript, or no code

You can call this scraper programmatically using the Apify API client.

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("zhorex/letterboxd-scraper").call(run_input={
    "mode": "film_details",
    "urls": ["parasite-2019", "everything-everywhere-all-at-once"]
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

#### JavaScript

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('zhorex/letterboxd-scraper').call({
    mode: 'film_details',
    urls: ['parasite-2019', 'everything-everywhere-all-at-once'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Or skip coding entirely and use the [web interface](https://apify.com/zhorex/letterboxd-scraper) with no-code tools like Zapier, Make, or n8n.

### Pricing

**$0.003 per result**.

| Mode | Charged per |
|---|---|
| `film_details` | Film scraped |
| `film_reviews` | Review scraped |
| `user_profile` | Profile scraped |
| `popular_films` | Film listed |

### Technical Details

- **Residential proxy by default** — the Actor runs on Apify residential proxy; leave the default on
- **Lightweight** — HTTP-only requests, no headless browser; runs on 512 MB by default
- **Respectful** — Built-in 1.5s delay between requests
- **Resilient** — Automatic retry with exponential backoff on rate limits (429)
- **Fast** — Processes ~40 items/minute with built-in delays

### FAQ

**Does this need a proxy?**
Yes. The Actor runs on Apify residential proxy by default; leave the default on. The built-in request delays keep the request rate low.

**Can it scrape private profiles?**
No. Only data shown on the public profile page is returned.

**What's the rate limit?**
The scraper has a built-in 1.5-second delay between requests to be respectful to Letterboxd's servers. If rate-limited (HTTP 429), it backs off exponentially.

**Can I get full watch history?**
Only what's publicly visible on the user's profile page. The scraper does not authenticate or access private data.

**What if a film page has changed its layout?**
The scraper uses multiple fallback CSS selectors. If a field can't be parsed, it returns `null` instead of crashing.

**How much does it cost to scrape Letterboxd?**
$0.003 per result ($3 per 1,000 results). Apify's free plan includes $5/month in credits, which is enough for roughly 1,600 results. No subscription required — you only pay for what you use.

**Can I use this Letterboxd scraper in Python?**
Yes. Install the Apify Python client (`pip install apify-client`) and call the Actor with a few lines of code. See the Python example above.

**Is scraping Letterboxd legal?**
This scraper only accesses publicly available data and does not bypass authentication or access private profiles. Always review Letterboxd's Terms of Service and applicable laws in your jurisdiction before scraping.

**What does this Letterboxd scraper cover?**
This Actor (`zhorex/letterboxd-scraper`) covers film details, reviews, user profiles, and trending films with 4 dedicated modes.

**Can I export Letterboxd data to CSV or Excel?**
Yes. After each run, you can download your results in JSON, CSV, or Excel format directly from the Apify dashboard. You can also push data to Google Sheets, a webhook, or any API endpoint.

### Integrations & data export

This Actor integrates with the full Apify ecosystem:

- **Google Sheets** — Automatically send scraped film data to a spreadsheet
- **Zapier / Make / n8n** — Connect Letterboxd data to 5,000+ apps with no-code automation
- **REST API** — Start runs, fetch results, and manage datasets programmatically
- **Webhooks** — Get notified when a scrape finishes and push data to your backend
- **Amazon S3 / Google Cloud Storage** — Export datasets directly to cloud storage
- **Slack / Email** — Receive notifications with results after each run

### Other Scrapers by Zhorex

**Social & Entertainment**

- [Telegram Channel Scraper](https://apify.com/zhorex/telegram-channel-scraper) — Scrape messages, media, and metadata from public Telegram channels
- [RedNote Xiaohongshu Scraper All-in-One](https://apify.com/zhorex/rednote-xiaohongshu-scraper) — Scrape posts, comments, and profiles from Xiaohongshu

**Business & Reviews**

- [G2 Reviews Scraper](https://apify.com/zhorex/g2-reviews-scraper) — Extract software reviews and ratings from G2.com

**SEO & Data Tools**

- [Domain Authority Checker](https://apify.com/zhorex/domain-authority-checker) — Bulk check domain authority for SEO analysis
- [Phone Number Validator](https://apify.com/zhorex/phone-number-validator) — Validate and format international phone numbers

### Legal

This actor only accesses publicly available data on letterboxd.com. It does not log in or access private profiles. Use responsibly and in compliance with Letterboxd's Terms of Service.

**Personal data.** Some fields describe people (reviewer usernames, display names, profile links and review text in `film_reviews`; username, display name, avatar, bio, location, follower/following counts and recent ratings in `user_profile`). Under Apify's [Standard Actor Contract](https://docs.apify.com/legal/standard-actor-contract) you, as the person running the Actor, decide what is collected and are the controller of that data: you need a lawful basis (e.g. GDPR) and must respect Letterboxd's terms. Collect only what you need and delete what you no longer need. Do not use the output to harass, stalk or build profiles of private individuals.

Not affiliated with, endorsed by or sponsored by Letterboxd. Names are used only to describe the data source.

***

### Your Review Matters

If you have used this Actor, **a 30-second rating helps, good or bad:**

1. Go to the [Letterboxd Scraper page](https://apify.com/zhorex/letterboxd-scraper)
2. Scroll down and click the star rating
3. Optionally leave a one-line comment about your use case

**Why it matters:** Ratings help other users judge whether this Actor fits their use case.

Found a bug? [Open an issue](https://apify.com/zhorex/letterboxd-scraper/issues) and it will be looked at.

# Actor input Schema

## `mode` (type: `string`):

What to scrape from Letterboxd

## `urls` (type: `array`):

Film URLs for film_details/film_reviews, or username/profile URLs for user_profile. Not needed for popular_films.

## `maxResults` (type: `integer`):

Maximum reviews per film (film_reviews mode) or max films (popular_films mode)

## `category` (type: `string`):

Which popular films category to scrape

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

Filter by genre slug: action, comedy, drama, horror, thriller, sci-fi, animation, romance, documentary, mystery, fantasy, adventure, crime, family, history, music, war, western

## `sortBy` (type: `string`):

How to sort reviews (film_reviews mode only)

## `proxyConfiguration` (type: `object`):

Proxy for Letterboxd requests. RESIDENTIAL Apify Proxy is preselected; leave the default on. Without it, Letterboxd may be unavailable from Apify's IPs and the run can return 0 items.

## Actor input object example

```json
{
  "mode": "film_details",
  "urls": [
    "https://letterboxd.com/film/parasite-2019/"
  ],
  "maxResults": 50,
  "category": "popular",
  "sortBy": "popular",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "urls": [
        "https://letterboxd.com/film/parasite-2019/"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("zhorex/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 = {
    "urls": ["https://letterboxd.com/film/parasite-2019/"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("zhorex/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 '{
  "urls": [
    "https://letterboxd.com/film/parasite-2019/"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call zhorex/letterboxd-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zhorex/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/gm2Brm9z51bNE2iLE/builds/TdVYge4b3tjpo0jps/openapi.json
