Flick API · Beta
API Reference
Read your own Flick data — profile, reviews, watchlist, lists — and write reviews to your own account, over plain JSON. Every endpoint below has a built-in Try it console — paste a key once and send live requests right from the docs.
This API is in beta.
Stored only in this browser tab and sent only to http://localhost:8080. No key yet? Create one.
Introduction
The Flick API is scoped to yourdata: an API key acts on behalf of the account that created it. There is no OAuth and no access to other users' accounts — keys read and write the key owner's data only.
All endpoints live under https://flickmovies.com/api/beta and accept and return JSON.
OpenAPI is the industry-standard format for describing a REST API in a single machine-readable file — every path, parameter, and response shape. We publish ours at /api/beta/openapi.json. Point a tool at it to generate a typed client in your language (openapi-generator, Speakeasy, etc.), import it into Postman or Insomnia, or feed it to an AI assistant — no hand-copying of endpoints. The OpenAPI link in the top nav opens /api/beta/docs, a Swagger UI rendered from that same schema where you can browse and try endpoints against the live server. (For most things, the inline Try it consoles below are quicker.)
API access requires a Flick Pro subscription. By using the API you agree to the API Terms of Service.
https://flickmovies.com/api/betaAuthentication
Create an API key on the API keys page — sign in with the same email or phone you use in the Flick app. Keys look like flick_sk_… and the full key is shown once, at creation; store it somewhere safe.
Pass the key on every request, either as a bearer token or an X-API-Key header. You can hold up to 5 active keys and revoke any of them at any time from the same page — revocation takes effect within about 30 seconds.
Keys are personal and non-transferable. Don't embed them in client-side code or public repos — anyone with your key can read and write your Flick data. If a key leaks, revoke it immediately.
curl https://flickmovies.com/api/beta/me \
-H "Authorization: Bearer flick_sk_YOUR_KEY"
# or
curl https://flickmovies.com/api/beta/me \
-H "X-API-Key: flick_sk_YOUR_KEY"Rate limits
Default limits are 60 requests/minute and 5,000 requests/day per key (subject to change during beta — reach out on Discord if you need more). Daily windows reset at UTC midnight.
Exceeding a limit returns 429 with a Retry-After header (seconds). Back off and retry after that long.
X-RateLimit-LimitRequests allowed per minuteX-RateLimit-RemainingRemaining in the current minute windowX-RateLimit-ResetUnix time when the minute window resetsX-RateLimit-Limit-DayRequests allowed per day (UTC days)X-RateLimit-Remaining-DayRemaining in the current UTC dayRetry-AfterOn 429 only — seconds to wait before retryingX-RateLimit-Limit: 60
X-RateLimit-Remaining: 41
X-RateLimit-Reset: 1781200560
X-RateLimit-Limit-Day: 5000
X-RateLimit-Remaining-Day: 4817{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded for the minute window. Retry after 12 seconds."
}
}Errors
Every error — auth, validation, rate limiting, server faults — uses the same envelope: an error object with a stable machine-readable code and a human-readable message. Match on the code, not the message.
invalid_requestMalformed body or query paramsinvalid_api_keyMissing, malformed, or unknown keyapi_key_revokedKey was revokedpro_requiredAccount no longer has Pronot_foundResource doesn't exist or isn't yoursmedia_not_foundNo such title on TMDBrate_limitedRate limit exceeded — back off per Retry-Afterinternal_errorSomething broke on our sideapi_disabledAPI temporarily disabled (check Discord){
"error": {
"code": "media_not_found",
"message": "No movie found on TMDB for tmdb_id 999999999."
}
}Pagination & media
List endpoints paginate with ?page=1&limit=50 (limit max 100) and return a { data, page, limit, total, has_more } envelope. Pagination style may change to cursors before GA.
Titles are identified by their TMDB id plus a media_type of movie, tv, tv_season, or tv_episode. For seasons and episodes, pass the show's TMDB id along with season_number (and episode_number for episodes).
Everywhere a title appears in a response it uses the same media object. The season_number, episode_number, and show_title fields are present only for seasons and episodes.
{
"data": [ … ],
"page": 1,
"limit": 50,
"total": 412,
"has_more": true
}{
"tmdb_id": "1396",
"type": "tv_episode",
"title": "Pilot",
"year": 2008,
"poster_url": "https://image.tmdb.org/t/p/w500/…",
"season_number": 1,
"episode_number": 1,
"show_title": "Breaking Bad"
}Profile
Get your profile
/api/beta/meThe profile of the account that owns the API key.
Update your profile
/api/beta/meUpdate your own display name and bio.
Only the fields you send change; omitted fields are left as-is.
Body parameters
display_namestring· max 120 charsYour display name.
biostring· max 2,000 charsYour profile bio.
List users you follow
/api/beta/me/followingThe users you follow, most recently followed first. Each user_id here is exactly what watched_with accepts (you can also pass the @username).
This is the discovery endpoint for co-watcher tagging: list who you follow, then pass their user_id (or @username) to watched_with on a review write.
Query parameters
pageinteger· default 1Page number, 1-indexed.
limitinteger· default 50, max 100· default 50Items per page.
Media
Resolve a title to a TMDB id
/api/beta/resolveBest-effort lookup from loose metadata you already have — a title, optionally a year and type — to the TMDB id and media_type the rest of the API expects.
Handy before a review write: most catalogs and spreadsheets carry a title and year, not a TMDB id. Resolve once, then POST to /me/reviews with the result.
This is a fuzzy match, not an authority. match is the strongest candidate (or null when nothing plausible turns up); candidates holds up to five ranked alternatives. Each carries a score (0–1) and a confidence of high, medium, or low — verify before trusting a low.
Only movie and tv are resolvable here. For a specific season or episode, resolve the show, then pass season_number / episode_number to the review endpoints.
Query parameters
titlestringrequired· 1–200 charsThe title to search for.
yearintegerRelease (or first-air) year. Narrows same-named titles.
media_typestringNarrow to movie or tv. Omit to search both.
Reviews
List your reviews
/api/beta/me/reviewsYour reviews. Defaults to newest first; every filter below is optional and they combine (AND).
source is app (logged in the app), import (Letterboxd/CSV import), or api (created via this API).
is_log is true for a plain watch log — no rating, no review text, no photos; the row only records that you watched (e.g. a quick episode mark in the app). Anything carrying an opinion is is_log: false.
watch_context ("how you watched") is an object or null; watched_with is a list of user ids.
Pass tmdb_id together with media_type to fetch your review(s) of one specific title.
Query parameters
media_typestringFilter to one type: movie, tv, tv_season, or tv_episode.
tmdb_idstringOnly your review(s) of this title. Requires media_type.
tagstringOnly reviews carrying this exact tag.
min_ratingnumberLowest rating to include.
max_ratingnumberHighest rating to include.
ratedbooleantrue = only rated reviews; false = only unrated (text-only reviews and watch logs). Omit for both.
sortstringSort field: created_at (default), watched_date, or rating.
orderstringdesc (default) or asc.
pageinteger· default 1Page number, 1-indexed.
limitinteger· default 50, max 100· default 50Items per page.
Get one of your reviews
/api/beta/me/reviews/{review_id}Fetch a single review you own by id.
Path parameters
review_idstringrequiredThe review id (from GET /me/reviews).
Endpoint errors
not_foundThe review doesn't exist or isn't yoursCreate a review
/api/beta/me/reviewsAdd one review to your account.
Re-POSTing an identical review (same title, rating, text, watched date) is deduplicated and returns 200 with deduplicated: true instead of creating a copy.
Reviews created via the API are tagged source: "api" and show up in the app like imported reviews. Rewatch numbering and rating-tier ordering normalize the next time you edit in the app — a known beta limitation.
Body parameters
tmdb_idstringrequiredThe TMDB id of the title. For seasons and episodes, pass the show’s TMDB id.
media_typeenumrequiredWhat kind of title this is.
movietvtv_seasontv_episodeseason_numberintegerrequired if media_type is tv_season or tv_episodeSeason being reviewed.
episode_numberintegerrequired if media_type is tv_episodeEpisode being reviewed.
ratingnumber· 0–10Your rating. Omit for an unrated log.
reviewstring· max 10,000 charsReview text.
watched_datedate· YYYY-MM-DDWhen you watched it. Not in the future.
tagsarray of strings· max 20 tags, 64 chars eachTags to attach.
watched_witharray of strings· max 50People you watched with. Each entry is a user id (from GET /me/following) or an @username. Each must be someone you follow — unknown entries are rejected.
watch_contextobjectHow you watched it. A sparse object — send only what you know. Keys: source (theater/home/onTheGo), cinema_type, format, theater, auditorium, showtime, seat, medium (streaming/physical/broadcast/download), service, edition, channel, place, device.
Endpoint errors
media_not_foundThe tmdb_id / media_type combination doesn’t exist on TMDBCreate reviews in batch
/api/beta/me/reviews/batchAdd up to 50 reviews in one request.
Items are processed independently; the response reports per-item outcomes in input order.
Duplicates — against your existing reviews or within the batch — are skipped and counted in deduplicated_count.
There is no all-or-nothing rollback: check each item’s created / error instead of the HTTP status.
Body parameters
reviewsarray of objectsrequired· 1–50 itemsThe reviews to create.
each item
tmdb_idstringrequiredThe TMDB id of the title. For seasons and episodes, pass the show’s TMDB id.
media_typeenumrequiredWhat kind of title this is.
movietvtv_seasontv_episodeseason_numberintegerrequired if media_type is tv_season or tv_episodeSeason being reviewed.
episode_numberintegerrequired if media_type is tv_episodeEpisode being reviewed.
ratingnumber· 0–10Your rating. Omit for an unrated log.
reviewstring· max 10,000 charsReview text.
watched_datedate· YYYY-MM-DDWhen you watched it. Not in the future.
tagsarray of strings· max 20 tags, 64 chars eachTags to attach.
watched_witharray of strings· max 50People you watched with. Each entry is a user id (from GET /me/following) or an @username. Each must be someone you follow — unknown entries are rejected.
watch_contextobjectHow you watched it. A sparse object — send only what you know. Keys: source (theater/home/onTheGo), cinema_type, format, theater, auditorium, showtime, seat, medium (streaming/physical/broadcast/download), service, edition, channel, place, device.
Endpoint errors
media_not_foundReported per item in results[].error, not as a top-level statusUpdate a review
/api/beta/me/reviews/{review_id}Update one of your reviews. The title is immutable.
Only the fields you send change. Send an explicit null to clear rating, tags, watch_context, or watched_with.
Editing a rating renormalizes the rating-tier ordering automatically.
Path parameters
review_idstringrequiredThe review id to update.
Body parameters
ratingnumber· 0–10New rating.
reviewstring· max 10,000 charsNew review text.
watched_datedate· YYYY-MM-DDWhen you watched it.
tagsarray of strings· max 20 tagsReplacement tag list.
watched_witharray of strings· max 50Replacement co-watchers — user ids or @usernames, each someone you follow.
watch_contextobjectHow you watched it. A sparse object — send only what you know. Keys: source (theater/home/onTheGo), cinema_type, format, theater, auditorium, showtime, seat, medium (streaming/physical/broadcast/download), service, edition, channel, place, device.
Endpoint errors
not_foundThe review doesn't exist or isn't yoursDelete a review
/api/beta/me/reviews/{review_id}Permanently delete one of your reviews.
Path parameters
review_idstringrequiredThe review id to delete.
Endpoint errors
not_foundThe review doesn't exist or isn't yoursAdd/remove co-watchers across reviews
/api/beta/me/reviews/bulk/watched-withAdd and/or remove "watched with" co-watchers across many reviews.
Entries in add and remove are user ids or @usernames. Everyone in add must be someone you follow — unknown entries reject the request. remove is not follow-gated (you can untag anyone).
Body parameters
review_idsarray of stringsrequired· 1–100 idsThe review ids to edit.
addarray of stringsCo-watchers to add — user ids or @usernames you follow.
removearray of stringsCo-watchers to remove — user ids or @usernames.
Set watch context across reviews
/api/beta/me/reviews/bulk/watch-contextOverwrite "how you watched" on many reviews at once.
Send watch_context: null to clear it on all targeted reviews.
Body parameters
review_idsarray of stringsrequired· 1–100 idsThe review ids to edit.
watch_contextobjectHow you watched it. A sparse object — send only what you know. Keys: source (theater/home/onTheGo), cinema_type, format, theater, auditorium, showtime, seat, medium (streaming/physical/broadcast/download), service, edition, channel, place, device.
Watchlist
List your watchlist
/api/beta/me/watchlistYour watchlist, most recently added first.
Query parameters
pageinteger· default 1Page number, 1-indexed.
limitinteger· default 50, max 100· default 50Items per page.
Add to your watchlist
/api/beta/me/watchlistAdd a title to your watchlist.
Re-adding a title already on your watchlist is a no-op.
Body parameters
tmdb_idstringrequiredThe TMDB id.
media_typeenumrequiredWhat kind of title.
movietvtv_seasontv_episodeseason_numberintegerrequired if media_type is tv_season or tv_episodeSeason.
episode_numberintegerrequired if media_type is tv_episodeEpisode.
Endpoint errors
media_not_foundNo such title on TMDBAdd to your watchlist in bulk
/api/beta/me/watchlist/batchAdd up to 50 titles to your watchlist in one request.
Items are processed independently — check each added / error in results.
Body parameters
itemsarray of objectsrequired· 1–50 itemsThe titles to add.
each item
tmdb_idstringrequiredThe TMDB id.
media_typeenumrequiredWhat kind of title.
movietvtv_seasontv_episodeseason_numberintegerrequired if media_type is tv_season or tv_episodeSeason.
episode_numberintegerrequired if media_type is tv_episodeEpisode.
Remove from your watchlist
/api/beta/me/watchlist/{tmdb_id}Remove a title from your watchlist.
Path parameters
tmdb_idstringrequiredThe TMDB id to remove.
Query parameters
media_typeenumrequiredThe media type (tmdb_id alone is ambiguous across movie/tv).
movietvtv_seasontv_episodeseason_numberintegerSeason (for tv_season / tv_episode).
episode_numberintegerEpisode (for tv_episode).
Endpoint errors
not_foundThat title isn't on your watchlistmedia_not_foundNo such title on TMDBLists
List your lists
/api/beta/me/listsCustom lists you own. The built-in watchlist is excluded — use /me/watchlist for that.
List items in a list
/api/beta/me/lists/{list_id}/itemsItems in one of your lists. Ranked lists come back in rank order.
Returns 404 not_found for lists you don’t own.
Path parameters
list_idstringrequiredA list id from GET /me/lists.
Query parameters
pageinteger· default 1Page number, 1-indexed.
limitinteger· default 50, max 100· default 50Items per page.
Endpoint errors
not_foundThe list doesn’t exist or belongs to someone elseCreate a list
/api/beta/me/listsCreate a new custom list.
Body parameters
titlestringrequired· 1–200 charsList title.
descriptionstring· max 2,000 charsList description.
is_rankedboolean· default falseWhether the list is ranked (ordered).
Update a list
/api/beta/me/lists/{list_id}Rename a list, change its description, or toggle ranking.
Built-in lists (like the watchlist) can’t be edited.
Path parameters
list_idstringrequiredThe list id.
Body parameters
titlestring· 1–200 charsNew title.
descriptionstring· max 2,000 charsNew description.
is_rankedbooleanWhether the list is ranked.
Endpoint errors
not_foundThe list doesn't exist or isn't yoursDelete a list
/api/beta/me/lists/{list_id}Permanently delete a custom list and its items.
Built-in lists (like the watchlist) can’t be deleted.
Path parameters
list_idstringrequiredThe list id to delete.
Endpoint errors
not_foundThe list doesn't exist or isn't yoursAdd a title to a list
/api/beta/me/lists/{list_id}/itemsAdd a title to one of your lists.
Path parameters
list_idstringrequiredThe list id.
Body parameters
tmdb_idstringrequiredThe TMDB id.
media_typeenumrequiredWhat kind of title.
movietvtv_seasontv_episodeseason_numberintegerrequired if media_type is tv_season or tv_episodeSeason.
episode_numberintegerrequired if media_type is tv_episodeEpisode.
notesstring· max 2,000 charsPer-item notes.
positionenum· default endWhere to insert in a ranked list.
startendEndpoint errors
not_foundThe list doesn't exist or isn't yoursmedia_not_foundNo such title on TMDBAdd titles to a list in bulk
/api/beta/me/lists/{list_id}/items/batchAdd up to 50 titles to a list in one request.
Items are processed independently — check each added / error in results.
Path parameters
list_idstringrequiredThe list id.
Body parameters
itemsarray of objectsrequired· 1–50 itemsThe titles to add.
each item
tmdb_idstringrequiredThe TMDB id.
media_typeenumrequiredWhat kind of title.
movietvtv_seasontv_episodeseason_numberintegerrequired if media_type is tv_season or tv_episodeSeason.
episode_numberintegerrequired if media_type is tv_episodeEpisode.
notesstringPer-item notes.
Endpoint errors
not_foundThe list doesn't exist or isn't yoursUpdate a list item
/api/beta/me/lists/{list_id}/items/{tmdb_id}Update an item’s notes or move it within a ranked list.
position is a 0-based target index used to reorder ranked lists.
Path parameters
list_idstringrequiredThe list id.
tmdb_idstringrequiredThe item’s TMDB id.
Query parameters
media_typeenumrequiredThe item’s media type.
movietvtv_seasontv_episodeseason_numberintegerSeason (for tv_season / tv_episode).
episode_numberintegerEpisode (for tv_episode).
Body parameters
notesstring· max 2,000 charsNew per-item notes.
positioninteger0-based index to move the item to (ranked lists).
Endpoint errors
not_foundThe list or item doesn't exist or isn't yoursmedia_not_foundNo such title on TMDBRemove a title from a list
/api/beta/me/lists/{list_id}/items/{tmdb_id}Remove a title from one of your lists.
Path parameters
list_idstringrequiredThe list id.
tmdb_idstringrequiredThe item’s TMDB id.
Query parameters
media_typeenumrequiredThe item’s media type.
movietvtv_seasontv_episodeseason_numberintegerSeason (for tv_season / tv_episode).
episode_numberintegerEpisode (for tv_episode).
Endpoint errors
not_foundThe list or item doesn't exist or isn't yoursmedia_not_foundNo such title on TMDBWatching
List shows you’re watching
/api/beta/me/watchingShows with in-progress episode/season activity, most recent first.
Read-only in beta. episode_count / season_count are the logged episodes/seasons since your last reset.
Changelog & support
- 2026-07 — Review objects now include
is_log:truefor plain watch logs (no rating, review text, or photos), so they're distinguishable from deliberate blank reviews. Additive — existing fields and theratedfilter's behavior are unchanged. - 2026-06 — Initial beta: own-data reads (profile, reviews, watchlist, lists) and review writes (single + batch).
This beta exists to learn what you want to build. Feature requests, bug reports, and questions all go to our Discord or hello@flickmovies.com.