Rotten Tomatoes API endpoint
Returns the critic reviews one Rotten Tomatoes publication has published, newest first: stable review ids, ISO `created_at`/`updated_at` times, the critic identity, the publication name, the quote, the score sentiment and the original article URL. Pass `data.page_info.end_cursor` back as `after` for the next page, with the same `limit` (max 20). `data.subject.kind` is `publication` and `data.subject.title` is the outlet's name. An empty list is a `200` with no reviews. The `id` must be the encrypted publication id (`encrypted_publication_id` on any review row); a numeric id is rejected. `data.fetched_at` is the UTC fetch time.
/rottentomatoes/publication/reviewsid (required): the publication's encrypted_publication_id, which every review row and the publication profile carry. The numeric publication_id is not accepted here and returns an invalid-parameter error, as does an id the upstream does not recognise.limit: reviews per page. Defaults to 10; maximum 20.after: pagination cursor. Pass data.page_info.end_cursor from the previous response and keep limit the same on every page of one walk: the cursor is a page index, so it points at index × limit reviews.data.subject.kind is publication and data.subject.title is the outlet's name (the id you passed if no row names it).critic, movie, episode and season for the dedicated review feeds.id, ISO created_at and updated_at, review (the excerpt the upstream carries, not the article), score_sentiment, original_score when the critic published a score, the critic's display_name, critic_url, critic_vanity and encrypted_critic_id, the publication name and its ids, and publication_review_url, which links to the original article.top_review, top_critic, top_publication, tomatometer_approved and publication_approved are the upstream flags for the row.data.page_info carries has_next_page and end_cursor. A publication with nothing to list, or a cursor past the end, returns 200 with reviews: [].data.transport is feed_api here. The shared transport enum also lists browser_render for review-page request fallbacks and public_page for an embedded sample on movie review pages.data.fetched_at is the UTC time, to the second, when the data was read. A reused response keeps its original time.X-Cache is miss for a live read and hit for a reused response; X-Availability-Last-Success-At and X-Availability-Last-Success-Age-Seconds give the same instant and its age.| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| id | string | Yes | Publication id: encrypted_publication_id | ld6ANN0Z | |
| limit | integer | No | Reviews per page, default 10, max 20. Keep it the same on every page of one walk. | 10 | |
| after | string | No | Pagination cursor: pass data.page_info.end_cursor from the previous response | MQ== | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/rottentomatoes/publication/reviews?id=ld6ANN0Z&limit=10" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"data": {
"subject": {
"kind": "publication",
"path": "",
"url": "",
"title": "Kermode and Mayo's Take (YouTube)"
},
"type": "critics",
"limit": 2,
"source_url": "",
"reviews_api_url": "",
"fetched_at": "2026-10-30T02:15:04Z",
"reviews": [
{
"id": "103175211",
"type": "critic",
"display_name": "Mark Kermode",
"publication": "Kermode and Mayo's Take (YouTube)",
"created_at": "2026-10-28T22:12:45.000Z",
"review": "I really enjoyed it.",
"score_sentiment": "POSITIVE",
"top_review": true,
"top_critic": true,
"top_publication": false,
"tomatometer_approved": true,
"publication_approved": false,
"verified": false,
"super_reviewer": false,
"has_spoilers": false,
"has_profanity": false,
"critic_url": "https://www.rottentomatoes.com/critic/mark-kermode",
"publication_review_url": "https://www.youtube.com/watch?v=fjH-nDZnVhc",
"updated_at": "2026-10-28T22:12:45.000Z",
"scheduled_at": "2026-10-21T19:11:02.000Z",
"status": "ACTIVE",
"language": "English",
"critic_vanity": "mark-kermode",
"encrypted_critic_id": "5rPoepZe",
"publication_id": "100009998",
"encrypted_publication_id": "ld6ANN0Z"
},
{
"id": "103175176",
"type": "critic",
"display_name": "Rick Bentley",
"publication": "KGET-TV (Bakersfield, CA)",
"created_at": "2026-10-28T20:54:09.000Z",
"review": "After a tortuously long backstory, “Clayface” finally gets to the obvious. He uses his ability to look like anyone to get revenge in gory and bloody fashion. There is an effort to give Hagen some depth but they all are superficial moves.",
"score_sentiment": "NEGATIVE",
"original_score": "C-",
"top_review": false,
"top_critic": false,
"top_publication": false,
"tomatometer_approved": true,
"publication_approved": false,
"verified": false,
"super_reviewer": false,
"has_spoilers": false,
"has_profanity": false,
"critic_url": "https://www.rottentomatoes.com/critic/rick-bentley",
"publication_review_url": "https://www.kget.com/community/ricks-reviews/clayface-makes-scary-switch-from-superhero-genre/",
"updated_at": "2026-10-28T20:54:09.000Z",
"scheduled_at": "2026-10-21T19:11:02.000Z",
"status": "ACTIVE",
"language": "English",
"critic_vanity": "rick-bentley",
"encrypted_critic_id": "Wy1K86rz",
"publication_id": "4037",
"encrypted_publication_id": "7ZWMo8lm"
}
],
"page_info": {
"has_next_page": true,
"end_cursor": "MQ=="
},
"transport": "feed_api",
"public_page_derived": false
},
"msg": "OK"
}Request schema
No body schema
Response schema
#/definitions/rottentomatoes.publicationReviewsResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | rottentomatoes.ReviewsResponse | No | ||||
| data.fetched_at | string | No | 2026-06-07T14:46:16Z | UTC time, to the second, when the Rotten Tomatoes page behind this response was fetched. A cached response keeps its original time. | ||
| data.limit | integer | No | 10 | |||
| data.movie | object | No | Movie summary, for movie feeds only. Kept for existing callers; prefer subject for new integrations. | |||
| data.movie.ems_id | string | No | afbf1c81-1bfe-3996-9cbc-2e1be23d1f61 | |||
| data.movie.media_type | string | No | Movie | |||
| data.movie.path | string | No | /m/inception | |||
| data.movie.title | string | No | Inception | |||
| data.movie.url | string | No | https://www.rottentomatoes.com/m/inception | |||
| data.page_info | object | No | Whether more reviews follow this page, and the cursor to request them. | |||
| data.page_info.end_cursor | string | No | Mjk= | Cursor of the last item on this page. Pass it as `after` to get the next page. | ||
| data.page_info.has_next_page | boolean | No | true | Whether more items follow this page. | ||
| data.page_info.has_previous_page | boolean | No | true | Whether items precede this page. | ||
| data.page_info.start_cursor | string | No | MA== | Cursor of the first item on this page. | ||
| data.public_page_derived | boolean | No | true | True when the reviews came from the public page's embedded sample rather than from the gated critic-review feed. | ||
| data.render | object | No | Browser render audit facts. Present only for `browser_render`. | |||
| data.render.load_more_clicks | integer | No | 0 | "Load More" steps needed to reach the requested page. | ||
| data.render.pages_fetched | integer | No | 1 | Number of distinct review pages that were loaded. | ||
| data.render.total_ms | integer | No | 18432 | Total wall time the render took, in milliseconds. | ||
| data.render_error | string | No | Why a browser render that was attempted did not produce the response, when a public-page sample was served instead. | |||
| data.reviews | array | No | MovieReview record, 34 fields: created_at, critic_url, critic_vanity, display_name, encrypted_critic_id, encrypted_publication_id, has_profanity, has_spoilers, id, language, media, original_score and 18 more. Described under Rotten Tomatoes movie reviews API. | |||
| data.reviews_api_url | string | No | https://www.rottentomatoes.com/napi/rtcf/v1/movies/afbf1c81-1bfe-3996-9cbc-2e1be23d1f61/reviews?type=critic&pageCount=10 | |||
| data.source_url | string | No | https://www.rottentomatoes.com/m/inception/reviews/all-critics | |||
| data.subject | object | No | Subject of the feed: a movie, TV season, TV episode or critic. | |||
| data.subject.ems_id | string | No | 71374db9-1350-30fa-b30a-d3f623bbdfc4 | Rotten Tomatoes' own unique id of the subject, when it has one. | ||
| data.subject.kind | string | No | movie, season, episode, critic, publication | season | Kind of subject: `movie`, `season`, `episode`, `critic` or `publication`. | |
| data.subject.media_type | string | No | TvSeason | Kind of title, such as `TvSeason`. | ||
| data.subject.path | string | No | /tv/breaking_bad/s01 | Rotten Tomatoes path of the subject. | ||
| data.subject.title | string | No | Breaking Bad: Season 1 | Display title of the subject, when known. | ||
| data.subject.url | string | No | https://www.rottentomatoes.com/tv/breaking_bad/s01 | Rotten Tomatoes page URL of the subject. | ||
| data.transport | string | No | feed_api, browser_render, public_page | feed_api | How the reviews were read. `feed_api` is the review feed's own JSON API, which is newest-first, carries review ids and ISO timestamps and is not bounded by the page's click depth. `browser_render` is the same feed read from the review page's own requests in a real browser. `public_page` is the embedded sample on the public movie page. | |
| data.type | string | No | critics | |||
| msg | string | No | OK |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 404 | Not Found | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 500 | Internal Server Error | #/definitions/app.Response |
| 503 | Service Unavailable | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/rottentomatoes/publication/reviews?id=ld6ANN0Z&limit=10" \
-H "x-api-key: $CRAWLORA_API_KEY"