The REST API is the token-cheap publish path: push a file so its bytes never pass
back through your agent's context. It's the same pipeline as the MCP publish tool —
idempotent by content hash, versioned, format auto-detected.
POST https://htmlbook.io/api/docs
Authorization: Bearer <your hb_live_… key>
The key is the same one you use for MCP. A key is bound to one workspace.
Send the document as the raw request body. project and slug go in the query string:
curl -s -X POST "https://htmlbook.io/api/docs?project=acme&slug=q3-report" \
-H "Authorization: Bearer $HTMLBOOK_API_KEY" \
--data-binary @q3-report.mdhtmlbook picks Markdown vs. HTML by the Content-Type or a leading-< sniff, so both
just work:
# HTML — becomes an hb-doc if it has <article class="hb-doc">, else a bundle
curl -s -X POST "https://htmlbook.io/api/docs?project=acme&slug=dashboard" \
-H "Authorization: Bearer $HTMLBOOK_API_KEY" \
--data-binary @dashboard.htmlWhy a file push beats inlining: Write(doc.html) then publish(html=…) tokenizes the
document twice and leaves it in context. --data-binary @doc.html emits only the one
curl line.
If you'd rather send JSON, post { "html": … } or { "markdown": … } with project
/slug still in the query:
curl -s -X POST "https://htmlbook.io/api/docs?project=acme&slug=q3" \
-H "Authorization: Bearer $HTMLBOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "markdown": "# Q3\n\nRevenue up 8% QoQ." }'Markdown mistakenly sent in the html field (no leading <) is rerouted to the
markdown path, so it still lands as a themed doc, not a verbatim bundle.
- HTML requires
project(in the query). - Markdown can omit
projectif the file carries it in YAML frontmatter — the file self-addresses. See markdown.md. slugis optional everywhere; it's derived from the title / first heading.
JSON with the owner reader link, plus the public share link only when the document is public (never a link that would 404):
{
"project": "acme",
"slug": "q3-report",
"version": 1,
"kind": "hbdoc",
"url": "https://htmlbook.io/app/p/acme/q3-report",
"shareUrl": "https://htmlbook.io/d/a1b2c3"
}shareUrl is present only when visibility is public.
Re-posting an unchanged document is a true no-op — no new version. For Markdown the
hash is over the .md source, so re-running a sync is cheap.
Give each .md frontmatter so it self-addresses, then loop:
for f in docs/**/*.md; do
curl -s -X POST "https://htmlbook.io/api/docs" \
-H "Authorization: Bearer $HTMLBOOK_API_KEY" \
--data-binary @"$f"
done# Owner — Markdown source (add &download=1 for an attachment)
curl -s "https://htmlbook.io/api/docs/source?project=acme&slug=q3-report" \
-H "Authorization: Bearer $HTMLBOOK_API_KEY"
# Public document — raw source, no auth
curl -s "https://htmlbook.io/d/a1b2c3/raw"See also: Publishing · Markdown · MCP tools