Skip to content

← Back to API docs

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.

Team tier? Every 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.