Files

109 lines
3.0 KiB
Markdown
Raw Permalink Normal View 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.
```json
{
"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 |
2026-07-26 18:15:29 +02:00
| q | string | — | Case-insensitive search across title and body |
| page | int | 1 | Page number |
| limit | int | 20 | Per page (1100) |
```json
{
"page": 1,
"page_size": 20,
"total": 1,
2026-07-26 18:15:29 +02:00
"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
2026-07-26 18:15:29 +02:00
no match. Drafts return `404` with `{"error":"draft"}`.
```json
{
"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.
```json
{ "tags": [{ "name": "intro", "count": 1 }] }
```
2026-07-26 18:15:29 +02:00
## `GET /api/volumen/feed.xml`, `GET /api/volumen/feed.json`, `GET /api/volumen/sitemap.xml`
2026-07-26 18:15:29 +02:00
- `feed.xml` — RSS 2.0 feed of the 20 most recent posts.
- `feed.json` — [JSON Feed 1.1](https://www.jsonfeed.org/) 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.