Letterboxd Scraper - Films, Ratings & Reviews avatar

Letterboxd Scraper - Films, Ratings & Reviews

Pricing

from $1.20 / 1,000 film records

Go to Apify Store
Letterboxd Scraper - Films, Ratings & Reviews

Letterboxd Scraper - Films, Ratings & Reviews

Scrape Letterboxd films and reviews by search phrase, popular or genre lists, or film URL. Extract ratings, directors, runtimes, review text and star ratings. Includes incremental monitoring, resume support and MCP connectors.

Pricing

from $1.20 / 1,000 film records

Rating

5.0

(1)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

2

Bookmarked

2

Total users

1

Monthly active users

11 days ago

Last modified

Categories

Share

Letterboxd Films, Lists, Diaries & Reviews Scraper

Letterboxd Scraper turns Letterboxd into structured data you can reuse anywhere. Search by title phrase, or paste any letterboxd.com link - film pages, a member's list (the films come attached to the list row), their lists index, their diary (one row per entry), or their profile (stats and favourite films). Every film row carries ratings, directors, genre, runtime and tagline, with reader reviews available as an optional per-film add-on. Export to JSON, CSV, or Excel, or pull results straight into your app through the API.

Why This Scraper?

  • Two clear modes: search by film title phrase, or paste ANY Letterboxd link shape - film pages, member lists, diaries, profiles, browse lists.
  • Member lists with their films. Paste a list link and get one list row (title, owner, film count, description) with every film nested in order: rank, title, year and the owner's rating.
  • Diaries and profiles. A diary link yields one row per entry (film, watched date, star rating, rewatch flag, review link); a profile link yields the member's stats and favourite films.
  • Real film metadata in every row: title, release year, directors, genre, average rating, ratings count, runtime, and tagline - plus optional reader reviews (author, star rating, date, text, likes, spoiler flag).
  • Reviews-only output: turn on Output reviews only and the dataset becomes one row per reader review (film, author, rating, date, text, likes, spoiler flag), billed as ordinary result rows with no enrichment charge. Enrichment is set up automatically - review fetching turns on and the film detail page is never read, so the mode works even when detail pages are refused.
  • Output caps in both modes and separate dataset views per kind: Films, Lists, List films (one row per film), Diary, Profiles and Reviews.
  • Resume and recurring updates: continue one interrupted run with Resume, or turn on Incremental mode to get only new, updated, and reappeared films on a schedule; MCP connector export sends a concise summary into Notion, Linear, Airtable, or Apify while the complete record always stays in the dataset.

Use Cases

  • Film bloggers and critics: pull ratings, taglines, and directors to enrich reviews and roundup posts.
  • Data journalists and researchers: build historical rating datasets across genres, decades, or directors.
  • Watch-list and recommendation tools: track new releases and rating changes with Incremental mode.
  • Audience and sentiment teams: read reader review text and star ratings for a title or a set of titles.
  • Catalogers and archivists: collect structured metadata for a curated list of titles from pasted URLs.

Data You Get

Sample shape: values are illustrative placeholders, not from a live listing.

FieldExample
urlhttps://letterboxd.com/film/sample-film-title/
slugsample-film-title
titleSample Film Title
imagehttps://a.ltrbxd.com/resized/sample-poster.jpg
descriptionA one-paragraph synopsis of the film.
genre["Drama", "Mystery"]
directors["Sample Director"]
averageRating3.8
averageRatingPrecise3.76
ratingsCount125000
datePublished2023-05-01
releaseYear2023
runtimeMinutes118
taglineA story worth telling.
scrapedAt2026-01-01T00:00:00Z
reviewsreader reviews array, present only when Fetch reader reviews is on
changeType"NEW", incremental mode only
changedFields["averageRating"], incremental mode only
firstSeenAt2026-01-01T00:00:00Z, incremental mode only
lastSeenAt2026-01-05T00:00:00Z, incremental mode only

Each entry inside reviews carries filmSlug, author, rating, reviewDate, text, likes, and containsSpoilers.

How to Use

  1. Pick a mode: search (film title phrases) or url (paste Letterboxd film and browse links).
  2. Fill in the fields for that mode, and turn on Fetch reader reviews if you also want per-film review text and star ratings.
  3. Set Max items to control run size and cost, then click Start.
  4. Download the dataset as JSON, CSV, or Excel, or read it through the API.

Search by title phrase:

{
"mode": "search",
"queries": ["dune"],
"maxItems": 20
}

Search multiple phrases with reviews enrichment:

{
"mode": "search",
"queries": ["dune", "oppenheimer"],
"fetchReviews": true,
"maxReviewsPerFilm": 25,
"maxItems": 25
}

Paste Letterboxd URLs (any shape):

{
"mode": "url",
"startUrls": [
{ "url": "https://letterboxd.com/daverick/list/my-top-4-films-of-2025/" },
{ "url": "https://letterboxd.com/karsten/films/diary/" },
{ "url": "https://letterboxd.com/karsten/" },
{ "url": "https://letterboxd.com/film/dune-part-two/" }
],
"maxItems": 30
}

Each URL is routed by its shape: a list link produces one list row with its films nested (and a one-row-per-film view in the dataset), a diary link produces one row per diary entry, a profile link produces the member's stats and favourites, and film and browse links keep working exactly as before. Watchlist pages are skipped with a warning - the site renders another member's watchlist grid client-side, beyond a plain fetch. Diary and profile pages sit behind the site's bot challenge and are fetched through the same cleared connection the browse mode uses; when that connection is refused, those entries are skipped with a warning while the rest of the run continues.

Recurring incremental run (same search every day):

{
"mode": "search",
"queries": ["dune"],
"incrementalMode": true
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/letterboxd-film-reviews-scraper").call(run_input={"mode": "search", "queries": ["dune"]})
for film in client.dataset(run["defaultDatasetId"]).iterate_items():
print(film["title"], film["averageRating"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/letterboxd-film-reviews-scraper').call({ mode: 'search', queries: ['dune'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets, or webhooks from the Integrations tab.

Output caps in both modes

maxItems is the primary cap and applies to search and URL mode alike, so a pasted list of browse links can still be limited to a fixed number of films. maxPages additionally bounds how many browse-list pages are read per source (search mode is capped by maxItems alone); leave it empty to walk every result page and let maxItems do the capping.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips films already collected there (matched by slug), so you do not pay twice.
  • Incremental mode (incrementalMode) is for scheduled runs over the same search or URLs. Each film is classified NEW, UPDATED (with changedFields), UNCHANGED (suppressed and not billed unless emitUnchanged is on), REAPPEARED, or EXPIRED (only after a run that scanned the whole scope end to end, and only with emitExpired). stateKey names or shares the stored state; leave it empty to isolate state automatically by mode, queries, URLs, and browse path. With Incremental mode off, output is exactly as before.

Send results into your apps (MCP connectors)

Optionally pipe the scraped films into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each film, not the full JSON. Notion gets a page-per-film export; other connectors receive a best-effort write or digest. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify > Settings > API & Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you have not authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where film pages should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Connector write errors do not fail the run. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch for title-phrase search, or url for pasted Letterboxd links.
queriesarray["dune"]Film title phrases for search mode.
startUrlsarraysample URLLetterboxd film pages, browse lists, or direct film slugs for URL mode.
browsePathstring/films/popular/Used only in URL mode when Start URLs is empty; a site path to browse.
maxItemsinteger20Maximum films to return across the whole run. Must be at least 1.
maxPagesinteger0 (unlimited)Maximum pages to read per browse-list source (not used by search mode). Leave at 0 to walk every result page; Max items is the primary output cap.
fetchReviewsbooleanfalseFetch each film's reader reviews and attach them as a nested list, also exposed one-per-row in the Reviews output tab. Billed on the Reviews enrichment (detail-enrichment) event: one unit per 10 delivered reviews, plus the per-film detail unit when the film page is read. Cap and off-switch via Max reviews per film.
fetchDetailsbooleantrueSearch mode only. ON: each matched film's detail page is read for the full record (directors, genre, tagline, description) - charged the detail-enrichment event per film. OFF: film rows come from the search results alone (title, year, runtime, average rating, poster) with no detail charge. URL mode always reads the film page you paste, so the detail charge is inherent there.
reviewsOnlybooleanfalseReturn ONLY review rows (film, author, rating, date, text, likes, spoiler flag) - film/list/diary/profile rows are not returned, and reviews are billed as ordinary result rows with no enrichment charge.
maxReviewsPerFilminteger25Only used when Fetch reader reviews is on. Maximum reviews to collect per film.
resumeFromRunIdstring(none)Previous run ID or dataset ID from this actor. Films already collected there (matched by slug) are skipped, so the run returns only new ones.
incrementalModebooleanfalseDaily or recurring monitoring of the same search or URLs. The first run returns everything as NEW; later runs return only NEW, UPDATED, and REAPPEARED by default.
stateKeystring(none)Optional name for a monitoring campaign, so its incremental state stays stable or is deliberately shared. Auto-derived from mode, queries, URLs, and browse path when left empty.
emitUnchangedbooleanfalseIncremental mode only. Also return films unchanged since the last run, marked UNCHANGED. Adds and bills extra rows you already have.
emitExpiredbooleanfalseIncremental mode only. Also return films from a previous run no longer found, marked EXPIRED, once a run has fully scanned the search. Adds and bills extra synthetic rows.
ignoreFieldsForChangesarray(none)With Incremental mode on, dataset fields listed here never count as a change (they stay in the output, they just don't flip a row to UPDATED).
proxyobjectApify ProxyConnection settings. The default is recommended for Letterboxd.
mcpConnectorsarray(none)Optional connector IDs for sending a concise summary into your apps.
notionParentPageUrlstring(none)Notion connector only: page under which film pages are created.
maxNotifyListingsinteger50Cap on how many films are written to each selected connector per run. Does not affect the dataset.

Output Example

Sample shape: values are illustrative placeholders, not from a live listing.

{
"url": "https://letterboxd.com/film/sample-film-title/",
"slug": "sample-film-title",
"title": "Sample Film Title",
"image": "https://a.ltrbxd.com/resized/sample-poster.jpg",
"description": "A one-paragraph synopsis of the film.",
"genre": ["Drama", "Mystery"],
"directors": ["Sample Director"],
"averageRating": 3.8,
"averageRatingPrecise": 3.76,
"ratingsCount": 125000,
"datePublished": "2023-05-01",
"releaseYear": 2023,
"runtimeMinutes": 118,
"tagline": "A story worth telling.",
"reviews": [
{
"filmSlug": "sample-film-title",
"author": "sample_reviewer",
"rating": 3.5,
"reviewDate": "2026-01-03",
"text": "A short, generic reaction to the film.",
"likes": 2,
"containsSpoilers": false
}
],
"scrapedAt": "2026-01-01T00:00:00Z"
}

reviews is only present when Fetch reader reviews is on. With Output reviews only on, the dataset contains one row per review instead - slug, film title, year, author, rating, date, text, likes and spoiler flag per row (see the Reviews output tab).

Plan Requirement

For best reliability, keep the default Apify proxy setting. Max items is a maximum cap, not a guaranteed count; a run can save fewer rows when the selected search phrase, URL, or browse path matches fewer films.

FAQ

How much does it cost?

Charges by mode (the Pricing tab has the current rates):

ModeDataset rowsEnrichment charges
Reviews only (reviewsOnly)one row per reviewnone - reviews bill as ordinary result rows
Search + Include reviewsfilm rows from the search resultsReviews enrichment event: 1 unit per started block of 10 delivered reviews (1-10 = 1, 11-20 = 2, ...)
Search + Include reviews + Fetch film detail pagesfull film rows (directors, genre, tagline, description)Reviews enrichment per-10 + the per-film detail unit
URL modefilm rows (the pasted link IS the detail page)the per-film detail unit + Reviews enrichment per-10 when Include reviews is on

A run with Fetch reader reviews off in plain search mode (Fetch film detail pages off too) bills only result rows and the actor start. Suppressed rows (incremental UNCHANGED) are never charged.

You pay per film returned, with optional reader reviews billed only when you turn on Fetch reader reviews. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.

This actor collects only publicly available film and review data. You are responsible for how you use it: follow Letterboxd's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution, especially of reader-written review text.

What is the difference between Resume and Incremental mode?

Resume (resumeFromRunId) continues one specific interrupted run from a pasted run or dataset ID. Incremental mode is for a schedule, for example daily or weekly: the actor remembers the previous run of the same search or URLs by itself and returns only new, updated, and reappeared films. Use one or the other; a state key that already has saved incremental state cannot also be combined with Resume.

Can I get only new or changed films on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated, and reappeared films by default, and unchanged ones are not billed unless you turn that on too.

Why did my run fail instead of returning an empty dataset?

If every page the run tried was refused, the run stops with a clear message so "no matching films" is never confused with "nothing could be read." Run it again in a few minutes. If only some pages could not be read, you still get what was found.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear, or Airtable.

🔗 More scrapers you might like

Pair this actor with these related scrapers from the same team:

🧩 WEBTOON Scraper
Scrape the WEBTOON catalog into structured data. Extract series, genres, rankings and...
🧩 OK.ru Scraper
Scrape public OK.ru users, groups, topics, posts, videos, games and greetings by keyword...
🧩 MyAnimeList Scraper
Scrape MyAnimeList anime and manga by keyword, ranking chart or URL. Extract titles...
🧩 Roblox Scraper
Scrape Roblox experiences, marketplace items, users and communities. Player counts...
🧩 Allegro Scraper
Scrape Allegro by keyword or URL. Extract offers, prices, delivery, seller details, and...
📱 Truth Social Scraper
Scrape public Truth Social profiles, posts, media, metrics, author data, and complete...

👉 Browse all abotapi scrapers

💬 Support

  • 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • ⭐ Enjoying it? A quick review on the actor page helps other users find it.