# Reading articles Every route that returns an article accepts the optional `format` query parameter and returns the article body in that format. Articles are stored as HTML (Tiptap output). Storage and the request bodies of `POST /v1/article/` and `PATCH /v1/article/{id}` stay HTML. ## Routes that honour `format` - `GET /v1/article/` - `GET /v1/article/{id}` - `POST /v1/article/` - `PATCH /v1/article/{id}` - `PATCH /v1/article/{id}/publish` - `PATCH /v1/article/{id}/unpublish` Visibility is unchanged: anonymous and unverified callers only see online articles, and an offline article answers `404 Article not found`. ## The `format` parameter | Value | `body` | `body_format` | | --- | --- | --- | | empty or absent | markdown string | `markdown` | | `markdown` | markdown string | `markdown` | | `html` | the stored HTML string | `html` | | `json` | JSON array of blocks | `json` | Values are case-insensitive. When `format` is repeated, the first value is used. Any other value answers `400` with the plain-text message `The format must be one of: markdown, html, json.` before any article is read or written. An invalid id is reported first, ahead of the format. Breaking change: the default used to be HTML. Clients that need HTML must send `?format=html`. The web interface does so. ## Article object ```json { "id": 1, "title": "Backyard Renovation Update", "body": "## Plan\n\nReplace the **old** deck.", "body_format": "markdown", "is_online": true, "created_at": "2026-03-12T09:14:00Z", "updated_at": "2026-09-10T07:00:00Z" } ``` ## Markdown output Headings, bold, italic, links, bullet and ordered lists, blockquotes, fenced code blocks, rules, images and inline code are converted. Anything else is reduced to its text. `script` and `style` content is removed, and the source HTML is never passed through; the only HTML in the output is the alignment wrapper described below. List indentation attributes are dropped. Links with a scheme other than http, https, mailto or tel are reduced to their text. Characters that markdown would read as formatting (`*`, `_`, `` ` ``, `[`, `]`, `<`, `\`) and line starts that would read as a heading, list, quote or rule (`#`, `-`, `+`, `>`, `1.`) are backslash-escaped, so plain text stays plain text. A line break becomes a backslash followed by a newline. ### Text alignment Markdown has no syntax for alignment, so centered, right-aligned and justified paragraphs and headings are wrapped in a `div` with an inline style. The blank lines around the content make CommonMark parse the inside as markdown: ```markdown
Replace the old deck.
`: ```json [ {"type":"heading","level":2,"children":[{"type":"text","text":"Plan","marks":[]}]}, {"type":"paragraph","children":[ {"type":"text","text":"Replace the ","marks":[]}, {"type":"text","text":"old","marks":[{"type":"bold"}]}, {"type":"text","text":" deck.","marks":[]} ]} ] ``` ## Errors | Status | Body | | --- | --- | | `400` | `The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).` for an invalid id | | `400` | `The format must be one of: markdown, html, json.` for an unsupported format | | `404` | `Article not found` | | `500` | `Internal server error` when the body cannot be converted |