content
Collections, entries, and series fragments. The admin UI supports writing markdown content with blob:// and series:// embeds. Collections are managed in the admin UI; series fragments are reusable markdown blocks that can be spliced into entries.
Authentication
The read endpoints require a bearer token — send the read key as Authorization: Bearer <token> or X-API-Key; the write key is also accepted. /status stays public, and responses still send Access-Control-Allow-Origin: *.
The read token returns published content only. The write key additionally previews drafts: ?status=all or ?status=draft on /api/entries, or fetch a draft directly by slug (a draft is a 404 to the read token).
One exception: a single published entry, GET /api/entries/{slug}, is public so "view source" links open in a browser — no token — but rate-limited per client IP (keyed callers are exempt). Draft safety is unchanged: a draft is a 404 to anyone without the write key, so it never leaks through the public path. The lists and /api/series/{slug} stay token-gated.
JSON API
{ "collections": [Collection, …] }{ "entries": [Entry, …] } — published only404 if missing/draft; strong ETag{ "series": [Series, …] }404 if missing; strong ETag{ "service": "content", "ok": true, "collections": N }Write endpoints (POST /api/entries, PUT /api/entries/{slug}, DELETE /api/entries/{slug}, POST /api/series) require an API key.
Record Shapes
Collection
{
"slug": "string",
"name": "string",
"description": "string?",
"createdAt": "2024-01-01T00:00:00Z",
"entryCount": 0
}
Entry
{
"collection": "string",
"slug": "string",
"cid": "bafk…",
"title": "string",
"excerpt": "string?",
"body": "markdown",
"tags": ["string"],
"published": true,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z"
}
Series
{
"slug": "string",
"cid": "bafk…",
"title": "string?",
"body": "markdown",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z"
}
Body URIs
Entry and post body markdown embeds two custom URIs. Resolve them before rendering:
blob://<cid>— rewrite tohttps://blobs.farfield.systems/blobs/<cid>. For dimensions, blurhash, or a blur-up placeholder, readGET /blobs/<cid>/meta.— fetchGET /api/series/<slug>and splice the fragment'sbodymarkdown in place of the whole image construct. The fragment itself containsblob://images.