API
Watched and My List APIs
Authenticated APIs for the user's watched movies and saved list
/api/watched and /api/mylist both use Supabase and the shared movies table. They expose hydrated movie cards on reads, but writes only need a TMDB ID.
Auth
- Requires
Authorization: Bearer <supabase_access_token> - User is resolved server-side from the token
- Requests without a valid token return
401 Unauthorized
Current Tables
/api/watched
- Storage table:
user_watched_movies - Shape: one row per
(user_id, tmdb_id) - Read path: joins watched IDs to
moviesso the client receives hydrated cards
/api/mylist
- Storage table:
user_my_list - Shape: one row per user with
tmdb_ids integer[] - Write path: uses RPC functions
append_my_listandremove_my_list - Read path: resolves
tmdb_idsthroughmovies
Accepted Write Payload
Both routes accept either of these request bodies:
{
"tmdbId": 550
}
{
"movie": {
"tmdbId": 550
}
}
tmdbId must be a positive integer.
GET /api/watched
Returns the current user's watched list.
{
"success": true,
"movies": [
{
"tmdbId": 550,
"title": "Fight Club",
"year": 1999,
"posterPath": "/path.jpg",
"genres": ["Drama"],
"runtime": 139
}
]
}
If a movie exists in the relationship table but has not been hydrated in movies yet, the route returns a fallback item with empty display fields and the correct tmdbId.
POST /api/watched
Adds a watched row if it is not already present.
{
"tmdbId": 550
}
{
"success": true,
"watchedCount": null
}
DELETE /api/watched
Removes a movie from the watched list by tmdbId.
{
"tmdbId": 550
}
{
"success": true,
"watchedCount": null
}
GET /api/mylist
Returns the current user's saved list as hydrated movie cards.
{
"success": true,
"movies": [
{
"tmdbId": 157336,
"title": "Interstellar",
"year": 2014,
"posterPath": "/path.jpg",
"genres": ["Adventure", "Drama"],
"runtime": 169
}
]
}
POST /api/mylist
Adds a TMDB ID through the append_my_list RPC function.
{
"success": true,
"myListCount": null
}
DELETE /api/mylist
Removes a TMDB ID through the remove_my_list RPC function.
{
"success": true,
"myListCount": null
}
Error Codes
400invalid payload or invalidtmdbId401missing or invalid bearer token409movie is already in watched list when adding to/api/mylist405unsupported method500Supabase query, delete, upsert, or RPC failure