BookMyShow Scraper - Movies, Events & Showtimes
Pricing
from $1.20 / 1,000 movie, event or showtime records
BookMyShow Scraper - Movies, Events & Showtimes
Scrape BookMyShow movies and live events by city, category or URL. Extract genres, languages, posters, synopsis, cast, show dates and cinema showtimes. Includes incremental monitoring, resume support and MCP export.
Pricing
from $1.20 / 1,000 movie, event or showtime records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
6
Total users
3
Monthly active users
21 hours ago
Last modified
Categories
Features
Share
BookMyShow Scraper: Movies, Events & Showtimes
BookMyShow Scraper turns BookMyShow India into a clean movies-and-events data feed. Get movie listings with cast, genres, languages and formats, live events such as concerts, comedy shows and plays with venue and pricing, and per-cinema showtimes for any city. Search a city and category, or paste exact links, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.
Why This Scraper?
- Three ways to find data. Search a city and category listing, paste exact BookMyShow links (movie pages, event pages, per-day showtimes pages or city explore links), or read the showings of chosen movies over a window of dates.
- Three record kinds in one dataset. Movies, live events (concerts, comedy, workshops, plays, sports, activities) and per-cinema showtimes, discriminated by
kind. - Movie filters on the source's own codes. Language, genre and format narrow a search server-side; unknown codes are dropped instead of silently riding along.
- Detail enrichment on demand. Merge each listing row's synopsis, cast, director, formats and release date from its own page, with a small surcharge only on rows actually read.
- Built for monitoring. Incremental mode returns only new, updated and reappeared records on repeat runs, and unchanged records are never billed by default.
- Resume support. Continue a large pull without paying twice for records already collected.
- A refused run fails loudly instead of coming back as an empty, silent success.
Use Cases
- Cinema listing apps: feed movie showtimes, formats and availability for one or more cities into your own booking or discovery app.
- Event discovery and ticketing tools: track concerts, comedy shows, plays and sports events with venue, date, price and availability.
- Entertainment content and media teams: generate city guides, "what's on" roundups and movie previews automatically.
- Market research: monitor movie release patterns, formats and language mixes across Indian cities over time.
- Price and availability tracking: watch showtime availability status for specific movies or events on a schedule.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
kind | "movie" (also "event", "showtime") |
recordId | "movie:ET00000001" |
eventCode | "ET00000001" |
title | "Sample Movie Title" |
url | BookMyShow link to the movie, event or showtimes page |
posterUrl | poster image link (churns hourly; excluded from change detection) |
languages / genres | ["hindi", "english"] / ["drama", "action"] (movies) |
category | "movies" (also "events", "plays", "sports", "activities", "showtimes") |
regionCode | "SAMPLE" |
venueName / venueCode | "Sample Cinema" / "SAMP" (events and showtimes) |
listingSection | the widget group title when a listing names it (the live listings currently serve unnamed groups, so it is null; excluded from change detection and not a table column) |
tags | ["2D", "UA"] |
synopsis | plot or event description (detail pages) |
duration / releaseDate | "2h 15min" / "2026-01-01" (movies, detail pages) |
censor | "UA" (movies, detail pages) |
formats | ["2D", "IMAX 2D"] (movies, detail pages) |
cast / director | ["Sample Actor"] / "Sample Director" (movies, detail pages) |
rating / ratingText / ratingCount | 8.7 / "8.7/10" / 166357 (released movies, detail pages; empty until a movie has a rating, never a zero; the count only where the page publishes one) |
priceDisplay / availability | "Sample price display" / "Sample availability status" (events, detail pages) |
dateText / timeText | "1 Jan" / "7:00 PM" (events and showtimes) |
showDateCode / showDateTime | "20260101" / "202601011900" (showtimes only) |
sessionId / availStatus | "999999" / "1" (showtimes only) |
infoLabels / filters | ["Recliner"] / ["subtitled"] (showtimes only) |
changeType | "NEW" (also "UPDATED", "UNCHANGED", "REAPPEARED", "EXPIRED"; incremental mode) |
changedFields / firstSeenAt / lastSeenAt | [] / ISO timestamp / ISO timestamp (incremental mode) |
Showtime records leave title, languages and genres empty since they represent one showing rather than the movie or event itself; movie and event records do not carry the showtime-only fields (showDateCode, showDateTime, sessionId, availStatus, infoLabels, filters).
Showtime price, status and region fields
Showtime rows (one per showing) carry: sessionKey (stable id: venue code, session id and show time), showDateTimeUtc (the local show time converted to UTC), showDateCode, eventTitle, eventLanguage, eventFormat, eventGenre, censorRating, venueChain, venueUrl, citySlug, cutOffAtUtc, isMTicketAvailable and scrapedAt.
- Prices:
priceClasseslists the seat categories of the showing as{name, price, availability}(for exampleEXECUTIVE ROWS, 630,filling_fast), read from the price sheet the site itself ships for every showing.minPrice,maxPriceandpriceClassCountsummarise it andcurrencyisINR. A showing with no price sheet (some sold-out showings) returnspriceClassesempty and the three summaries null, never a zero. - Status:
sessionStatusdecodes the site's ownavailStatuscode intoavailable,filling_fast,almost_fullorsold_out(the codes 3, 2, 1 and 0, measured on over a thousand live showings).sessionAttributeslists the screen attributes of the showing (for exampleLaser,Dolby Atmos,Insignia,Cancellable) decoded from thefilterscodes. - Region:
regionName,regionCode,regionSlugandsubCodecome from the site's own region record for the page (for exampleDelhi-NCR,NCR,ncrand, for a sub-region such as Noida,NOIDA). - Seat layout:
seatLayoutUrlis the site's own seat-selection page for the showing. Seat counts and a full-layout flag are only served behind that page's sign-in (measured 2026-11-09), so the actor has no seat-count or full-layout fields at all and never returns them as empty values; the availability label per price class is the public signal.
Date handling in URL mode: a showtimes link with a date code (.../buytickets/ET00496545/20261110) returns that day; a link without a date returns the site's current day. A date in the past falls back to the current showings with a warning in the run log. One showtimes link is one day; to cover several days use showtimes mode below.
Showtimes mode: movies and dates
Set Mode to showings by movie and date to get every showing of the movies you choose over a window of days, without pasting one link per day:
- Movies: list movie codes in
eventCodes(up to 25), or leave it empty to read the top movies of the city's Now Showing listing (maxMovies, 1 to 25, default 3). - Dates:
dateModeisAUTO_DISCOVER(today and up tomaxDaysAheaddays after, 1 to 14, default 3; a movie stops afteremptyDateStreakLimitempty days in a row, 1 to 7, default 2),EXPLICIT_DATES(thedatesyou list, up to 14) orDATE_RANGE(fromDatetotoDateinclusive, capped at 14 days). Days are India calendar days, and past days are skipped. - Date range details: an empty or past
fromDatestarts today. With notoDatethe range is the first day plus the 3 days after it, 4 days in all. AfromDateortoDatethat is not a real calendar date is treated as empty, and atoDatebefore the first day reads nothing and says so in the run log. InAUTO_DISCOVERthe window is likewise today plusmaxDaysAheaddays after it. - City: a Delhi-NCR sub-region such as
noidaorgurgaonreads that sub-region's own showings. - Every list and window above has a finite cap,
maxItemsstill bounds the run, and showtimes mode adds no detail surcharge.
How to Use
- Pick a mode:
search(a city and category listing),url(paste BookMyShow links) orshowtimes(the showings of chosen movies over a date window). - For search mode, set City and Category; movies also accept language, genre and format filters. For URL mode, paste the links.
- Turn Fetch details on or off, and set Max items to control run size and cost.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Search movies in a city, filtered by language:
{"mode": "search","city": "mumbai","category": "movies","languages": "hindi,english","maxItems": 20}
Search live events in another city:
{"mode": "search","city": "bengaluru","category": "events","maxItems": 50}
Paste links (movie page, city explore link):
{"mode": "url","urls": ["https://in.bookmyshow.com/movies/mumbai/sample-movie-title/ET00000001","https://in.bookmyshow.com/explore/movies-pune"],"fetchDetails": true}
URL mode link shapes
URL mode run with the urls field untouched scrapes the 16 example links prefilled in that field, which cover every shape below except the bare-host movie page (accepted, but not in the prefilled list). Links on in.bookmyshow.com and bookmyshow.com are accepted; any other host is skipped with a warning in the run log. A showtimes link with a past date falls back to the current showings, with a warning. A link that yields no records is reported in the log.
| Shape | Example |
|---|---|
| City movies explore listing | https://in.bookmyshow.com/explore/movies-mumbai |
| City events explore listing | https://in.bookmyshow.com/explore/events-mumbai |
| City plays explore listing | https://in.bookmyshow.com/explore/plays-mumbai |
| City sports explore listing | https://in.bookmyshow.com/explore/sports-mumbai |
| City activities explore listing | https://in.bookmyshow.com/explore/activities-mumbai |
| Filtered explore listing (languages) | https://in.bookmyshow.com/explore/movies-mumbai?languages=hindi |
| City home explore page | https://in.bookmyshow.com/explore/home/mumbai |
| Movie page | https://in.bookmyshow.com/movies/mumbai/clayface/ET00496545 |
| Movie page, other city path | https://in.bookmyshow.com/movies/bengaluru/clayface/ET00496545 |
| Upcoming movies explore listing | https://in.bookmyshow.com/explore/upcoming-movies-mumbai |
| Live event page, non-numeric code | https://in.bookmyshow.com/events/amit-kumar-live-in-mulund/et675ifet4 |
| Legacy showtimes page | https://in.bookmyshow.com/buytickets/clayface-mumbai/movie-mumbai-ET00496545-MT/20261111 |
| City events listing, bare host | https://www.bookmyshow.com/explore/events-bengaluru |
| Movie page, bare host | https://bookmyshow.com/movies/mumbai/clayface/ET00496545 |
| Live event page | https://in.bookmyshow.com/events/acrylic-painting-workshop/ET00499618 |
| Per-day showtimes page with date code | https://in.bookmyshow.com/movies/mumbai/clayface/buytickets/ET00496545/20261110 |
| Showtimes page without date | https://in.bookmyshow.com/movies/mumbai/clayface/buytickets/ET00496545 |
Incremental monitoring for a scheduled run:
{"mode": "search","city": "chennai","category": "movies","incrementalMode": true,"stateKey": "chennai-movies-daily","maxItems": 0}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/bookmyshow-scraper").call(run_input={"mode": "search", "city": "mumbai", "category": "movies"})for record in client.dataset(run["defaultDatasetId"]).iterate_items():print(record["kind"], record["title"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/bookmyshow-scraper').call({ mode: 'search', city: 'mumbai', category: 'movies' });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How the city listing is read
Each city and category serves its full listing in one page: there is no second page to walk. Max items trims how many of that page's records are returned (0 = no limit); it does not reveal more records. To get a different set, change the city, category, or the language, genre and format filters.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips every record id already collected there, so you don't pay twice. - Incremental mode (
incrementalMode) is for scheduled runs over the same city, category and filters. Each record is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEAREDorEXPIRED(only after a run that scanned the whole listing, and only withemitExpired). The poster image URL and the listing widget group are excluded from change detection, so neither churning alone produces an UPDATED row.stateKeynames or shares the stored state; leave it empty to let the actor derive one automatically from the search or link settings.ignoreFieldsForChangeslists extra fields (dotted paths for nested values) to leave out of change detection; changing that list never turns stored records into a one-time wave of UPDATED rows. A showing's seat-category availability moves as seats sell, sopriceClassesshows as changed when a category's label moves (the same real change asavailStatus); addpriceClasses.availabilitytoignoreFieldsForChangesto leave it out. With incremental mode off, output is exactly as before.
Output views
The dataset has these table views in the Console: Records (everything), Movies, Live events, Showtimes and Changes (incremental).
Send results into your apps (MCP connectors)
Optionally pipe the scraped results 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 record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify, Settings, Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (city and category listing), url (paste BookMyShow links) or showtimes (showings by movie and date). |
city | string | mumbai | Search mode: the city slug, for example mumbai, national-capital-region-ncr, bengaluru, hyderabad, chandigarh, ahmedabad, pune, chennai, kolkata, kochi. Any other valid city slug from the site works. |
category | string | movies | Search mode listing: movies, events, plays, sports, or activities. |
languages | string | (none) | Movies only: comma-separated language codes, for example hindi, english, tamil. Unknown codes are dropped rather than silently ignored. |
genres | string | (none) | Movies only: comma-separated genre codes, for example action, drama, comedy. Unknown codes are dropped rather than silently ignored. |
formats | string | (none) | Movies only: comma-separated format codes, for example 2d, 3d, 4dx, imax-2d. Unknown codes are dropped rather than silently ignored. |
urls | array | one example of each link shape | URL mode: BookMyShow pages to read, one per line. Movie pages and live-show pages are one record each; per-day showtimes pages are one record per showing; city explore links are walked like search mode. |
eventCodes | array | (none) | Showtimes mode: up to 25 BookMyShow codes in any letter case: ET plus digits (movies), or the site's non-numeric form of ET plus 8 letters or digits; a full BookMyShow link containing a code also works. Showings are read from the movie showtimes pages, so use movie codes. Empty uses the city's top movies. |
maxMovies | integer | 3 | Showtimes mode with no movie codes: how many Now Showing movies to read, 1 to 25. |
dateMode | string | AUTO_DISCOVER | Showtimes mode: AUTO_DISCOVER, EXPLICIT_DATES or DATE_RANGE. |
dates | array | (none) | Explicit dates mode: YYYY-MM-DD dates, up to 14. Past dates are skipped. |
fromDate | string | (none) | Date range mode: first day, YYYY-MM-DD. Empty or past starts today. |
toDate | string | (none) | Date range mode: last day, YYYY-MM-DD, inclusive; the range is capped at 14 days. Empty reads the first day plus the 3 days after it (4 days). |
maxDaysAhead | integer | 3 | Auto discover: days after today to read at most, 1 to 14. |
emptyDateStreakLimit | integer | 2 | Auto discover: stop a movie after this many empty days in a row, 1 to 7. |
maxItems | integer | 20 | Stop after this many records (0 = no limit; the run then stops when the results run out). |
maxPages | integer | 0 | Upper bound on pages walked per scope. This listing surface arrives in one server-rendered page, so a walk reads exactly that page; the bound exists for consistency and defaults wide open. |
fetchDetails | boolean | true | Read each listing row's own page and merge the richer fields (synopsis, duration, censor, release date, formats, cast, director, and for live shows date, time, venue, price display and availability). Adds a per-row surcharge only on rows actually read; refused reads are pushed without the extra fields and never charged. |
resumeFromRunId | string | (none) | Continue one interrupted run: paste a previous run ID or dataset ID. |
incrementalMode | boolean | false | Turn on for daily or recurring monitoring. Returns only new and changed records on repeat runs over the same scope. |
stateKey | string | (none) | Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to derive a key automatically from the search and link settings. |
emitUnchanged | boolean | false | Also return (and bill) records that have not changed since the last run. |
emitExpired | boolean | false | Also return (and bill) records that were present before but are no longer found. Only produced once a run has fully scanned the tracked search. |
ignoreFieldsForChanges | array | (none) | Incremental mode only: field names that must not count as a change. Dotted paths reach nested values (for example showtimes.availability). Returned records still carry the live values. |
mcpConnectors | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which item pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
proxyConfiguration | object | Residential, India | Apify Proxy settings. Every run uses residential India exits by default: the lane the site reliably serves. You can bring your own proxy here. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"kind": "movie","recordId": "movie:ET00000001","eventCode": "ET00000001","title": "Sample Movie Title","url": "https://in.bookmyshow.com/movies/sample-city/sample-movie-title/ET00000001","posterUrl": "https://assets-in.bmscdn.com/discovery-catalog/events/sample-poster.jpg","languages": ["hindi", "english"],"genres": ["drama", "action"],"category": "movies","regionCode": "SAMPLE","venueName": null,"venueCode": null,"listingSection": "Recommended Movies","tags": ["2D", "UA"],"synopsis": "A sample synopsis describing the plot in general terms.","duration": "2h 15min","censor": "UA","releaseDate": "2026-01-01","formats": ["2D", "IMAX 2D"],"cast": ["Sample Actor One", "Sample Actor Two"],"director": "Sample Director","priceDisplay": null,"availability": null,"dateText": null,"timeText": null}
Plan Requirement
BookMyShow refuses datacenter connections on every exit: measured, the site answers an "Attention Required" block page (HTTP 403) to the default datacenter pool every time. Residential connections located in India are required, and this actor uses them by default, so a paid Apify plan (or your own residential proxy URLs under Connection) is needed. Even on residential exits some fetches meet a short "Just a moment..." check (measured 4 in about 30, roughly one in seven); the actor simply retries on a fresh exit.
Apify free plans do not include residential proxies. On a free plan the run logs this notice and continues on a backup connection, where some pages may still be unavailable:
The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs.
If nothing can be read the run fails with a clear message instead of returning an empty dataset: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested BookMyShow pages." (free plan), or "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required." Setting the environment variable BOOKMYSHOW_IN_ALTERNATE_CONNECTION=0 turns the backup connection off.
FAQ
How much does it cost?
Billing uses three registered events. apify-default-dataset-item is charged once per movie, event or showtime record returned in the dataset. detail-enrichment is charged once per row whose own detail page was read and merged (only when Fetch details is on and the read succeeds; refused reads are never charged). apify-actor-start is charged once per run, per GB of memory. Unchanged records suppressed in incremental mode are not returned and not billed. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape BookMyShow?
This actor collects only publicly available listing data. You are responsible for how you use it: follow BookMyShow's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Posters, synopses and other creative assets may be subject to third-party rights.
Can I get only new or changed listings 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 records for the same city, category and filters, and unchanged ones are not billed by default.
Why did a run return fewer records than expected?
Each city and category listing serves its full page in one response; there is no second page to walk. Max items trims how many of that page's records come back, it does not reveal more. If you expected more, check the spelling of the city slug, clear the language, genre or format filters, or raise Max items.
Why did my run fail instead of returning an empty dataset?
If every request to the site is refused, the run stops with a clear message so "this city has nothing on today" is never confused with "nothing could be read". Run it again in a few minutes. If only some links or scopes could 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.
๐ Want more sports data?
Pair this actor with these related scrapers from the same team:
| โฝ JioHotstar Scraper Scrape the JioHotstar catalog by content type or URL. Extract shows, movies, episodes... | โฝ Eventim Scraper Scrape CTS Eventim Germany and EU event catalogue: concerts, festivals, comedy, sports... |
| โฝ Sportsbook Odds Scraper (1xBet, Melbet, Linebet, Paripulse) Collect live and prematch betting odds from 1xBet, Melbet, Linebet and Paripulse. Give it... | โฝ Whatnot Scraper Scrape Whatnot live and upcoming shows, queued items and lots, and seller profiles... |
| โฝ FanDuel Odds Scraper Scrape FanDuel sportsbook odds, including moneylines, spreads, totals, player props and... | โฝ Strava Data Scraper Scrape public Strava data: clubs (members, location, sport, settings), athlete profiles... |
๐ 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.