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.
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, newest first.
source is app (logged in the app), import (Letterboxd/CSV import), or api (created via this API).
Query parameters
pageinteger· default 1Page number, 1-indexed.
limitinteger· default 50, max 100· default 50Items per page.
Create 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.
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.
Endpoint errors
media_not_foundReported per item in results[].error, not as a top-level statusWatchlist
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.
Lists
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 elseChangelog & support
- 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.