OpenWatchlist specification
OpenWatchlist is a plain-text format for tracking the films and series you watch. A valid file is readable in any text editor, diffable in any version control system, and useful with no software at all. Apps are viewers and editors over the file — never owners of it.
# My Watchlist
- Dune: Part Two (2024)
- Severance (2022) 4.5/5 * @s2e6 #apple-tv | so creepy
- Aftersun (2022) 4.5/5 * +2026-01-15 | quietly devastating
- The Flash (2023) 2/10 ~
## With John
- Heat (1995) #crime
- Mad Men (2007) 5/5 +
## Streaming Services
- Netflix
- Apple TV+
Four entries at the top: one queued, one being watched (mid s2e6), one watched with a date, one set aside with ~ (still unwatched — archiving hides it, it doesn't rewrite history). Each line carries its own state. Below them, a shelf called “With John” groups two more
titles. The shelf name is organization, nothing else; the + on Mad Men is what says it's been watched.
Design principles
- Humans first. Every construct must be writable on a phone keyboard and understandable without documentation. If a feature needs syntax a person wouldn't naturally type, it doesn't go in.
- The line is the record. Everything true about a title — status, rating, history — lives on its own line and travels with it. Moving a line never changes its meaning.
- The file is the database. There is no canonical copy elsewhere. Tools must read what humans write and write what humans can read.
- Never destroy what you don't understand. Unknown shelves and unparseable lines are preserved verbatim by conforming writers.
- Order is data. A user's ordering of entries is meaningful (a curated queue, a ranking) and conforming writers preserve it except for user-initiated moves.
- Lenient in, canonical out. Parsers accept entry tokens in any order and several equivalent spellings; writers emit one canonical form.
The entry line
Each title is one line: a bulleted - Title or a plain Title, followed by optional tokens, in this canonical order:
Title (Year) rating favorite masterpiece priority status/progress watch-date archive #tags | notes
Everything except the title is optional. A parser accepts the tokens in any order after the title; a writer always emits the canonical order above. In marks:
Title (YYYY) 4.5 * ^ !!! @s2e6 +2026-01-15 ~ #tags | note
Watch status
A title's watch status is carried on its line — by the marks it does or doesn't have. Only these four determine it:
| Marks on the line | Status |
|---|---|
| nothing | unwatched — a bare title is a queued title |
_ |
unwatched, explicitly — “not watched yet,” on the record |
@ (progress) |
watching — you're somewhere in it |
+ (watched) |
watched — you finished it, optionally dated |
When watch marks combine, the current state wins:
@ > + > _ > nothing. So +2024-11-03 @s3e4 reads as watching — a rewatch in progress, with its history intact.
Everything else — archive ~, favorite *, masterpiece ^, priority ! — is a separate metadata flag, never a watch status.
Archived is a flag, not a status
~ means set aside — dropped, retired, hidden from the active list. It is orthogonal to watch status: archiving something never erases whether you watched it. Every combination is meaningful:
Heat (1995) ~ archived · unwatched (never got to it)
The Irishman (2019) @1:20:00 ~ archived · watching (gave up an hour in, place kept)
Game of Thrones (2011) + ~ archived · watched (finished, then retired)
A conforming tool reports both facts — “archived” and the underlying watch status — and un-archiving (removing the ~) simply returns the line to its active life with everything intact.
Tokens
| Token | Form | Meaning |
|---|---|---|
| Year | (YYYY) |
Disambiguates remakes — Suspiria (1977) vs (2018). Premiere year for TV |
| Rating | n/5, n/10, or bare n |
Personal rating. Plain numbers 0–5 read out of 5, above 5 read out of 10; explicit forms (4.5/5, 8/10) are always allowed and preferred when clarity matters (see below) |
| Favorite | * |
Flag — independent of rating and status |
| Masterpiece | ^ |
Flag — a higher, narrower indication than favorite: elite, all-time-level work. A title can be * ^ (both), or ^ without * (a masterpiece that isn't a comfort favorite) |
| Priority | ! !! !!! |
Flag — eventually / soon / watch next. Three levels; !!! is the maximum |
| Unwatched | _ |
Status — explicitly not watched yet (a bare line is already unwatched; _ puts it on the record) |
| Progress | @, @s2e6, @s2, @1:20:00, @80m |
Status — where you are: season/episode or a movie timecode; bare @ means watching, position unrecorded. Because progress lives on the line, moving an entry anywhere never loses your place |
| Watched | + or +YYYY-MM-DD |
Status — watched, optionally dated (ISO). Repeat the token for rewatches |
| Archived | ~ |
Flag — set aside, orthogonal to watch status: an archived line keeps its unwatched/watching/watched state (see Archived) |
| Tag | #tag |
Freeform; letters, numbers, -, _. Lowercase kebab-case recommended |
| Note | | text |
Free text to end of line; always last |
Ratings: plain numbers
Ratings are plain numbers: 0–5 defaults to out of 5, greater than 5 defaults to out of 10. A plain 5 means 5/5 — if you mean five out of ten, write 5/10. Explicit forms (4.5/5, 8/10, 2/10) are always allowed and
preferred when clarity matters.
A trailing number is a rating by default. The one exception keeps titles that end in a number intact: a number sitting directly before the year is part of the title — which is exactly where it belongs. Add the year and the title is safe; leave it off and the number reads as a score.
Oppenheimer (2023) 8 rating 8/10 (trailing number → rating)
Heat (1995) 4 rating 4/5 (0–5 reads out of 5)
Ocean's 8 (2018) title "Ocean's 8", no rating (number before the year)
District 9 (2009) title "District 9", no rating
Ocean's 11 title "Ocean's 11" (numbers above 10 are never a rating)
Ocean's 8 title "Ocean's", rating 8/10 (no year → the 8 is read as a score)
Two guardrails make this safe in practice: a plain integer above 10 is never a rating (so Ocean's 11 and Catch 22 stay titles), and a bare decimal like 4.5 is always a rating anywhere — essentially nothing is titled a decimal. When a title ends
in a number, just include its year.
Bracket marks
The same status marks may be written at the start of a line in task-list brackets — handy when you want your list to render as checkboxes on GitHub or a markdown notes application like Obsidian, or when a leading mark reads better than a trailing one:
- [ ] Heat (1995) #crime unwatched
- [@] Severance (2022) @s2e6 watching
- [x] Mad Men (2007) 5/5 watched
- [ ] The Flash (2023) 2/10 unwatched
- [+] Game of Thrones (2011) ~ watched · archived
- [_] Blow Out (1981) unwatched (explicit)
[ ] and [x] are standard GitHub-Flavored Markdown and render as real checkboxes; [_], [@], and [+] extend the same bracket notation and display as readable text elsewhere. A bracket mark and an inline mark are the same channel:
[@] means what @ means, [+] means what + means, combine it with watch marks to archive something watched or in progress. A line's state is resolved from all its marks together under Watch status: bracket and inline marks should usually
match, and when they conflict the same precedence applies (@ beats +, and ~ is the separate archived flag). Writers preserve whichever spelling (inline or bracket) a line already uses.
Preamble
An OpenWatchlist file is UTF-8 Markdown. Anything before the first
## heading is the preamble — typically an # H1 title, free notes, and (very commonly) entries that simply live at the top level, on no shelf at all. Non-entry preamble text is preserved verbatim.
Shelves
Every ## Heading starts a shelf, running until the next ## heading or end of file. A shelf is organization — a place you keep things:
## With John
- Heat (1995)
- Blow Out (1981) +2026-02-11
## Rom-coms
- Set It Up (2018)
- Notting Hill (1999) 4/5 +
## Halloween marathon
- The Thing (1982) *
- Suspiria (1977)
Shelves do not decide watch status. Blow Out and Notting Hill above are watched because of their + marks — not because of which shelf they're on, and the unmarked titles around them are unwatched wherever they sit. Entries on any shelf parse under the full
entry grammar; tools preserve every shelf's name, order, and entry style, and never auto-empty one.
Name shelves anything: ## With John, ## Rom-coms, ## Favorites, ## Dad's recommendations. Apps may offer to organize a file into shelves for you — grouping by status (## Watched), by genre, by anything — but that's a filing convenience
the user opts into. The marks remain the truth; regrouping lines never changes what they mean.
- Title) or plain lines separated by blank lines. Both are equally valid; a writer preserves the style it finds.Streaming services
One shelf is special: ## Streaming Services (aliases: Services, Subscriptions) lists the services the author subscribes to, one per line. Service lines are plain names, not entry grammar — Apple TV+ must survive intact, so no token stripping applies inside it.
Files with no shelves
A list dumped from a notes app usually has no structure at all — and it doesn't need any. Since status lives on the line and shelves are optional organization, a file that is nothing but titles is already a complete OpenWatchlist document:
Heat (1995)
Casablanca (1942)
[x] The Thing (1982) 5/5
Severance @s2e6
parses as two queued titles, one watched, one in progress. Paste anything; structure is never a prerequisite.
Canonical examples
Heat (1995) !!! #crime #mann #pacino #deniro | need to watch
Heat (1995) _ !!! #crime #mann | explicitly unwatched
Severance (2022) 4.5 * @s2e6 #with-john #apple-tv | watching with John, very creepy
The Irishman (2019) @1:20:00 !! #scorsese #netflix | paused halfway through, finish soon
The Batman (2022) 4 * +2024-11-03 #dc #crime #noir | great atmosphere, slightly too long
Mad Men (2007) 5 * ^ + #prestige-tv #amc | watched, date unknown
The Flash (2023) 2/10 ~ #dc #superhero | bad, archived
Children of Men (2006) 5 * ^ !!! +2025-12-18 #sci-fi #dystopian | all-time favorite
Formatting conventions
- Lowercase kebab-case tags:
#with-john #apple-tv #sci-fi #prestige-tv #based-on-book. -
!!!is the maximum priority. Four or more exclamation marks read as title text, not a louder priority. -
A plain rating of
5means5/5. Five out of ten is written5/10.
Identity
Two lines refer to the same title when their title text and year match, case- and punctuation-insensitive. The year is part of a title's identity: Mulan (1998) and Mulan (2020) are different entries. Duplicate identities within a file are an authoring error tools should surface, not
silently merge. Identity is also how tools correlate one title across multiple list files.
Conformance
A conforming reader parses every construct in this document, treats unknown constructs and unparseable lines as opaque content, and never errors on arbitrary text.
A conforming writer emits canonical token order and spellings, preserves the preamble, every shelf, and entry order byte-for-byte apart from user-initiated changes, preserves each shelf's existing entry style, and round-trips: parsing then writing a canonical file reproduces it exactly.
Versioning
The format is versioned by this document. Backward compatibility is a hard requirement: a valid file must parse identically under every future version. New tokens may be added only where an older parser would already leave them harmlessly in the title.
OpenWatchlist is an open format. This document may be reproduced freely. The playground's parser.js is the reference parser for this specification.