farfield · docs

content

content.farfield.systems

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.

Screenshot of the Farfield content UI
Content admin dashboard in the logged-in state. Records shown are the live management view.

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

GET /api/collections
{ "collections": [Collection, …] }
GET /api/entries?collection=slug
{ "entries": [Entry, …] } — published only
GET /api/entries/{slug}
Entry — public, rate-limited; 404 if missing/draft; strong ETag
GET /api/series
{ "series": [Series, …] }
GET /api/series/{slug}
Series — 404 if missing; strong ETag
GET /status
{ "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: