Quick API use examples
Ready-to-copy curl for the most common workflows.
For auth, error envelope, and rate limits, see the
main API docs.
Working with folders? Jump to the
Folders API page.
curl below works identically for team tokens —
the wire format is the same, the endpoints are the same. The only difference is
where the writes land: a team token's POST /notes
creates a team note, increments the team's storage pool, and shows up in the
team audit log.
Mint team tokens at /team/api_tokens.
Filename = title
On POST /api/v1/notes the
filename is derived from your title
(NFC-normalized, slashes and control / format characters stripped, truncated to 200 bytes).
Same rule the
/notes/by-filename/:filename
endpoint uses — so a note created here with title cron-jobs-prod
is immediately addressable as
/notes/by-filename/cron-jobs-prod
for later appends.
- Blank title → filename auto-generated as
YYYYMMDD-HHMMSS-<hex>.txt. - A title that resolves to a filename you already have returns
422 validation_failed— pick a different title. - Bulk endpoint follows the same rule per row, including same-batch dedup.
One curl, one event
Two patterns. Append-only for log streams; standard CRUD for editable notes.
Sending the bearer token — two ways:
A. Export it once, then reference it as $FRESHJOTS_TOKEN in any curl in the same shell session:
export FRESHJOTS_TOKEN="mn_yourrealtokenhere"
curl -X POST https://freshjots.com/api/v1/notes/by-filename/cron-jobs-prod/append \
-H "Authorization: Bearer $FRESHJOTS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"backup ok 2026-04-26 03:00"}'
B. Paste the raw token inline — no $. Fine for one-off testing; the token will sit in your shell history, so rotate it after:
curl -X POST https://freshjots.com/api/v1/notes/by-filename/cron-jobs-prod/append \
-H "Authorization: Bearer mn_yourrealtokenhere" \
-H "Content-Type: application/json" \
-d '{"text":"backup ok 2026-04-26 03:00"}'
The endpoint examples below use option A. The $FRESHJOTS_TOKEN in them is a shell-variable reference — leave the $ in. Replacing the variable name with your literal token (e.g. $mn_realtoken) breaks the request because bash interprets $mn_realtoken as a different (undefined) variable.
Create-or-append by filename
First call creates the note, every subsequent call appends a line —
one curl, no id lookup, no setup step. A cron job hitting this URL hourly creates
cron-jobs-prod on its first run and adds a line on every run after.
By default the note is created as append-only (PATCH/DELETE return
403 note_locked); pass
"append_only": false in the body if you'd rather have an editable note instead.
Bonus: appends push to an open browser tab via Turbo — the viewer sees new
lines land in real time, no refresh needed.
curl -X POST https://freshjots.com/api/v1/notes/by-filename/cron-jobs-prod/append \
-H "Authorization: Bearer $FRESHJOTS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"backup ok 2026-04-27 03:00"}'
Create an editable (CRUD) note
When you want a note that can be PATCHed, appended, and deleted through the API, hit the standard create
endpoint. Filename is set to the (sanitized) title:
engineering-journal.
Note: API edits to a CRUD note do not push to an open
browser tab — refresh the page to see changes made through the API.
curl -X POST https://freshjots.com/api/v1/notes \
-H "Authorization: Bearer $FRESHJOTS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"note":{"title":"engineering-journal","plain_body":"fixed the auth bug"}}'
Alternative: create an append-only note via /notes
Equivalent to the create-or-append form above — passing "append_only": true
on the standard create endpoint locks the note (PATCH/DELETE return
403 note_locked; only further appends work).
Prefer the by-filename form for new streams; reach for this one when you need to set
folder_id or another field at creation time.
curl -X POST https://freshjots.com/api/v1/notes \
-H "Authorization: Bearer $FRESHJOTS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"note":{"title":"cron-jobs-prod","plain_body":"backup ok 2026-04-26 03:00","append_only":true}}'
List recent notes
curl https://freshjots.com/api/v1/notes?format=plain \
-H "Authorization: Bearer $FRESHJOTS_TOKEN"
Windows / PowerShell (no WSL)
The CLI is a bash script, but you don't need it — the API is plain HTTPS.
On Windows you can write to your account three ways, none of which need
WSL, bash, or jq.
The endpoints and JSON bodies are exactly the same as the
curl examples above.
Set the token in PowerShell
Session only (this window) — or persist it for your Windows user so new
shells pick it up (then reopen PowerShell, or set $env: as well for the current one):
# this session only
$env:FRESHJOTS_TOKEN = "mn_yourrealtokenhere"
# persist for future shells (current session still needs the line above)
[Environment]::SetEnvironmentVariable("FRESHJOTS_TOKEN", "mn_yourrealtokenhere", "User")
Windows PowerShell 5.1 only: if your first request fails with
Could not create SSL/TLS secure channel, your shell is
defaulting to TLS 1.0. Run this once per session (or add it to your profile):
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12.
PowerShell 7+ (pwsh) negotiates TLS 1.2 / 1.3 automatically — recommended.
Zero install — Invoke-RestMethod
Built into PowerShell; nothing to install. Create-or-append by filename
(first call creates the note, every later call appends a line) — the same
/notes/by-filename/:filename/append
endpoint as the curl example above:
Invoke-RestMethod -Method Post `
-Uri "https://freshjots.com/api/v1/notes/by-filename/cron-jobs-prod/append" `
-Headers @{ Authorization = "Bearer $env:FRESHJOTS_TOKEN" } `
-ContentType "application/json" `
-Body '{"text":"backup ok 2026-04-27 03:00"}'
Create an editable (CRUD) note — same
POST /api/v1/notes
body as the curl example:
Invoke-RestMethod -Method Post `
-Uri "https://freshjots.com/api/v1/notes" `
-Headers @{ Authorization = "Bearer $env:FRESHJOTS_TOKEN" } `
-ContentType "application/json" `
-Body '{"note":{"title":"engineering-journal","plain_body":"fixed the auth bug"}}'
Single-quoted strings are taken literally in PowerShell (an embedded
' needs doubling:
'it''s'), so a static JSON
body needs no escaping.
Dynamic body — build the JSON in PowerShell
As soon as the body needs a timestamp, a counter, or any user-supplied string,
stop hand-writing JSON. Build a hashtable and pipe it through
ConvertTo-Json — it
escapes quotes, backslashes, and control characters automatically, so the request
stays well-formed no matter what the text contains:
$body = @{ text = "backup ok $(Get-Date -Format o)" } | ConvertTo-Json
Invoke-RestMethod -Method Post `
-Uri "https://freshjots.com/api/v1/notes/by-filename/cron-jobs-prod/append" `
-Headers @{ Authorization = "Bearer $env:FRESHJOTS_TOKEN" } `
-ContentType "application/json; charset=utf-8" `
-Body $body
The explicit charset=utf-8
matters on Windows PowerShell 5.1, where Invoke-RestMethod
otherwise encodes the body with the system code page — non-ASCII characters
(accents, emoji, smart quotes) round-trip as mojibake. PowerShell 7+ sends UTF-8 by default.
Read the response, handle errors
Invoke-RestMethod parses the JSON response into a
PowerShell object for you — no jq needed. It also
throws on any 4xx / 5xx, which hides the API's error envelope (422 validation_failed,
403 note_locked, etc.). Wrap the call to surface it:
try {
$r = Invoke-RestMethod -Method Post `
-Uri "https://freshjots.com/api/v1/notes" `
-Headers @{ Authorization = "Bearer $env:FRESHJOTS_TOKEN" } `
-ContentType "application/json; charset=utf-8" `
-Body (@{ note = @{ title = "engineering-journal"; plain_body = "fixed the auth bug" } } | ConvertTo-Json)
"created note id=$($r.note.id) filename=$($r.note.filename)"
} catch {
# $_.ErrorDetails.Message is the raw JSON error body from the API
Write-Error "API call failed: $($_.ErrorDetails.Message)"
}
List recent notes
Invoke-RestMethod -Method Get `
-Uri "https://freshjots.com/api/v1/notes?format=plain" `
-Headers @{ Authorization = "Bearer $env:FRESHJOTS_TOKEN" }
PowerShell 7+ (pwsh) is recommended for all of the above;
Windows PowerShell 5.1 also works with the TLS / charset notes above.
Or the freshjots CLI (one global install via npm)
The npm package ships a freshjots command
that works identically in PowerShell, CMD, and Windows Terminal — npm generates a
.cmd shim on Windows automatically, so there
is no WSL or Git Bash dependency. If you already have Node 18 or later, the install is one line;
otherwise grab the LTS installer first with
winget install OpenJS.NodeJS.LTS.
npm install -g freshjots
freshjots list # one row per note: idfilenametitle
freshjots cat cron-jobs-prod # prints the note's plain body
"backup ok $(Get-Date -Format o)" | freshjots append cron-jobs-prod
freshjots create "Deploy log" "Initial entry."
"Initial entry." | freshjots create "Deploy log" # same, via stdin
Stdin piping works in PowerShell exactly as it does in bash, so the
| freshjots append pattern carries over.
Or a client library (for scripting)
The npm and PyPI clients are zero-dependency and cross-platform — no WSL.
Both read FRESHJOTS_TOKEN from the environment.
// Node 18+ — npm install freshjots (save as write.mjs, run: node write.mjs)
import { Client } from "freshjots";
await new Client().append("cron-jobs-prod", "backup ok");
# Python 3.8+ — pip install freshjots
from freshjots import Client
Client().append("cron-jobs-prod", "backup ok")
Back to the main API docs. Questions? Contact me directly.