# IMDb Scraper — Movies, TV, Ratings & Reviews (`tortuga/imdb-scraper`) Actor

Scrape IMDb titles and user reviews: rating, votes, genres, cast, box office, awards, plus thousands of reviews per title with rating, text, date and helpful votes. Charts and search too.

- **URL**: https://apify.com/tortuga/imdb-scraper.md
- **Developed by:** [Trevor Ortega](https://apify.com/tortuga) (community)
- **Categories:** Videos
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 titles

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## IMDb Scraper

Scrape IMDb titles and user reviews: rating, votes, genres, cast, release date, runtime, plot, box office, plus user reviews with rating, text, date and helpful votes. Works with title URLs, IDs, charts and search.

IMDb Scraper reads the same data the imdb.com website loads for its own pages, so you get clean JSON instead of scraped HTML. For movies and TV shows you get the rating and vote count, Metascore, genres, release date, runtime, certificate, plot, directors, writers and the top-billed cast with their characters, countries, languages, production companies, budget, worldwide, domestic and opening-weekend gross, awards ("Won 4 Oscars. 160 wins & 400 nominations total"), the IMDb popularity rank (MOVIEmeter / TVmeter) and Top 250 rank, poster, trailer, keywords, filming locations, and episode and season counts for series. For user reviews you get the star rating (1-10), headline, full text, date, helpful and not-helpful votes and the spoiler flag. You can sort reviews (most helpful, newest, oldest, most votes, highest or lowest rating), filter by star rating and skip spoilers. **The whole review list is reachable**: 50 reviews per request, all the way to the last review (12,000+ for The Shawshank Redemption). IMDb charts (Top 250 movies and TV, Most Popular, Lowest Rated, Top Indian / English movies) and advanced searches (by genre, type, year, rating, votes, country, language, keyword) give ranked rows. You don't need an IMDb account. Download the results as JSON, CSV or Excel, or use the API from Python, Node, n8n, Make or Google Sheets. You pay only for the items you get.

### What data does IMDb Scraper extract?

Every item has a `type` field: `title`, `review` or `list_entry`.

#### Title items (`type: "title"`, mode `titles`)

| Field | Description |
|---|---|
| `id`, `url` | IMDb title ID (`tt0111161`) and URL |
| `title`, `originalTitle` | Title as shown on IMDb (US English) and the original-language title |
| `titleType`, `titleTypeId`, `isSeries` | `Movie`, `TV Series`, `TV Mini Series`, `Short`, ... and whether it has episodes |
| `year`, `endYear` | Release year; last year for finished series |
| `releaseDate`, `releaseCountry` | First release date (`YYYY-MM-DD`, or `YYYY-MM` / `YYYY` when IMDb only knows part of it) and its country |
| `runtimeMinutes` | Runtime in minutes |
| `genres` | e.g. `["Crime", "Drama"]` |
| `rating`, `voteCount` | IMDb user rating (1-10) and number of votes |
| `metascore`, `criticReviewsCount` | Metacritic score and the number of critic reviews behind it |
| `userReviewsCount` | Number of IMDb user reviews |
| `plot` | Short plot summary |
| `certificate` | Rating certificate, e.g. `R`, `PG-13`, `TV-MA` |
| `directors`, `writers` | `[{id, name, url}]` |
| `cast`, `castTotal` | Top 15 billed actors `[{id, name, characters, url}]` and the full cast size |
| `countries`, `languages`, `companies` | Countries of origin, spoken languages, production companies |
| `budget`, `budgetCurrency` | Production budget when IMDb lists one |
| `grossWorldwide`, `grossDomestic`, `openingWeekendGross` (+ `...Currency`, `openingWeekendEndDate`) | Box office (domestic = US & Canada) |
| `popularityRank`, `topRank` | IMDb popularity rank (MOVIEmeter / TVmeter) and position in the Top 250 (or `null`) |
| `awardsSummary`, `awardWins`, `awardNominations` | Summary as on the title page, total wins and total nominations (wins included) |
| `posterUrl`, `trailerUrl` | Full-size poster and latest trailer |
| `keywords`, `keywordsTotal` | Top 20 plot keywords and how many IMDb has |
| `filmingLocations` | Up to 5 filming locations |
| `episodesCount`, `seasonsCount` | For series; `null` for movies |
| `isAdult`, `source`, `scrapedAt` | Adult flag, data source (`api`, or `page` / `page_jsonld` on the proxy fallback), ISO timestamp |

#### Review items (`type: "review"`, mode `reviews`)

| Field | Description |
|---|---|
| `titleId`, `titleName` | The movie or show the review belongs to |
| `reviewId`, `url` | IMDb review ID (`rw6606154`) and its public URL |
| `rating` | Integer 1-10, or `null` when the reviewer gave no star rating |
| `title` | Review headline |
| `text` | Full review text (plain text, paragraphs kept) |
| `submittedAt` | Date the review was posted (`YYYY-MM-DD`) |
| `helpfulUpVotes`, `helpfulDownVotes` | "Helpful" / "Not helpful" votes |
| `isSpoiler` | `true` when the review is flagged as containing spoilers |
| `scrapedAt` | ISO timestamp |

Reviewer usernames, profile links and avatars are **not** collected.

#### Chart and search rows (`type: "list_entry"`, modes `chart` and `search`)

`listName`, `rank`, `id`, `title`, `originalTitle`, `titleType`, `year`, `endYear`, `rating`, `voteCount`, `metascore`, `runtimeMinutes`, `certificate`, `genres`, `plot`, `posterUrl`, `url`, `sourceUrl`, `scrapedAt`.

### How to use IMDb Scraper

1. Pick a **Mode**: `reviews` (default), `titles`, `chart` or `search`.
2. Add titles in any combination: **Start URLs** (title, reviews, chart, advanced-search or `/find/?q=` URLs), **Title IDs** (`tt0111161`) or **Search terms** (`Dune 2021`). In `titles` and `reviews` mode a chart or search URL expands to the titles on it (up to **Max titles per chart / search URL**).
3. Set **Max items** (and **Max reviews per title** in `reviews` mode) to cap the run and the cost.
4. For reviews, optionally choose the **Review order**, a **star rating** to keep, and whether to **include spoilers**.
5. Click **Start**. Results appear in the **Dataset** tab; export them from there or use the API.

### Input example

```json
{
  "mode": "reviews",
  "titleIds": ["tt0111161"],
  "searchTerms": ["Dune 2021"],
  "startUrls": [{ "url": "https://www.imdb.com/title/tt0903747/reviews/?sort=submission_date&dir=desc" }],
  "maxItems": 3000,
  "maxReviewsPerTitle": 1000,
  "reviewSort": "newest",
  "includeSpoilers": true
}
```

```json
{ "mode": "titles", "startUrls": [{ "url": "https://www.imdb.com/chart/top/" }], "maxTitlesPerList": 250, "maxItems": 250 }
```

```json
{ "mode": "search", "startUrls": [{ "url": "https://www.imdb.com/search/title/?genres=horror&title_type=feature&release_date=2020-01-01,2024-12-31&num_votes=50000,&sort=user_rating,desc" }], "maxItems": 200 }
```

### Output example

```json
{
  "type": "title",
  "id": "tt0111161",
  "url": "https://www.imdb.com/title/tt0111161/",
  "title": "The Shawshank Redemption",
  "titleType": "Movie",
  "year": 1994,
  "releaseDate": "1994-10-14",
  "runtimeMinutes": 142,
  "genres": ["Drama"],
  "rating": 9.3,
  "voteCount": 3248119,
  "metascore": 82,
  "plot": "After a banker is sentenced to life in Shawshank Prison, he forms an unlikely friendship with a seasoned inmate and clings to hope amid cruelty and corruption.",
  "certificate": "R",
  "directors": [{ "id": "nm0001104", "name": "Frank Darabont", "url": "https://www.imdb.com/name/nm0001104/" }],
  "writers": [{ "id": "nm0000175", "name": "Stephen King", "url": "https://www.imdb.com/name/nm0000175/" }, { "id": "nm0001104", "name": "Frank Darabont", "url": "https://www.imdb.com/name/nm0001104/" }],
  "cast": [{ "id": "nm0000209", "name": "Tim Robbins", "characters": ["Andy Dufresne"], "url": "https://www.imdb.com/name/nm0000209/" }],
  "countries": ["United States"],
  "languages": ["English"],
  "companies": ["Castle Rock Entertainment"],
  "budget": 25000000,
  "budgetCurrency": "USD",
  "grossWorldwide": 29425588,
  "popularityRank": 40,
  "topRank": 1,
  "awardsSummary": "Nominated for 7 Oscars. 21 wins & 43 nominations total",
  "posterUrl": "https://m.media-amazon.com/images/M/MV5BMDAyY2FhYjctNDc5OS00MDNlLThiMGUtY2UxYWVkNGY2ZjljXkEyXkFqcGc@._V1_.jpg",
  "trailerUrl": "https://www.imdb.com/video/vi3877612057/",
  "keywords": ["prison", "based on the works of stephen king", "escape from prison", "friendship between men", "wrongful conviction"],
  "episodesCount": null,
  "seasonsCount": null,
  "scrapedAt": "2026-10-05T17:12:00Z"
}
```

```json
{
  "type": "review",
  "titleId": "tt0111161",
  "titleName": "The Shawshank Redemption",
  "reviewId": "rw6606154",
  "url": "https://www.imdb.com/review/rw6606154/",
  "rating": 10,
  "title": "An incredible movie. One that lives with you.",
  "text": "It is no wonder that the film has such a high rating, it is quite literally breathtaking. ...",
  "submittedAt": "2021-02-17",
  "helpfulUpVotes": 659,
  "helpfulDownVotes": 52,
  "isSpoiler": false,
  "scrapedAt": "2026-10-05T17:12:00Z"
}
```

### How to scrape all IMDb reviews of a movie or TV show

Set **Mode** to `reviews`, add the title (URL, `tt` ID or name) and set **Max reviews per title** as high as you need. Reviews are read 50 per request with IMDb's own pagination cursor, so the actor goes through the whole list, not just the first page you see on the site: in testing it walked all 12,026 reviews of The Shawshank Redemption that IMDb serves (IMDb's header says 12,053; the rest are hidden by IMDb) in 242 requests, about 4 minutes. Use **Review order** `newest` to follow a title over time, `rating_low` to find complaints, or **Only reviews with this rating** to get, say, every 1-star review. A reviews URL copied from imdb.com keeps its sort, rating filter and spoiler setting.

### How to scrape the IMDb Top 250

Use `chart` mode with `https://www.imdb.com/chart/top/` (or leave Start URLs empty: the Top 250 is the default). All 250 rows come back in one request with rank, year, rating, votes, Metascore, runtime, certificate and genres. Other charts: `/chart/toptv/`, `/chart/moviemeter/`, `/chart/tvmeter/`, `/chart/bottom/`, `/chart/top-english-movies/` and `/india/top-rated-indian-movies/` (plus Malayalam, Tamil and Telugu). For full details of every movie on a chart, use `titles` mode with the same URL and **Max titles per chart / search URL** = 250.

### Can I use IMDb advanced search filters?

Yes. Build a search on imdb.com/search/title, copy the URL and paste it into **Start URLs** in `search` mode (ranked rows) or in `titles` / `reviews` mode (details or reviews of each result). Supported filters: title text, title type, genres, release date or year range, user rating range, number of votes, country of origin, primary language and keywords, with any of IMDb's sort orders (popularity, rating, number of votes, release date, A-Z, year, runtime, US box office, Metascore). Filters the actor does not support are listed in the log and ignored. Results are paginated 50 at a time with no fixed limit.

### Monitor changes on a schedule

Turn on **Only new or changed items** and save the input as a task with a Schedule (Apify Console: **Saved tasks** -> **Schedule**, for example daily). Each run remembers what earlier runs of the same input returned and outputs only what is new: reviews not seen before in `reviews` mode (read newest first; paging stops where the previous run's reviews begin, usually after one API call per title), titles whose IMDb rating or Metascore changed in `titles` mode, and titles that entered a chart or search result or changed rating in `chart` and `search` mode. Unchanged items are skipped before they are saved, so they are not charged. Add **Only reviews newer than** (`2 days` or a date like `2026-10-01`) to bound how far back the first run reads; IMDb dates reviews by day, so the cutoff day itself is included. Monitored items carry `changeType` (`new` or `changed`) and, for changed titles, `previousValues` with the old values (e.g. `{"rating": 8.7}`); use **Monitoring key** to keep several schedules on the same input apart.

### Does it work without an IMDb account or a proxy?

Yes. Everything comes from data IMDb shows to anonymous visitors. The actor reads IMDb's own data API (the one the website calls), which does not need a proxy. Signed-in features (watchlists, your own ratings, IMDbPro data) are never accessed.

### Proxy note

imdb.com pages sit behind an AWS WAF "verify you are human" challenge, but the data API this actor uses is not, so **a normal run makes no proxy requests at all**. If IMDb ever refuses the direct API requests, the actor retries them through the proxy in the input and, if that fails too, falls back to reading imdb.com pages through the proxy. Only Apify's **Unblocker** proxy (group `UNBLOCKER`, the default) passes the WAF challenge. Unblocker is billed to your Apify account per successful request: 10 Unblocker units, about **$0.0015 on the free plan** and less on paid plans; requests the proxy cannot complete are free. The page fallback is thinner: a title page gives the main fields (rating, votes, genres, date, runtime, plot, director, cast, keywords) but not budget, gross, awards or ranks, and a reviews page carries only 5 reviews. The run's `SUMMARY` record (key-value store) reports `dataRoute` (`direct`, `proxy` or `pages`) and `successfulRequests` (billed proxy requests), so every run's proxy cost is visible.

### How much does it cost?

Pay per item: `title` $0.01, `review` $0.003, chart / search row $0.002. No start fee and no subscription; Apify's free plan is enough to try it. Platform usage is small (the API answers in about a second).

Worked example: **1,000 reviews of one movie** = 20 API requests (50 reviews each) = **$3.00** in review events and $0.00 in proxy. In the fallback case where IMDb refused direct requests and the Unblocker had to carry them, the same 20 requests would add about 20 x $0.0015 = $0.03. **The Top 250 with full title details** = 1 chart request + 250 title requests = 250 x $0.003 = **$0.75** (plus at most about $0.38 of Unblocker on the fallback).

### Integrations and API

Use the run in Zapier, Make, n8n, Google Sheets, or call it from Python / Node with the Apify client. See the **API** tab for ready-made snippets.

### Is it legal to scrape IMDb?

This Actor collects only publicly visible data: title metadata, aggregate ratings, public credits (cast and crew names as listed on IMDb), charts, and the text of public user reviews. It does not collect reviewer usernames, profile links, avatars, emails or anything behind a login. IMDb's Conditions of Use restrict automated collection and commercial use of IMDb data, so check that your use case is allowed (IMDb licenses its data for commercial use separately). You are responsible for how you use the data and for complying with IMDb's terms and applicable law.

### Support

Found a bug or need a field added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

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

What to scrape. `reviews`: user reviews (`review` items) of every title. `titles`: one `title` item per movie / show with rating, votes, cast, box office, awards and more. `chart`: ranked rows (`list_entry`) of IMDb charts such as the Top 250. `search`: ranked rows (`list_entry`) for search terms or advanced-search URLs. In `titles` and `reviews` mode, chart and search URLs expand to the titles on them.

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

IMDb URLs, one per line: title pages (`https://www.imdb.com/title/tt0111161/`), reviews pages (`/title/tt0111161/reviews/?sort=submission_date&dir=desc`, the sort and rating filter in the URL are kept), charts (`/chart/top/`, `/chart/toptv/`, `/chart/moviemeter/`, `/chart/tvmeter/`, `/chart/bottom/`, `/chart/top-english-movies/`, `/india/top-rated-indian-movies/`), advanced searches (`/search/title/?genres=comedy&user_rating=7,&sort=num_votes,desc`) or `/find/?q=...` searches.

## `titleIds` (type: `array`):

IMDb title IDs, one per line, e.g. `tt0111161` (The Shawshank Redemption) or `tt0903747` (Breaking Bad).

## `searchTerms` (type: `array`):

Movie or show names, one per line (add the year to disambiguate, e.g. `Dune 2021`). In `titles` / `reviews` mode each term resolves to its best-matching title; in `search` mode every match is returned as a ranked row.

## `maxItems` (type: `integer`):

Overall cap on dataset items for the run (titles, reviews and list rows combined). Keeps cost predictable.

## `maxReviewsPerTitle` (type: `integer`):

Cap on reviews collected for each title in `reviews` mode. The full review list is reachable (50 reviews per request), so large values work: The Shawshank Redemption has 12,000+ reviews.

## `maxTitlesPerList` (type: `integer`):

In `titles` and `reviews` mode, how many titles to take from each chart or search start URL before fetching their details or reviews.

## `reviewSort` (type: `string`):

Order in which reviews are collected (matters when a cap is set). `helpfulness` is IMDb's default order; `newest` is best for monitoring.

## `ratingFilter` (type: `integer`):

Keep only reviews whose star rating is exactly this value (1-10), using IMDb's own filter. Leave empty for all reviews, including those without a rating.

## `includeSpoilers` (type: `boolean`):

Reviews flagged as spoilers are included and marked with `isSpoiler: true`. Turn off to skip them (IMDb's own spoiler filter).

## `reviewsNewerThan` (type: `string`):

Only reviews newer than: a date (YYYY-MM-DD) or a period such as '7 days' or '2 weeks'. Reviews are then read newest first and paging stops at the first page that reaches older reviews, so a daily run makes one call per title. IMDb dates reviews by day, so reviews from the cutoff day itself are included. Leave empty for no date limit. `reviews` mode only.

## `onlyNewOrChanged` (type: `boolean`):

Remember what earlier runs of this input returned and output only new items: in `reviews` mode only reviews not output before (read newest first; paging stops where the previous run's reviews begin); in `titles` mode titles whose IMDb rating or Metascore changed; in `chart` and `search` mode titles that are new in the list or whose rating changed (rank and vote counts move daily and are not watched). Use with a Schedule; unchanged items are not charged.

## `monitoringKey` (type: `string`):

Name for this watch, so several schedules on the same search stay separate; defaults to a key derived from the search input. Only used with **Only new or changed items**.

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

Normally not used: the Actor reads IMDb's own data API directly, which needs no proxy and costs nothing extra. Only if IMDb refuses those requests does it fall back to this proxy; imdb.com pages sit behind an AWS WAF challenge that only Apify's Unblocker proxy (group UNBLOCKER) passes. Unblocker is billed to your Apify account per successful request: 10 Unblocker units, about $0.0015 or less. On the fallback one request = one title, 50 reviews, one chart or 50 search rows.

## Actor input object example

```json
{
  "mode": "reviews",
  "startUrls": [
    {
      "url": "https://www.imdb.com/title/tt0111161/"
    }
  ],
  "titleIds": [],
  "searchTerms": [],
  "maxItems": 100,
  "maxReviewsPerTitle": 100,
  "maxTitlesPerList": 50,
  "reviewSort": "helpfulness",
  "includeSpoilers": true,
  "onlyNewOrChanged": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

No description

# 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": [
        {
            "url": "https://www.imdb.com/title/tt0111161/"
        }
    ],
    "titleIds": [],
    "searchTerms": [],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "UNBLOCKER"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/imdb-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": [{ "url": "https://www.imdb.com/title/tt0111161/" }],
    "titleIds": [],
    "searchTerms": [],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["UNBLOCKER"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/imdb-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": [
    {
      "url": "https://www.imdb.com/title/tt0111161/"
    }
  ],
  "titleIds": [],
  "searchTerms": [],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call tortuga/imdb-scraper --silent --output-dataset

```

## MCP server setup

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