Your data .md
Public lists & discovery
You read public lists and community activity through the /v3/lists endpoints, without needing to own the list.
GET /v3/lists/community, GET /v3/lists/search, GET /v3/lists/tags, and GET /v3/users/{username}/lists work with no credential at all. GET /v3/lists/{id} and GET /v3/lists/{id}/items accept a credential optionally, it only matters if you happen to own the list you're requesting.
Fetching a list by id#
GET /v3/lists/{id} resolves any list by its bare numeric id and serves public lists to anyone. unlisted and private lists 404 for everyone except their owner (sending a credential unlocks the owner-override). A non-owner request for an unlisted or private id also 404s rather than 403, so existence is never leaked.
curl "https://flicklist.tv/api/v3/lists/4821"const res = await fetch('https://flicklist.tv/api/v3/lists/4821');
const list = await res.json();import requests
r = requests.get("https://flicklist.tv/api/v3/lists/4821")
list_ = r.json(){
"id": 4821,
"name": "Weekend Watchlist",
"slug": "weekend-watchlist",
"privacy": "public",
"is_smart": false,
"item_count": 12,
"likes": 3,
"owner": { "username": "apiretti" }
}
Worked example: read a community list and resolve its items#
A batch or collection tool typically starts from /lists/community or /lists/search, picks a list, then walks its items to resolve real catalog identifiers.
curl "https://flicklist.tv/api/v3/lists/community?sort=popular&limit=5"const res = await fetch('https://flicklist.tv/api/v3/lists/community?sort=popular&limit=5');
const lists = await res.json();
const firstId = lists[0].id;
const itemsRes = await fetch(`https://flicklist.tv/api/v3/lists/${firstId}/items?limit=100`);
const items = await itemsRes.json();
const tmdbIds = items.map((item) => item.ids.tmdb).filter(Boolean);import requests
lists = requests.get(
"https://flicklist.tv/api/v3/lists/community", params={"sort": "popular", "limit": 5}
).json()
first_id = lists[0]["id"]
items = requests.get(
f"https://flicklist.tv/api/v3/lists/{first_id}/items", params={"limit": 100}
).json()
tmdb_ids = [item["ids"]["tmdb"] for item in items if item["ids"]["tmdb"]]Each item's ids block follows the same ids object shape as every other Sync object: fldb is always present, tmdb/imdb/tvdb are nullable. Use whichever key your downstream tool needs, and ignore any key you don't recognize.
GET /v3/lists/{id}/items is paginated (page/limit, X-FlickList-Page* response headers), unlike /v3/sync/lists/{id}/items which always returns a caller's own list in full.
Browsing and searching#
GET /v3/lists/community lists every public, non-empty list, most-recent-first by default. Sort with sort=recent (default), popular (by likes), or biggest (by item count). An unrecognized sort value is a 400, not a silent fallback.
GET /v3/lists/search matches q against list name, description, and tags (case-insensitive substring), public and non-empty lists only. q is required, an empty or whitespace-only value is a 400.
GET /v3/lists/tags returns tags ranked by usage across public lists. It isn't paginated, limit (default 25, max 100) caps the flat result.
[
{ "tag": "cozy", "count": 214 },
{ "tag": "true-crime", "count": 178 }
]
One user's public lists#
GET /v3/users/{username}/lists always returns that user's public-privacy lists only, regardless of any credential you send. A nonexistent username 404s. A real username with no visible public lists returns a 200 with an empty array, confirming the account exists without exposing content.