Files
volumen/docs/api-reference.md
petrbalvin 3b8ed31f67
Test / test (push) Successful in 1m7s
Release / release (push) Successful in 1m11s
chore: prepare release v0.4.0
2026-07-26 18:15:29 +02:00

3.0 KiB
Raw Permalink Blame History

API Reference

Status: the public read API (/api/volumen) and the admin (/admin) are implemented. The admin is server-rendered HTML, not part of the JSON API.

Base path: /api/volumen. All responses are JSON unless noted. Read endpoints send Access-Control-Allow-Origin: *.

GET /api/volumen/site

Returns site metadata from the configuration.

{
  "title": "My Blog",
  "description": "A blog powered by volumen.",
  "base_url": "https://example.com",
  "language": "en",
  "author": "Anonymous",
  "fediverse_creator": "@petrbalvin@mastodon.social"
}

fediverse_creator is null when the site-wide default is not set; a per-post value (see below) takes precedence when present.

GET /api/volumen/posts

Paginated list of published posts (drafts are excluded), newest first. Posts with all_langs = true in their frontmatter match every lang filter.

Name Type Default Description
lang string Filter by language
tag string Filter by tag
q string Case-insensitive search across title and body
page int 1 Page number
limit int 20 Per page (1100)
{
  "page": 1,
  "page_size": 20,
  "total": 1,
  "has_next": false,
  "has_prev": false,
  "posts": [
    {
      "slug": "hello",
      "title": "Hello",
      "excerpt": "Hello world.",
      "date": "2026-01-15",
      "lang": "en",
      "tags": ["intro"],
      "author": null,
      "fediverse_creator": null,
      "cover": null,
      "reading_time": 1,
      "translations": {},
      "url": "/api/volumen/posts/hello"
    }
  ]
}

GET /api/volumen/posts/{slug}

Single post including the raw Markdown body and rendered HTML. Optional ?lang= selects a translation. Returns 404 with {"error":"not_found"} if no match. Drafts return 404 with {"error":"draft"}.

{
  "slug": "hello",
  "title": "Hello",
  "excerpt": "Hello world.",
  "date": "2026-01-15",
  "lang": "en",
  "tags": ["intro"],
  "author": null,
  "fediverse_creator": "@petrbalvin@mastodon.social",
  "cover": null,
  "reading_time": 1,
  "translations": {},
  "url": "/api/volumen/posts/hello",
  "body": "Hello **world**.",
  "html": "<p>Hello <strong>world</strong>.</p>\n"
}

GET /api/volumen/tags

Tag cloud with counts (published posts only), most frequent first.

{ "tags": [{ "name": "intro", "count": 1 }] }

GET /api/volumen/feed.xml, GET /api/volumen/feed.json, GET /api/volumen/sitemap.xml

  • feed.xml — RSS 2.0 feed of the 20 most recent posts.
  • feed.jsonJSON Feed 1.1 document with content_html and date_published per item.
  • sitemap.xml — XML sitemap built from site.base_url.

OPTIONS /api/volumen/*

Preflight requests return an empty 204 with the same CORS headers as the GET endpoints, so browsers can reach the JSON API cross-origin.