OpenWatchlist is a small, human-readable markdown dialect for tracking the movies and shows you watch. One file, no database, no account required — readable by a person, parseable by a machine.
Reading this as an AI? /llms.txt is the condensed spec — the whole format in one read.
# My Watchlist
> the July queue — shows first
Oppenheimer (2023) 8 +
Severance (2022) 4.5 * @s2e6 #apple-tv | so creepy
Dune: Part Two (2024) !!!
Children of Men (2006) 5 * ^ +2025-12-18 #sci-fi | all-time favorite
Mad Men (2007) 5/5 * +2019-05-20 @s3e4 #rewatch
The Wheel of Time @s1e3 ~ | not for me — three episodes in
## From John
Heat (1995) #crime
Blow Out (1981) +2026-02-11
## Rom-coms
- [x] Notting Hill (1999) 4/5
- Set It Up (2018)
Services: Netflix | Apple TV+
Every line carries its own state. A bare title is queued; !!! bumps it to watch-next. @s2e6 means mid-watch; + means watched — dated if you remember, alone if you don't; a trailing 8
is a rating (out of 10; 5 and below reads out of 5);
^ marks a masterpiece; Mad Men's +2019 … @s3e4 is a rewatch in progress; and the ~ on The Wheel of Time sets it aside without forgetting it was three episodes in. The > line is a comment — a note to yourself, never a title.
## With John is a shelf — organization you invent, never watch status.
Title |
the only required thing |
(1995) |
year — identity for remakes; premiere year for TV |
4.5/5 |
your rating — and it can live alone: a trailing plain number is a rating (0–5 reads out of 5, above 5 reads out of 10), and a decimal like 4.5 works anywhere. A number that ends a title stays put when you add the year (Ocean's 8 (2018)). Write
5/10 explicitly when you mean five of ten
|
* |
favorite — a flag, independent of rating and status |
^ |
masterpiece — a higher, narrower honor than favorite; * ^ together is fine |
! !! !!! |
priority — eventually, soon, watch next. Three levels max |
_ |
explicitly unwatched — a bare line is already unwatched; _ says so on the record |
@s2e6 |
where you are — series, or @1:20:00 for films. Lives alone too: a bare @ just means “watching, somewhere” |
+2026-07-01 |
watched, when — repeat for rewatches. Also lives alone: a bare + means “watched, don't remember when” |
~ |
archived — a flag, not a status: + ~ is watched-then-retired, @s1e3 ~ is dropped with your place kept |
#tag |
anything you like — lowercase kebab-case (#with-john) |
| note |
free text to end of line |
## Shelf |
your own organization — With John, Rom-coms, anything. Shelves never mean watch status; the marks above do |
> comment |
a whole line that's a note, not a title — > for prose, // to switch a line off, --, or /* … */ across lines. Never inline; always preserved |
Services: A | B |
your subscriptions, one line, anywhere in the file (conventionally last). | alone delimits, so Apple TV+ survives; the old ## Streaming Services shelf still reads |
Every construct is something you'd naturally type on a phone keyboard. If a feature needs documentation to write, it doesn't belong in the format.
There is no canonical copy anywhere else. Tools read what you write and write what you can read — nothing lives behind an API you don't control.
Unknown sections and unparseable lines are preserved exactly as written. A watchlist can share a file with grocery notes and survive.
Every watchlist app eventually asks you to trust it with your history — what you've watched, what you loved, what you're mid-season on. When the app changes, shuts down, or starts charging, that history is usually stuck. OpenWatchlist inverts that: the file is portable by construction. Any app that speaks the format can open your list; you can also just open it in a text editor and read it yourself, forever.
Read the full spec or paste your own list into the playground to see it parsed live, right in your browser — nothing you paste is sent anywhere.
Adding OpenWatchlist to a tool takes minutes. The specification is short and normative; the reference parser (parser.js) is a zero-dependency JavaScript module you can drop in or port — it exports parseDocument(),
parseEntryLine(), resolveStatus(), and entryToCanonical(). Verify your output against it in the playground.
Automated agents and LLMs: read /llms.txt first — it is the official condensed edition of the specification (the complete format in one read, with direct links to the spec and parser), maintained in lockstep with
/spec.html and updated with every version.