Skip to content

Personal API ​

Your own scripts can use the same API as the app. It is JSON over HTTPS, one workspace per token.

Token ​

Create one in Settings → Connections → Personal tokens and send it with every request:

sh
curl -H "Authorization: Bearer vsp_…" https://noted-this.date/api/entries

The token carries its own unlock key, so it reads your content without a passkey. It is shown once. Treat it like a password, and revoke it on the same page when you are done with it. Writing needs Pro.

Entries ​

RequestDoes
GET /api/entries{ entries, next }, newest first with photos. ?in=all|favorites|archive, ?q=, ?tag=, ?day=YYYY-MM-DD, ?fromDate=, ?toDate= filter, ?pinned= splits pinned, ?before= takes the previous next
GET /api/entries/{id}One entry: meta, Markdown body and photos
POST /api/entriesWrite an entry, see below
PATCH /api/entries/{id}Change body, tags, visibility, pinned, favorite, archived
DELETE /api/entries/{id}Delete for good, with photos no other entry uses
POST /api/entries/{id}/publishPost to a connected { "provider": "x" }, "threads", "bluesky" or "telegram" (Pro, experimental)

A text entry is JSON:

json
{ "body": "Rain all day.", "tags": ["weather"], "visibility": "private" }

occurredAt (milliseconds), pinned, favorite and archived are optional; they default to now and false. visibility is private or public; a public entry can be read by anyone at /e/{id}.

An entry with photos takes two steps:

  1. Upload each original with PUT /api/photos: the image as the body, its type in Content-Type and its SHA-256 in hex in X-Content-SHA256. JPEG, PNG, WebP, GIF and AVIF are accepted, up to 200 MB each; convert HEIC first.
  2. Send the entry as multipart/form-data: an entry field holding the JSON above, then for each photo, in order, its digest, a thumb JPEG, its mime type and a meta JSON with width, height, thumbHash, takenAt, geo, place and exif. Up to four photos and 8 MB per request.

The app builds the thumbnail and meta in the browser with @vesper/media.

Photos ​

RequestDoes
GET /api/photos{ photos, next }: photos of 24 entries per page with their entry, taken time and place; the same filters and ?before= as entries
GET /api/photos/{id}?size=thumbThe thumbnail; size=original for the full image

GET /api/tags lists every tag with its count; PATCH /api/tags with { "from", "to" } renames a tag on every entry, and "to": null removes it.

GET /api/workspace tells who the token belongs to: the workspace handle, plan, role, scopes, and write, which is false when the plan or the token cannot write.

Each workspace can make 120 API requests a minute; past that the answer is 429 with Retry-After.

There is also a command line built on this API.

Errors ​

Errors are JSON with a message:

StatusWhen
400The input does not validate
401No valid token
403A missing scope, or the plan is Free
404Nothing matches
423The workspace is locked
429Too many requests; wait a minute
502X, Threads, Bluesky or Telegram refused the post