Skip to content

About a week ago, I pushed a script to my GitHub that would monitor the Regal Cinemas website for new movies and report it to a Telegram bot. It was decently feature-rich, but I still wasn’t fully satisfied with it. The primary issue I kept noticing was that the bot would properly fire off an alert whenever a new movie was posted to the website, but oftentimes tickets couldn’t be acquired yet because showtimes are updated separately.

This was obviously very frustrating, so I got to work trying to fix it. The biggest issue that I kept running into kept circling back to Selenium. I was scraping Regal’s website each time the script ran to find the new films listed on its homepage, and this was already a chore in its own right. It seems to use CloudFlare to block non-US IP addresses and also takes advantage of CloudFlare’s anti-crawler tech. Using requests would get blocked due to its user agent, but even passing a generic user agent (at the time of this writing, 41% of desktop users browse the internet on a Windows 10 machine running Chrome 126, represented as Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.3) wouldn’t work well due to the website using dynamic content. In circumstances like these, Selenium is usually the best bet, as it essentially runs a stripped-down version of a web browser to pull remote web content rather than trying to download it. This allows things like JavaScript to fully load in a page, where requests would pull static content.

However, due to its high resource usage, its usually better to avoid using Selenium if at all possible. Thankfully, Regal has left some information out in the open that makes accessing this information far easier.

regal cinemas api

Bazinga! Regal utilizes its own REST API at regmovies.com/api/ for pulling and pushing information from its own databases, and they seem to have left…pretty much everything about it exposed publicly. They even host their own website at developer.regmovies.com, which is pretty much a lightly reskinned default Azure API Management Developer Portal with no actual documentation on the API at all. I actually even signed up for the website to see if I could get any actual documentation, but even having an account yielded no actual documentation. The site does describe some sort of API limits, but thankfully, you don’t actually need to pass any API keys to use it, and there doesn’t seem to be any limits to its usage. So, here’s my own attempt at some documentation, after a couple of days of crawling and google dorking and the like.

Actually, before I go further, after some light brute-forcing, here’s a full list of Regal theaters and their codes, which you’ll find helpful with the API calls below.

And one final note, You need to pass a browser user agent for the API to work. Otherwise, it will fail.

regal cinemas logo

localTheatreData

Main endpoint for pulling information about individual theatre locations.

Endpoint

1
GET regmovies.com/api/localTheatreData

Parameters

ParameterTypeDescriptionExample
locationsstringLocation code of the theater(s) you are querying, comma-separated if querying multiple theaters.0103

Response Fields

FieldTypeValueExample
namestringName of the the locationRegal Downtown West
path_namestringURL slug of the location, located at https://regmovies.com/theatres/(path_name)regal-downtown-west-cinema-0103
theatre_codestringUnique code of the location0103
message_startPossibly unused, could not find a query that reported any information in this field.
message_endPossibly unused, could not find a query that reported any information in this field.
message_titlestringHeader to a message about a location, stringPlease Note:
theatre_info_messagestringBody to an informational message about a locationAfter 6 PM, moviegoers under the age of 17 must be accompanied by a parent or legal guardian 21 years of age. To be on theatre property, a valid state ID or military ID may be required to verify age.
addressstringAddress of the location1640 Downtown West Blvd.
citystringCity of the locationKnoxville
statestringState of the locationTN
postal_codestringZIP code of the location37919
latitudefloatLatitude of the location35.922
longitudefloatLongitude of the location-84.0509
phone_numberstringPhone number of the location(844) 462-7342
pwp_availabilitybooleanIndicates whether or not the location allows for booking of Private Watch PartiesTrue
iana_timezonestringTimezone code in the IANA formatUS/Eastern

getShowtimes

Main API endpoint for fetching showtimes of a theater.

Endpoint

1
GET https://www.regmovies.com/api/getShowtimes

Parameters

ParameterTypeDescriptionExample
theatresstringComma-separated list of theatre codes.0298,0663,0877,0880,0904,0905,0909,1931,1935,1937,1942,1958
datestring(Optional) Specific date for showtimes in YYYY-MM-DD format. If empty, it returns showtimes for today.2024-07-18
hoCodestring(Optional) Unique movie code.HO00015973
ignoreCacheboolean(Optional) If set to true, forces the API to ignore cached data and fetch fresh data. Default is false.false
moviesOnlyboolean(Optional) If set to true, the API will return only the movies available at the theatres, without showtimes.false

Response Fields

shows Array
FieldTypeDescriptionExample
TheatreCodestringUnique code of the theatre.“0298”
AdvertiseShowDatestringLocal date for the advertised show (ISO 8601 format).“2024-07-18T00:00:00”
UtcDatestringUTC date for the advertised show (ISO 8601 format).“2024-07-18T07:00:00.000Z”
FilmarrayArray of films showing at the theatre.See Film Array below
timeintegerUnix timestamp of the data retrieval.1721355012062
Film Array
FieldTypeDescriptionExample
TitlestringTitle of the film.“Despicable Me 4”
MasterMovieCodestringUnique movie code.“HO00015973”
PerformancesarrayArray of performance details.See Performances Array below
Performances Array
FieldTypeDescriptionExample
AuditoriumintegerAuditorium number.14
PerformanceIdintegerUnique Regal performance ID.186535
PerformanceAttributesarrayArray of attributes for the performance.[“2D”, “CC”, “DV”, “Reserved-Selected”]
PerformanceGroupstringSpecial group of the performance.“IMAX”
CalendarShowTimestringLocal calendar time for the show (ISO 8601 format).“2024-07-18T18:40:00”
UtcShowTimestringUTC time for the show (ISO 8601 format).“2024-07-19T01:40:00.000Z”
UnixTimeintegerUnix timestamp for the showtime.1721328000000
StopSalesbooleanIndicates if sales have stopped for the show.false
movies Array
FieldTypeDescriptionExample
TitlestringTitle of the movie.“Despicable Me 4”
MasterMovieCodestringUnique internal Regal movie code.“HO00015973”
RelatedFormatsarrayArray of associated formats, showing information, and auditorium information.[“2D”, “CC”, “DV”, “No Passes”, “Stadium”]
DescriptionstringDescription of the movie.“In the first Despicable Me movie in seven years, Gru, the world’s favorite supervillain-turned-Anti-Villain League-agent, returns for an exciting, bold new era of Minions mayhem in Illumination’s Despicable Me 4.”
RatingstringMPAA movie rating.“PG”
DurationintegerDuration of the movie in minutes.94
ActorsarrayArray of main actors.[“Steve Carell”, “Kristen Wiig”]
DirectorsarrayArray of directors.[“Chris Renaud”]
GenrePrimarystringPrimary genre of the movie.“Adventure”
GenreSecondarystringSecondary genre of the movie.“Animated”
OpeningDatestringOpening date of the movie (ISO 8601 format).“2024-07-03T00:00:00”
StudiostringStudio of the movie.“Universal Film Exchange”

autoComplete

Main API endpoint for fetching geodata on a given ZIP code. This is utilized when a user is typing in their postal code to find the closest theaters to them when looking up showtimes.

Endpoint

GET https://www.regmovies.com/api/autoComplete

Parameters

ParameterTypeDescriptionExample
querystringZIP code to query.37919

Response Fields

Root Object
FieldTypeDescriptionExample
statusCodeintegerHTTP status code of the response.200
predictionsarrayList of autocomplete predictions.See predictions Array below
predictions Array
FieldTypeDescriptionExample
descriptionstringTitle of the prediction.“Knoxville, TN 37919, USA (4 theatres)”
idstringThe ZIP code parameter from the query.“37919”
matched_substringsarrayList of matched substrings in the query.[]
place_idstringPlace ID of the prediction.“37919”
referencestringReference ID of the prediction.“37919”
structured_formattingobjectStructured formatting of the prediction.See structured_formatting Object below
termsarrayList of terms in the prediction.See terms Array below
typesarrayList of types associated with the prediction.[“postal_codes”, “geocode”]
locationobjectLatitude and longitude of the prediction.See location Object below
structured_formatting Object
FieldTypeDescriptionExample
main_textstringMain text of the structured formatting.“37919”
main_text_matched_substringsarrayMatched substrings in the main text.null
secondary_textstringSecondary text of the structured formatting.“Knoxville, TN, US”
terms Array
FieldTypeDescriptionExample
offsetintegerOffset of the term.0
valuestringValue of the term.“Knoxville”
valuestringValue of the term.“TN”
valuestringValue of the term.“37919”
valuestringValue of the term.“USA”
location Object
FieldTypeDescriptionExample
latfloatLatitude of the location.35.9244
lngfloatLongitude of the location.-84.0015

Miscellaneous endpoints

In my search, I also discovered the following endpoints, mostly associated with placing an order.

regmovies.com/api/Member
experience.regmovies.com/api/GetTicketsForSession
experience.regmovies.com/api/OrderMedia
experience.regmovies.com/api/GetTicketsForSession
experience.regmovies.com/api/ForceCancelOrder
experience.regmovies.com/api/GetOrder
experience.regmovies.com/api/AddTickets
experience.regmovies.com/api/cart
experience.regmovies.com/api/SeatPlan

They also varyingly take the following parameters:

  • cartId, which is a string formatted as RWEB + 28 hex characters (presumably a Regal web token).
  • VistaSession, a string consisting of 6 digits.
  • sessionId, a string consisting of 6 digits.
  • date, ISO 8601 format.
  • theatreCode, a string for the unique 4-digit code of a Regal theatre.
  • sessionToken, a string for a session token, stored locally as a cookie in UUID-4 format, AKA 32 hex characters separated in a 8-4-4-4-12 format. Can also pass false in some API calls that require it and still get a valid result. These API calls are absolutely ripe for exploitation, but I’ll leave that for another article after further analysis.

Conclusion

Getting back to the script that I was trying to write, after my discovery, I rewrote it from scratch to utilize Regal’s API and finally get back to using requests. This made the script run overall about 88% faster and use far less processing power. Real neat! Check it out on GitHub, or subscribe to the Telegram channel).