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, or key
  • Query parameter apiKey or key

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..."