Every route below sits under one base address.
The client holds one base address and builds every route from it. Nothing in this system may assume that it is mounted at the root of a host. Asset paths, redirects and the cookie path are all built from the configured prefix.

Two authentication models

The tool has two groups of routes. They do not share an authentication method.
The cookie is httpOnly, Secure and SameSite=Lax. Its Path is set explicitly.

Status codes

The codes carry meaning. A client must treat them differently.
401 and 410 are separate answers on purpose. A client that treats them as one either retries a dead session forever or throws away a good token.

Reviewer routes

These routes use the bearer token.

Session

A session response carries the session, the project, the author, the whitelist, the anchor algorithm versions and the upload limits.
canSetDisplayName is sent as a fact. The client does not infer it from displayName being empty. This way the prompt appears exactly once and no control is drawn that would fail.

Threads and comments

Uploads

Admin routes

These routes use the gateway session cookie. The account also needs the webpage-review flag.

Projects

Whitelist

Reviewer sessions

A token lasts 7, 14, 30 or 90 days. The default is 30 days.
The validity is a closed set, not a range. A typed “90000 days” cannot quietly mint a permanent credential.

Threads, uploads and read state

Identifiers

Every {id} matches this pattern.

Sizes

The system uses 1024 × 1024 for one megabyte, everywhere. The conversion from a typed megabyte figure to bytes happens one time, in the router.
The two readings of a megabyte differ by 4.9 percent at 1000 MB. Nobody would notice which one shipped. For that reason the choice is made in one place and written down.