v1.4

Your watchlist is a text file.

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.

The whole grammar

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

Human-first

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.

Your file is the database

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.

Never destroy what's not understood

Unknown sections and unparseable lines are preserved exactly as written. A watchlist can share a file with grocery notes and survive.

Why a format, not an app

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.

For implementers & AI agents

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.