# Fandango at Home > Fandango at Home is a streaming video-on-demand service offering movies and TV shows to rent, buy, or watch free with ads (AVOD). Content is available in SD, HD, HDX (1080p), and UHD/4K. Fandango at Home is accessible at https://athome.fandango.com. Users can browse, rent, buy, and watch streaming content including free ad-supported titles. > **Content freshness:** The catalog is CDN-backed and can change hourly. Re-query search and browse endpoints at least once per session - do not cache results across sessions, as titles are added, removed, and change offer availability frequently. ## Content Catalog API The content API supports two calling styles against the same base URL `https://apicache.vudu.com/api2/`. **Style 1 - POST JSON** (recommended for programmatic use): ``` POST https://apicache.vudu.com/api2/ Content-Type: application/json { "_type": "contentSearch", "titleMagic": "inception", ... } ``` **Style 2 - GET path-params** (used by the web app, shareable as URLs): ``` GET https://apicache.vudu.com/api2/_type/contentSearch/titleMagic/inception/count/10/.../format/application*2Fjson ``` Parameters are alternating key/value path segments. Repeated keys (e.g. `type`, `followup`) are expressed as repeated segments. The `format/application*2Fjson` segment (URL-encoded `application/json`) requests a JSON response. Add `contentEncoding/gzip` and `Accept-Encoding: gzip` for compressed responses. All examples in this document use POST JSON. The `clientType` field should be `"html5app"`. Responses are JSON (sometimes wrapped in `/*-secure-` ... `*/` by CDN - strip that wrapper if present). ### Search by Title Use `titleMagic` for all content searches - it supports partial/fuzzy matching and works across movies and TV. `title` requires an exact prefix match and **does not work for TV content** (returns zero results for series, seasons, or episodes). ```json { "_type": "contentSearch", "titleMagic": "incep", "count": 10, "offset": 0, "sortBy": "-releaseTime", "type": ["program"], "clientType": "html5app" } ``` TV example - partial term matches series: ```json { "_type": "contentSearch", "titleMagic": "break", "count": 10, "offset": 0, "type": ["series"], "clientType": "html5app" } ``` > `title` is a strict prefix filter that only works reliably for movies. Prefer `titleMagic` for all user-facing search. **`type` values:** `"program"` (movies), `"series"`, `"season"`, `"episode"` **`superType` values:** `"movies"`, `"tv"` (broad filter across all TV sub-types) **`sortBy` values** (prefix `-` for descending): - `releaseTime` - theatrical release date - `firstVuduableTime` - date added to Fandango at Home - `title` - alphabetical - `starRating` - user star rating - `tomatoMeter` - Rotten Tomatoes critic score ### Look Up a Title by Content ID Fetch full metadata for a known content ID: ```json { "_type": "contentSearch", "contentId": ["182168"], "count": 1, "offset": 0, "clientType": "html5app" } ``` Content IDs are returned in search results as `contentId`. Example IDs: - `182168` - Inception (2010) - `6873` - Saw (2004) - `9073` - Maverick (1994) ### Filter by Offer Type Filter by transaction type (rent or buy): ```json { "_type": "contentSearch", "offerType": ["pto"], "count": 10, "offset": 0, "sortBy": "-firstVuduableTime", "type": ["program"], "clientType": "html5app" } ``` **`offerType` values:** - `"pto"` - purchase/buy (permanent ownership) - `"ptr"` - rental (time-limited) > Note: There is no AVOD/free filter parameter. Free ad-supported titles are identified by the presence of `advertContentDefinitions` in the response (see below). ### Filter by Genre Filter results by genre ID: ```json { "_type": "contentSearch", "genreId": ["101"], "offerType": ["pto"], "count": 10, "offset": 0, "sortBy": "-releaseTime", "type": ["program"], "clientType": "html5app" } ``` **Genre IDs** (enumerated from live catalog): - `101` - Action - `104` - Comedy - `105` - Documentary - `106` - Drama - `107` - Family - `108` - International - `110` - Horror - `112` - Music/Musical - `113` - Romance - `114` - Sci-Fi - `115` - Other - `117` - Suspense - `118` - Adventure - `120` - Crime - `121` - Historical - `122` - Western - `123` - Fantasy - `124` - Animation - `125` - Sports - `126` - Independent - `127` - Reality - `128` - Kids - `129` - Superheroes ### Discover Free (AVOD) Content There is no direct `offerType` filter for free/AVOD content. To identify free titles, request `advertContentDefinitions` as a followup field. Titles with a non-empty `advertContentDefinition` array inside that response are available to watch free with ads: ```json { "_type": "contentSearch", "offerType": ["pto"], "count": 25, "offset": 0, "sortBy": "-firstVuduableTime", "type": ["program"], "clientType": "html5app", "followup": ["advertContentDefinitions"] } ``` In the response, a title is free (AVOD) if the `advertContentDefinitions` array contains objects with an `advertContentDefinition` sub-array: ```json "advertContentDefinitions": [ { "_type": "advertContentDefinitionList", "advertContentDefinition": [ { "_type": "advertContentDefinition", "advertContentDefinitionId": ["52857"], "contentId": ["2039923"], "preRollEnabled": ["true"], "midRollSpotSecond": ["557", "1740", "2982"], "startTime": ["2022-07-13 07:00:00"], "stopTime": ["2027-06-30 07:00:00"] } ] } ] ``` A title with `"moreAbove": ["false"], "moreBelow": ["false"]` and no `advertContentDefinition` items is **not** available free. ### Get Genre Metadata for a Title To retrieve the genres associated with a specific title, include `"genres"` in the followup: ```json { "_type": "contentSearch", "contentId": ["182168"], "count": 1, "offset": 0, "followup": ["genres"], "clientType": "html5app" } ``` The response includes: ```json "genres": [ { "_type": "genreList", "genre": [ { "_type": "genre", "genreId": ["101"], "name": ["Action"] }, { "_type": "genre", "genreId": ["114"], "name": ["Sci-Fi"] } ] } ] ``` ### TV Series Hierarchy TV content is structured as series → seasons → episodes. Traverse the hierarchy using `containerId`: **Step 1 - Find a series:** ```json { "_type": "contentSearch", "titleMagic": "breaking bad", "count": 5, "offset": 0, "type": ["series"], "clientType": "html5app" } ``` Response includes `contentId` for the series (e.g. `"205516"` for Breaking Bad). **Step 2 - Get seasons by series `contentId` as `containerId`:** ```json { "_type": "contentSearch", "containerId": ["205516"], "count": 10, "offset": 0, "type": ["season"], "clientType": "html5app" } ``` **Step 3 - Get episodes by season `contentId` as `containerId`:** ```json { "_type": "contentSearch", "containerId": ["207559"], "count": 20, "offset": 0, "type": ["episode"], "clientType": "html5app", "followup": ["episodeNumberInSeason", "seasonNumber", "advertContentDefinitions"] } ``` The `episodeNumberInSeason` and `seasonNumber` followups add structured numbering to each episode (e.g. S1E1, S1E2). Example response fields: `"seasonNumber": ["1"]`, `"episodeNumberInSeason": ["1"]`. Series titles in the catalog carry a `[TV Series]` suffix (e.g. `"Breaking Bad [TV Series]"`). Strip this when displaying to users. ### Free First Episodes (AVOD on TV) Episodes, like movies, expose AVOD availability via `advertContentDefinitions` in the followup. Individual episodes may be free even if the rest of the season requires purchase. Check each episode in Step 3 above - presence of an `advertContentDefinition` sub-array signals free ad-supported playback. Example workflow to find free episodes for a show: ```json { "_type": "contentSearch", "containerId": ["SEASON_CONTENT_ID"], "count": 20, "offset": 0, "type": ["episode"], "clientType": "html5app", "followup": ["advertContentDefinitions"] } ``` Filter client-side: episodes where `advertContentDefinitions[0].advertContentDefinition` is non-empty are free to watch with ads. ## Person Credits and Filmography ### Get Cast and Crew for a Title Use `creditSearch` with a `contentId` to retrieve cast, crew, and director credits. Note: `clientType` is not accepted by this operation. ```json POST https://apicache.vudu.com/api2/ { "_type": "creditSearch", "contentId": ["182168"], "count": 20, "offset": 0 } ``` Each `credit` object includes: ```json { "_type": "credit", "firstName": ["Christopher"], "lastName": ["Nolan"], "personId": ["750584"], "role": ["Director", "Producer", "Screenwriter"], "portraitUrl": ["http://images2.vudu.com/person/750584"] } ``` For actors, a `characterName` field is also included. The `personId` is used to look up filmographies. ### Get a Person's Filmography Use `creditPersonId` in a `contentSearch` to retrieve all titles associated with a director or actor. Include all relevant `type` values and use `responseSubset: ["micro"]` for a lightweight response (returns only `contentId`, `title`, `type`, and quality fields). Use `followup: ["seasonNumber", "episodeNumberInSeason"]` to get structured season/episode numbering on TV content. `groupBy: "series"` groups TV episodes under their parent series. ```json { "_type": "contentSearch", "creditPersonId": ["750584"], "type": ["program", "season", "series", "episode", "bundle"], "dimensionality": "any", "groupBy": "series", "includeComingSoon": true, "includePreOrders": true, "followup": ["seasonNumber", "episodeNumberInSeason"], "responseSubset": ["micro"], "count": 25, "offset": 0, "clientType": "html5app" } ``` Equivalent as a GET path-param URL (shareable, used by the web app): ``` https://apicache.vudu.com/api2/_type/contentSearch/count/25/creditPersonId/750584/dimensionality/any/followup/episodeNumberInSeason/followup/seasonNumber/format/application*2Fjson/groupBy/series/includeComingSoon/true/includePreOrders/true/offset/0/responseSubset/micro/type/bundle/type/episode/type/program/type/season/type/series ``` **`responseSubset` values:** - `"micro"` - minimal fields only: `contentId`, `title`, `type`, `bestDashVideoQuality`, `bestHlsVideoQuality`, `bestStreamableVideoQuality`. Use for large result sets. - Omitting `responseSubset` returns the full metadata response. **`type` values for filmography:** `"program"` (movies), `"series"`, `"season"`, `"episode"`, `"bundle"` (multi-title packs) Example person IDs (from `creditSearch` on Inception): - `750584` - Christopher Nolan (Director) - `562171` - Leonardo DiCaprio (Actor) - `570009` - Joseph Gordon-Levitt (Actor) ### Person Portrait Images Portrait images for cast and crew are available at: ``` https://images2.vudu.com/person/{personId} ``` Example: - https://images2.vudu.com/person/750584 - Christopher Nolan - https://images2.vudu.com/person/562171 - Leonardo DiCaprio ### Filmography Pages Each person has a browseable filmography page on FAH: ``` https://athome.fandango.com/content/browse/filmography/{slug}/{personId} ``` The `{slug}` is decorative (same as content detail URLs - any string resolves on `personId` alone). Examples: - https://athome.fandango.com/content/browse/filmography/Christopher-Nolan/750584 - https://athome.fandango.com/content/browse/filmography/Leonardo-DiCaprio/562171 Convention: first and last name hyphenated, e.g. `Christopher-Nolan`. > Note: `robots.txt` disallows `/content/browse/filmography/*` from crawler indexing, but the pages return HTTP 200 and are accessible to users and LLMs. Do not proactively crawl or bulk-index these URLs. ## Trailer Player Trailers resolve at the following canonical URL (the `/content/movies/play/` form also works but 301-redirects here): ``` https://athome.fandango.com/content/browse/play/{contentId}/TRAILER ``` Example: - https://athome.fandango.com/content/browse/play/182168/TRAILER - Inception trailer The sitemap declares trailer `player_loc` entries with `allow_embed="yes"`, meaning they can be iframed by third parties. Additional trailer edition IDs are returned in search results: - `streamableTrailerEditionId` - general streaming trailer edition - `hlsTrailerEditionId` - HLS format trailer edition - `dashTrailerEditionId` - DASH format trailer edition ## Images Poster images are served from: - `https://images2.vudu.com/poster2/{contentId}-338` - 338px wide (used in sitemap thumbnails) - `https://images2.vudu.com/poster2/{contentId}` - default size (redirects to current image) The `-338` suffix requests a specific width. Both forms return HTTP 200. Note: The API response also includes a `placardUrl` field pointing to `images2.vudu.com/placard2/{contentId}`, but these URLs consistently return 404. Use `posterUrl` / `poster2` only. Example: - https://images2.vudu.com/poster2/182168-338 - Inception poster (338px) - https://images2.vudu.com/poster2/182168 - Inception poster (default) ## Content Detail URL Format All content types - movies, series, seasons, and episodes - use the same URL pattern: ``` https://athome.fandango.com/content/browse/details/{slug}/{contentId} ``` The `{slug}` is **purely decorative**. Any string works - the page resolves entirely on `contentId`. Using a human-readable slug improves appearance but is not required. Verified with series (205516), season (207559), and episode (207577) content IDs. Examples: - https://athome.fandango.com/content/browse/details/Inception/182168 - movie - https://athome.fandango.com/content/browse/details/Breaking-Bad/205516 - TV series - https://athome.fandango.com/content/browse/details/Breaking-Bad-Season-1/207559 - season - https://athome.fandango.com/content/browse/details/Breaking-Bad-Pilot/207577 - episode Convention from the sitemap: spaces → hyphens, special characters dropped. ## Pricing Data The sitemap exposes SD/HD rental and purchase prices per title in structured `video:price` elements. Typical price ranges observed: - Rental: $2.99–$7.99 (SD or HD) - Purchase: $5.00–$19.99 (SD or HD) Pricing is not exposed through the public content search API - it is only present in the sitemap XML and on the detail page. ## Notable API Behaviors - **Pagination:** Use `count` (page size, max ~50 reliable) and `offset` (zero-based index). - **Arrays in responses:** Most scalar fields are returned as single-element arrays, e.g. `"title": ["Inception"]`, `"contentId": ["182168"]`. - **`genres` list endpoint:** Access-denied publicly. Retrieve genre IDs per-title via `followup: ["genres"]` on a content lookup, or use the enumerated genre IDs in the Filter by Genre section above. - **`filmography` paths:** `robots.txt` disallows `/content/browse/filmography/*` - automated crawling is disallowed, but these pages return HTTP 200 and are linkable. - **`offerType` enum is strict:** Only `pto` and `ptr` are valid. Any other value returns a validation error. - **CDN wrapper:** Responses from `apicache.vudu.com` may be wrapped as `/*-secure-{...}*/`. Strip this wrapper before parsing JSON. - **`/api2` and robots.txt:** The `robots.txt` at `https://athome.fandango.com/robots.txt` disallows `/api2`. This `llms.txt` file explicitly documents it as an intended programmatic endpoint - a POST API, not a crawlable URL. ## Error Responses All errors return the same JSON envelope regardless of error type: ```json { "_type": "error", "code": [""], "text": [""], "zoom": [{ "_type": "zoomData", "requestId": [""] }] } ``` Common error codes: - `accessDenied` - unknown or unsupported `_type`, or request rejected by the API - `validationError` - a field value is invalid (e.g. unsupported `offerType` value) The `requestId` inside `zoom` is useful for support escalation. ## Optional: Example Full Workflow To find new Action movies available to buy, sorted by newest first: ```json POST https://apicache.vudu.com/api2/ { "_type": "contentSearch", "genreId": ["101"], "offerType": ["pto"], "count": 10, "offset": 0, "sortBy": "-firstVuduableTime", "type": ["program"], "clientType": "html5app" } ``` To find recently added free (AVOD) content - search a broad set and filter client-side for those with `advertContentDefinitions`: ```json POST https://apicache.vudu.com/api2/ { "_type": "contentSearch", "count": 50, "offset": 0, "sortBy": "-firstVuduableTime", "type": ["program"], "clientType": "html5app", "followup": ["advertContentDefinitions"] } ``` Filter the response: titles where `advertContentDefinitions[0].advertContentDefinition` is a non-empty array are free to watch with ads.