3.0 KiB
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 (1–100) |
{
"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.json— JSON Feed 1.1 document withcontent_htmlanddate_publishedper item.sitemap.xml— XML sitemap built fromsite.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.