---
title: "Get movie/TV recommendations"
method: POST
path: "/movies"
---

# Get movie/TV recommendations

`POST /movies`

## Request

- Base URL: `https://localselections.com/api/v1`
- URL: `https://localselections.com/api/v1/movies`
- Auth: API key in header `X-API-Key`

Stage 196: real trending or genre-filtered movie/TV titles — the same TMDB-first, OMDb-fallback logic (screenPicks.ts) /spin and /bracket's movie category already use. Omit `genre` for what's currently trending, or pass one to filter. `tmdbUnavailable` is true when TMDB itself is down and the (dormant-by-default) OMDb movie-only fallback served the results instead. Every title returned here is TMDB's own catalog data (TMDB's trending/genre endpoints include real TV titles, not just movies) — this endpoint never returns TVmaze-sourced titles, which this app only ever adds client-side in the browser (Stage 168). Each title carries a `detailUrl` to a real, permanent LocalSelections page when it's TMDB-sourced with enough real overview text to index (null otherwise — see the TrendingTitle schema). Requires the `movies` scope. Costs 1 unit of the key's rate-limit budget per call. Stage 198: a free-tier key is also separately capped at 150 calls/day to this endpoint specifically (see the 429 response) — commercial use is exempt.

## Request body

- object
  - `genre` string: Optional genre filter, e.g. "Comedy", "Action", "Drama". Omit for trending.

## Response `200`

Trending or genre-filtered movie/TV titles.

- object
  - `titles` object[], required
    - `id` string, required
    - `title` string, required
    - `mediaType` 'movie' | 'tv', required
    - `overview` string, nullable
    - `posterUrl` string, uri, nullable
    - `rating` number, nullable
    - `releaseDate` string, nullable
    - `tmdbUrl` string, uri, required: Link to the title at its source provider — TMDB, or IMDb when a fallback served it (see `provider`).
    - `provider` 'tmdb' | 'omdb' | 'tvmaze': Which provider produced this title. Absent means TMDB.
    - `detailUrl` string, uri, nullable: Stage 196: a real, permanent LocalSelections detail page for this exact title, reusing that page's own indexability rule (a TMDB-provider title with enough real overview text). Null for a non-TMDB-provider title (no local page exists) or one without enough overview text to index. Only present on /movies (not /spin or /bracket's narrowed/candidate titles, which predate this field).
  - `tmdbUnavailable` boolean, required

## Other responses

- `400`: The request body failed validation.
- `401`: Missing or invalid API key.
- `403`: The API key does not carry the scope this endpoint requires (see the "Requires the ... scope" note on each path, or call GET /introspect to see a key's real granted scopes).
- `429`: Rate limit exceeded for this API key. The budget is 30 units/60s for keys owned by an unsubscribed account, 120 units/60s for a subscribed account's keys (Stage 60) — shared across every endpoint, but each endpoint spends a different number of units per call rather than always 1 (Stage 104): search/groups_host/groups_join/places/movies cost 1, surprise_me/events cost 2, spin costs 3, bracket costs 4. Call GET /introspect to see a key's real remaining budget before it runs out. Separately, these three endpoints also enforce their own free-tier-only daily ceiling per key (`error: "daily_limit_exceeded"`) — resets at UTC midnight, and does not apply to a commercial-tier key. Contact support@localselections.com for commercial/high-volume access.
- `502`: An upstream data source failed or returned nothing usable.

---

[API](https://skmtc.dev/localselections/apis/localselections-public-api.md) · [All operations](https://skmtc.dev/localselections/apis/localselections-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/localselections/apis/localselections-public-api/revisions/a24e9598add4?raw)
