API
Movie Details & Caching
Fetch enriched movie metadata with Supabase-backed caching
The Movie Details endpoint fetches enriched metadata for a single movie by its TMDB ID. Results are cached server-side in the Supabase movies table for about 3 months to avoid redundant TMDB API calls.
Endpoint
GET /api/movies/:id
How It Works
- Client requests
/api/movies/:idwith a TMDB movie ID - Server checks
moviesfor a cached row - Cache hit - returns the cached record immediately, no TMDB call made
- Cache miss or stale/incomplete row - fetches from TMDB (
/movie/:id?append_to_response=credits,videos), upserts the movie row in Supabase, and returns the normalized response
Example Usage
const response = await fetch('/api/movies/550')
const movie = await response.json()
Path Parameter
| Parameter | Type | Description |
|---|---|---|
id | number | TMDB movie ID (positive integer) |
Returns 400 if the ID is missing or not a positive integer.
Response Format
{
"id": 550,
"title": "Fight Club",
"poster": "https://image.tmdb.org/t/p/w500/path/to/poster.jpg",
"rating": 8.4,
"year": 1999,
"duration": "2h 19m",
"runtime": 139,
"genres": ["Drama", "Thriller"],
"actors": ["Brad Pitt", "Edward Norton", "Helena Bonham Carter", "Meat Loaf", "Zach Grenier"],
"directors": ["David Fincher"],
"description": "A ticking-time-bomb insomniac...",
"trailer": "https://www.youtube.com/watch?v=SUXWAEX2jlg"
}
| Field | Type | Notes |
|---|---|---|
id | number | TMDB ID |
title | string | Movie title |
poster | string | Full image URL (w500). Empty string if no poster |
rating | number | vote_average rounded to 1 decimal place |
year | number | Release year parsed from release_date |
duration | string | Formatted as 2h 19m. "N/A" if runtime is unknown |
runtime | number | Raw runtime in minutes, or null when unavailable |
genres | string[] | Genre names |
actors | string[] | Top 5 cast members |
directors | string[] | Director names |
description | string | Movie overview |
trailer | string | YouTube link or null |
Caching Details
| Property | Value |
|---|---|
| Cache store | Supabase movies table |
| TTL | ~3 months (90 days) |
| Cache key | tmdb_id |
| Trailer selection | Most recent official YouTube trailer (type = "Trailer", official = true) |
Cache freshness is checked via the cached_at timestamp column. A record is also refreshed when required detail fields are still empty.
Error Handling
| Status | Cause |
|---|---|
400 | id is missing or not a positive integer |
404 | TMDB returned no movie for that ID |
500 | TMDB API or Supabase failure |