Doc-as-code with the KB API
Doc-as-code is the pattern of treating help-center articles like application code — authored as files in a version-controlled repository, reviewed in pull requests, and synced into the live KB by an automated pipeline. Atender is built to support this pattern via /api/v1/kb/* and a tenant API key.
It is the pattern this very help center uses. The articles you’re reading live as markdown files in a Git-tracked vault, and a small Python script reads them and upserts to the KB whenever the source files change.
Why doc-as-code
Some help centers fit the in-app editor perfectly — small team, low volume, content authored by the same people who deliver support. For those teams, the in-app editor is exactly right.
The case for doc-as-code is stronger when:
- Multiple authors need to review each other’s changes. A pull request is a much better review surface than “tell me when you’re done and I’ll look at the article in the editor.”
- The source of truth lives elsewhere. If your engineering team writes specs in Markdown and your support team wants those specs translated into customer-facing articles, syncing from one repo to the KB closes the loop automatically.
- You want a version history beyond Atender. Git keeps every revision, with author attribution, in your own repo. The in-app editor doesn’t keep an external history.
- You’re migrating from another help center. A bulk import via the API is dramatically faster than recreating articles in the UI.
- You want CI to validate articles. Spell checkers, link checkers, frontmatter linters — all easy to run on Markdown files in CI, hard to bolt onto a hosted editor.
If none of those apply, stay in the in-app editor. Doc-as-code is overhead that only pays off when one of those needs is real.
The architecture
A doc-as-code setup has three parts:
- Source of truth — Git repo (or any version-controlled folder) — Markdown files with frontmatter for metadata
- Push script — The same repo or your CI — Reads the files, calls the API to upsert
- Live KB — Atender — The rendered, searchable, AI-retrievable surface
The push script is the bridge. It walks the repo, calls /api/v1/kb/categories to ensure each category exists, then calls /api/v1/kb/articles to upsert each article. It runs on every commit (in CI) or on demand (locally).
For what the script must handle — idempotent upserts, the frontmatter contract, and the requirements checklist — see Build an idempotent KB push script. For what the API does and doesn’t sync after a push (embeddings, translations, roles, sections), see KB API sync behavior and limits.
A real example: this very help center
The Atender help center is doc-as-code. The pattern in production:
- Articles live in
Atender/KB Articles/in an Obsidian vault on a maintainer’s machine. - A Python script reads each
.mdfile, parses the frontmatter, and walks every category. - The script calls
/api/v1/kb/*with a production API key stored in 1Password. - Categories upsert by name; articles upsert by slug.
- After the bulk push, the maintainer clicks Sync Translations in the editor to refresh non-English versions.
The whole loop — edit, save, push — takes under a minute for a single article and a few minutes for a whole batch. The KB stays current without anyone “remembering to update the help center.”