Skip to main content
A category is a node in the tree that organizes articles inside a knowledge base. Categories nest through parent_id; each carries a name, a slug, an icon, and a sort order. An article points to a category through its category_id.

Anatomy

Where categories live

Categories are scoped to an org and live inside a knowledge base — knowledge_base_id is required when you create one. The tree is built from parent_id — null means “root of the tree.” There is no enforced depth limit, but most teams keep it to two or three levels for usability.

Creating a category

POST /article-categories requires name, slug, and knowledge_base_id. The slug must be unique within the org. Pass parent_id to nest under another category.
Both knowledge_base_id and parent_id must reference resources that belong to your organization. A foreign or nonexistent id is rejected with 422 — "A referenced resource does not exist." sort_order, when supplied, must be an integer; a non-integer value returns invalid_payload.

Listing

GET /article-categories returns a flat, paginated list. Use the query parameters to scope: The API does not return a tree — assemble it client-side from the flat list (see the object reference).

Deleting

DELETE /article-categories/{id} has two modes.

Default: refuse if non-empty

If the category has child categories or contains articles, the call returns 409 category_not_empty with counts of what’s in the way. Empty categories delete cleanly with a 204.
The counts are scoped to direct contents — a child category that itself has children only contributes 1 to child_category_count. Use them to decide whether a cascade is safe.

Cascade: delete everything

Pass ?cascade=true to delete the category, every descendant category, and every article inside them in one call. The response is a summary:
Cascade is irreversible and destroys articles. The article.deleted webhook fires per article. There is no soft-delete fallback — for a recoverable removal, set article status to archived instead.

Webhook events