Headless Publishing API (api/publish.php)
External build pipelines, report generators, AI agents, and qwiki-builder publish categories, documents, and media assets programmatically through api/publish.php.
Authentication
Pass either the site's publishApiKey or an active scoped LLM key (qwk_llm_...) via:
- HTTP header
X-API-Key: <key>(recommended) - Form/POST parameter
api_key,apiKey, orkey - Query parameter
apiKeyorkey
Missing or invalid keys return 401 Unauthorized; if neither publishApiKey nor any llmKeys are configured on the portal, the endpoint returns 403 Forbidden.
Supported Actions (action)
| Action | Key Parameters | Behavior |
|---|---|---|
publish_doc (default) |
bookId, title, content, optional slug, type (markdown/html), description, shareKey, publicShareable, update/overwrite |
Creates or updates a document, generates a 16-hex shareKey, handles `depth on HTML, and returns canonicalurlandshareUrl`. |
update_doc / edit_doc |
Same as publish_doc |
Forces allowOverwrite = true, updating content in-place through DocumentService::replaceContent() (creating a revision snapshot if enabled). |
create_category / add_book |
title, optional id/bookId, description, parentId |
Idempotently creates top-level or nested categories (when parentId is provided) and updates title/description if the ID already exists. |
list_categories / get_books |
None | Returns the portal's category/sub-category hierarchy. |
upload_image / upload_asset / upload_media |
Multipart image, file, or asset |
Validates image (png, jpg, jpeg, gif, svg, webp) or video (mp4, webm, ogg, ogv, mov) files and stores them in uploads/images/ or uploads/videos/, returning url and fullUrl. |
list_chapters / get_chapters |
Optional bookId |
Lists chapters across all categories or one category with slug, file, shareKey, shareUrl, and url. |
resolve_share_key |
shareKey |
Resolves a 16-hex shareKey to its bookId, slug, title, file, url, and shareUrl. |
set_status / update_status |
slug / shareKey / file, status (draft/in_review/published/archived), optional approver, approverNote, clean_source |
Updates document lifecycle status in qwiki.json and synchronizes HTML data-qwiki-status (optionally stripping drafting artifacts with clean_source=1). |
delete_chapter / delete_doc |
slug, optional bookId, permanent (1/true) |
Moves the document (and .submissions.json for forms) to data/trash/ by default; only unlinks permanently and purges revisions when permanent=true. Refuses locked/protected chapters with 403. |
Example: Create a Nested Category & Publish a Chapter
# 1. Create a nested sub-category
curl -sS -X POST https://wiki.example.com/api/publish.php \
-H "X-API-Key: $QWIKI_KEY" \
-d "action=create_category" \
-d "id=release-notes" \
-d "parentId=manual-welcome" \
-d "title=Release Notes"
# 2. Publish or update a Markdown chapter inside it
curl -sS -X POST https://wiki.example.com/api/publish.php \
-H "X-API-Key: $QWIKI_KEY" \
-d "action=update_doc" \
-d "bookId=release-notes" \
-d "slug=v1-20-16" \
-d "title=VaultFlow 1.20.16" \
--data-urlencode "c VaultFlow 1.20.16\n\nRelease summary..."