Skip to content
Fresh Jots
· 4 min read
Write a Note From Any Project You Have, in Any Language, From Any Method

Write a Note From Any Project You Have, in Any Language, From Any Method

A Fresh Jots note is just a URL. Anything that can make an HTTPS POST can write to it: a Python script, a Java service, a Postgres trigger, a shell pipeline, a Claude Code session. The pattern is the same across every language; the only thing that changes is the HTTP client.

This post is the index — three lines of glue in every major language, plus links to the full per-language guides as they go live.

The contract

One endpoint, one header, one JSON body. That's the whole API surface you need for "append a line to my note":

POST https://freshjots.com/api/v1/notes/by-filename/<your-note>/append 
Authorization: Bearer <FJOTS_TOKEN>
Content-Type: application/json {"text": "your line here"}

You address notes either by id (`/notes/42/append`) or by filename (`/notes/by-filename/cron-jobs/append`). Filename is easier — every script that "knows itself" can name its own target without round-tripping to find an id.

A curl call, to anchor everything below:
curl -X POST https://freshjots.com/api/v1/notes/by-filename/deploy-log/append \
  -H "Authorization: Bearer $FJOTS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text":"deploy ok — sha=abc123"}'
Three lines of body in every language below produce the exact same HTTP request.

The pattern in other languages

Python
import os, requests
requests.post(
    "https://freshjots.com/api/v1/notes/by-filename/deploy-log/append",
    headers={"Authorization": f"Bearer {os.environ['FJOTS_TOKEN']}"},
    json={"text": "deploy ok — sha=abc123"},
)

SQL (Postgres, via the `http` extension)
SELECT http_post(
  'https://freshjots.com/api/v1/notes/by-filename/db-events/append',
  '{"text":"backup_done at ' || now()::text || '"}',
  'application/json',
  ARRAY[http_header('Authorization', 'Bearer ' || current_setting('app.fjots_token'))]
);
Useful inside a trigger so the database itself writes the note when a row changes. The deep-dive post will cover MySQL (UDF) and SQL Server (CLR) too.

JavaScript (Node)
await fetch("https://freshjots.com/api/v1/notes/by-filename/deploy-log/append", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.FJOTS_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ text: "deploy ok — sha=abc123" }),
});

TypeScript
Same as JavaScript, with the response typed:
type AppendResponse = { id: number; byte_size: number; last_appended_at: string };

const res = await fetch(
  "https://freshjots.com/api/v1/notes/by-filename/deploy-log/append",
  {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.FJOTS_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ text: "deploy ok — sha=abc123" }),
  },
);
const note: AppendResponse = await res.json();

Java
HttpClient.newHttpClient().send(
  HttpRequest.newBuilder(URI.create(
      "https://freshjots.com/api/v1/notes/by-filename/deploy-log/append"))
    .header("Authorization", "Bearer " + System.getenv("FJOTS_TOKEN"))
    .header("Content-Type", "application/json")
    .POST(BodyPublishers.ofString("{\"text\":\"deploy ok — sha=abc123\"}"))
    .build(),
  BodyHandlers.discarding());

C#
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("FJOTS_TOKEN"));
await http.PostAsync(
    "https://freshjots.com/api/v1/notes/by-filename/deploy-log/append",
    new StringContent("{\"text\":\"deploy ok — sha=abc123\"}",
                      Encoding.UTF8, "application/json"))

C++ (libcurl)
CURL* c = curl_easy_init();
struct curl_slist* h = nullptr;
h = curl_slist_append(h, ("Authorization: Bearer " + std::string(getenv("FJOTS_TOKEN"))).c_str());
h = curl_slist_append(h, "Content-Type: application/json");
curl_easy_setopt(c, CURLOPT_URL,
  "https://freshjots.com/api/v1/notes/by-filename/deploy-log/append");
curl_easy_setopt(c, CURLOPT_HTTPHEADER, h);
curl_easy_setopt(c, CURLOPT_POSTFIELDS, "{\"text\":\"deploy ok — sha=abc123\"}");
curl_easy_perform(c);
curl_easy_cleanup(c);

C (libcurl)
Same shape as C++ — libcurl is C-first. The deep-dive post will show error checking and a reusable wrapper function.

Why this matters

Once you internalize that *any* HTTPS POST is one append, a lot of "I should set up logging for this" questions collapse into "I'll just append to a Fresh Jots note":

- **Deploy receipts** — every successful deploy gets one line. Bisecting regressions three weeks later is grep, not Datadog.
- **CI failure log** — on-failure step in GitHub Actions / GitLab CI / CircleCI curls the build summary into a per-repo note.
- **Backup/cron heartbeat** — append at the end of every successful run, set a dead-man deadline. Free replacement for Healthchecks.io.
- **Database trigger journal** — Postgres trigger writes a line when a sensitive row changes. Audit trail without an audit table.
- **Personal incident timeline** — debugging prod at 3 AM, append timestamped lines from the terminal. Post-mortem writes itself.

The lift is so low (three lines) that the question stops being "is this worth setting up" and starts being "is there any reason *not* to."

Per-language deep dives

**Python** — `requests` for one-offs, `httpx` for async, exporting a clean `fjots.append(text)` for the rest of your codebase.
**SQL** — Postgres (`http` extension, `pg_net`), MySQL, SQL Server. Triggers and async caveats.
**JavaScript** — Node 20+'s built-in `fetch`, browser `fetch` with CORS notes, batching via the bulk endpoint.
**TypeScript** — typed responses, a small SDK shape, using the API from a Vite / Next.js app.
**Java** — `HttpClient` patterns, Spring Boot integration, error-handling middleware.
**C#** — `HttpClient` lifetime (don't `new` per call), `IHttpClientFactory`, ASP.NET integration.
**C++** — libcurl wrappers, RAII for headers, cpr as the modern alternative.
**C** — libcurl with proper error checking, a single-file reusable function.

Get started

You need a Fresh Jots API token. The fastest path:

2. Pick **Software development** mode at onboarding (or switch to it later from Settings).
3. A 14-day trial API key lands in your inbox.
4. Set `FJOTS_TOKEN` in your shell or `.env`, copy the curl above, change the filename to one you own.

Three lines, in your language. One note, append-only. The rest is up to you.

Share this post

Ready to start taking better notes? Sign up free