API

Recommendations (Cached)

Main recommendation endpoint with per-user Supabase caching

GET /api/recommend is the primary recommendations endpoint used by the home feed. It combines watched history, My List-aware filtering, AI generation, and Supabase caching, reducing cost and latency by reusing valid recommendations for 7 days.

Endpoint

GET /api/recommend

Optional query flags:

  • ?refresh=true or ?refresh=1
  • ?getNew=true or ?getNew=1

Auth

Requires Authorization: Bearer <supabase_access_token>.

Cache Strategy

The route stores and reuses recommendation sets in Supabase table recommendations.

FieldPurpose
user_idPer-user cache key
tmdb_idsCached recommendation TMDB IDs
watched_hashHash of watched movies used to validate freshness (My List is applied during generation, not in this cache-key hash)
expires_atCache expiration timestamp

Cache TTL is 7 days.

Behavior by Mode

Default (/api/recommend)

  • If cache is fresh and watched_hash matches current watched history: returns cached recommendations (cached: true)
  • Otherwise generates a new set and stores it (cached: false)

Refresh (/api/recommend?refresh=true)

  • Skips cache reuse
  • Generates a fresh set and overwrites cache

Get New (/api/recommend?getNew=true)

  • Skips cache reuse
  • Loads previous cached recommendations and excludes them from the next AI generation round
  • Generates a new set (still applying My List filtering rules) and stores it

Response Shape

{
  "recommendations": [157336, 603],
  "cached": false,
  "stale": false,
  "regenerationError": null,
  "staleRecommendations": null
}

Successful responses return TMDB IDs only. The frontend hydrates details separately through GET /api/movies/:id.

Rate Limiting

Recommendation generation is limited to 20 requests/day per authenticated user.

Headers returned on generation requests:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset

Error Codes

  • 400 no watched movies found
  • 401 missing or invalid bearer token
  • 409 recommendation request already in progress
  • 429 daily recommendation limit reached
  • 500 Supabase or internal failure
  • 502 AI output could not be parsed, validated, or resolved into enough TMDB matches
  • 503 no provider is configured, or all configured provider/model attempts are unavailable
Copyright © 2026