API docs
Bearer-token REST. Plain notes only. Available on the
Dev and Dev-pro tiers.
For the systemic pitch — every script gets its own notebook, append-by-filename for cron jobs and
AI-session digests, real-world workflows — see
/for/developers.
Base URL: https://freshjots.com/api/v1
Quick API use examples.
Ready-to-copy curl for the common workflows: create, append-only logs, append by filename, list.
Working with folders? Create folders, drop notes into them on create, bulk-upload into a folder.
Folders API →Authentication
Generate a token in /settings/api_tokens. Tokens are shown once on creation and stored as a one-way hash — copy to your password manager or shell profile immediately.
Authorization: Bearer mn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Missing or invalid token returns 401 unauthenticated.
Token holder lacks API access (Free/Paid tier) returns 403 forbidden.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /notes | List notes (summary). Filter ?format=plain or ?format=rich. Paginate ?page=N (50/page, max 200). |
| GET | /notes/:id | Full note (plain_body + byte_size). |
| POST | /notes | Create plain note. Body: {title, plain_body, folder_id?}. |
| PATCH | /notes/:id | Update title / plain_body. Format is immutable. |
| DELETE | /notes/:id | Delete note. |
| POST | /notes/:id/append | Atomic append to plain_body. Body: {text}. |
| POST | /notes/:id/move | Move to folder. Body: {folder_id} or null. |
| GET | /notes/by-filename/:filename | Find by filename instead of id. |
| POST | /notes/by-filename/:filename/append | Stream addressing — append by filename. Creates the note if missing. |
| POST | /notes/bulk | Dev-pro only. Up to 50 creates per call. Body: {notes: [...]}. |
| GET | /folders | List folders. |
| POST | /folders | Create folder. Body: {name}. |
| PATCH | /folders/:id | Rename folder. |
| DELETE | /folders/:id | Delete folder. Notes inside are preserved (un-foldered). |
Rate limits
- Dev: 600 reads / 60 writes / 300 appends per minute. 1 active token. 15 GB storage.
- Dev-pro: 2,000 reads / 200 writes / 1,000 appends per minute. 10 active tokens. 30 GB storage. Bulk endpoint enabled.
Throttled requests return 429 rate_limited
with Retry-After,
X-RateLimit-Limit,
X-RateLimit-Remaining, and
X-RateLimit-Reset headers.
The full per-tier breakdown — including per-note size caps, browser-surface throttles, pagination ceilings, token-expiry policy, and the export window — is on the Service limits page.
Error envelope
All error responses share the same shape:
{ "error": { "code": "validation_failed", "message": "Title can't be blank", "details": ["Title can't be blank"] } }
Stable error codes:
unauthenticated— missing / invalid token (401)forbidden— token lacks API access or account unconfirmed (403)not_found— record absent or owned by another user (404)validation_failed— bad input or schema violation (422)cap_exceeded— note count over your tier's cap (422)storage_cap_exceeded— total bytes would exceed your storage cap (422)content_too_large— single note over per-format byte cap (413)content_type_mismatch— attempted rich-note write via API (422)rate_limited— throttle window exceeded (429)
Live browser updates
Heads-up:
when you have a note open in the web UI and an API write hits it,
only append-only notes update in place — the browser
subscribes to a per-user stream and replaces the body as new content lands, no refresh
needed. Try it: open an append-only note in one tab, then
curl an append from another window.
Editable (CRUD) notes updated through the API
(PATCH /api/v1/notes/:id,
POST /notes/:id/append on a non-locked
note) are not pushed to an open browser tab — refresh the page
to pick up the new content. This is by design: pushing mid-edit content swaps would clash with
the editor's in-flight autosave.
Questions? Contact me directly.