API reference
23 operations in kb. Raw spec: openapi.json.
GET
/api/v1/kb/articlesGET /api/kb/articles
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_id | query | — | No | |
status | query | null | KbArticleStatus | No | |
client_visible | query | boolean | No | Only articles passing the effective client-facing gate. |
q | query | — | No | Title substring narrowing; ranked full-text search rides /api/search. |
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
POST
/api/v1/kb/articlesPOST /api/kb/articles — instant-first (IF1/IF2).
Request body
CreateArticleRequest
Responses
| Status | Description |
|---|---|
200 | |
409 | slug already in use or idempotency key reused |
422 | title/body rejected by KB rules |
Security: bearer
GET
/api/v1/kb/articles/{article_id}/embedsGET /api/kb/articles/{article_id}/embeds
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
article_id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
POST
/api/v1/kb/articles/{article_id}/embedsPOST /api/kb/articles/{article_id}/embeds — resolve-then-store; instant-first (IF1/IF2).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
article_id | path | string | Yes |
Request body
CreateEmbedRequest
Responses
| Status | Description |
|---|---|
200 | |
404 | article not visible in scope |
409 | url already attached or idempotency key reused |
422 | url is not on the allowlist |
Security: bearer
GET
/api/v1/kb/articles/{id}GET /api/kb/articles/{id} — with the sanitized read-only HTML projection (no editor package in any read bundle).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | article not visible in scope |
Security: bearer
PATCH
/api/v1/kb/articles/{id}PATCH /api/kb/articles/{id} — instant-first (IF1/IF2). Archived articles refuse title/body edits until unarchived (typed conflict); status flips stay legal.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Request body
UpdateArticleRequest
Responses
| Status | Description |
|---|---|
200 | |
404 | article not visible in scope |
409 | archived content lock, version conflict, slug reuse, or idempotency key reused |
422 | title/body rejected by KB rules |
Security: bearer
DELETE
/api/v1/kb/articles/{id}DELETE /api/kb/articles/{id} — emits `kb_article.deleted` so the unified-search indexer drops the article's index entry.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | article not visible in scope |
Security: bearer
GET
/api/v1/kb/categoriesGET /api/kb/categories
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
POST
/api/v1/kb/categoriesPOST /api/kb/categories — instant-first (IF1/IF2).
Request body
CreateCategoryRequest
Responses
| Status | Description |
|---|---|
200 | |
409 | slug already in use or idempotency key reused |
Security: bearer
PATCH
/api/v1/kb/categories/{id}PATCH /api/kb/categories/{id} — instant-first (IF1/IF2).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Request body
UpdateCategoryRequest
Responses
| Status | Description |
|---|---|
200 | |
404 | category not visible in scope |
409 | version conflict, slug reuse, or idempotency key reused |
Security: bearer
DELETE
/api/v1/kb/categories/{id}DELETE /api/kb/categories/{id} — articles keep existing (category_id clears; ON DELETE SET NULL), so no content is lost behind a removal.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | category not visible in scope |
Security: bearer
GET
/api/v1/kb/embed-providersGET /api/kb/embed-providers — system rows + the org's extensions.
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
POST
/api/v1/kb/embed-providersPOST /api/kb/embed-providers — registry extension (admin-managed); instant-first (IF1/IF2). System rows are shipped, never created here.
Request body
CreateProviderRequest
Responses
| Status | Description |
|---|---|
200 | |
409 | slug already in use or idempotency key reused |
422 | provider shape rejected (hosts/regex/endpoint) |
Security: bearer
PATCH
/api/v1/kb/embed-providers/{id}PATCH /api/kb/embed-providers/{id} — org rows only; instant-first.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Request body
UpdateProviderRequest
Responses
| Status | Description |
|---|---|
200 | |
404 | provider not visible in scope (system rows are not patchable through the org filter) |
409 | system-row edit, version conflict, or idempotency key reused |
422 | provider shape rejected |
Security: bearer
DELETE
/api/v1/kb/embed-providers/{id}DELETE /api/kb/embed-providers/{id} — org rows only. Deleting a provider leaves its embeds in place with `provider_id` cleared (the FK is ON DELETE SET NULL) so they degrade to blocked, never to unvalidated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | provider not visible in scope |
409 | system rows are not deletable |
Security: bearer
POST
/api/v1/kb/embeds/resolvePOST /api/kb/embeds/resolve — validate a URL against the allowlist without attaching it to an article (live preview in the editor).
Request body
ResolveEmbedRequest
Responses
| Status | Description |
|---|---|
200 | |
422 | url is not on the allowlist |
503 | provider oEmbed endpoint unreachable |
Security: bearer
DELETE
/api/v1/kb/embeds/{id}DELETE /api/kb/embeds/{id}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | embed not visible in scope |
Security: bearer
GET
/api/v1/kb/external-documentsGET /api/kb/external-documents
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
article_id | query | — | No | Narrow to one article's attachments. |
Responses
| Status | Description |
|---|---|
200 |
Security: bearer
POST
/api/v1/kb/external-documentsPOST /api/kb/external-documents — instant-first (IF1/IF2).
Request body
CreateExternalDocumentRequest
Responses
| Status | Description |
|---|---|
200 | |
404 | attached article not visible in scope |
409 | idempotency key reused |
422 | title/url rejected by KB rules |
Security: bearer
GET
/api/v1/kb/external-documents/{id}GET /api/kb/external-documents/{id}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | external document not visible in scope |
Security: bearer
PATCH
/api/v1/kb/external-documents/{id}PATCH /api/kb/external-documents/{id} — instant-first (IF1/IF2). A URL change resets the link-check columns: the old verification is about the old URL.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Request body
UpdateExternalDocumentRequest
Responses
| Status | Description |
|---|---|
200 | |
404 | external document not visible in scope |
409 | version conflict or idempotency key reused |
422 | title/url rejected by KB rules |
Security: bearer
DELETE
/api/v1/kb/external-documents/{id}DELETE /api/kb/external-documents/{id}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | external document not visible in scope |
Security: bearer
POST
/api/v1/kb/external-documents/{id}/link-checkPOST /api/kb/external-documents/{id}/link-check — performs one server-side HTTPS HEAD (GET fallback) and records the outcome as data. `unreachable` covers DNS/TLS/timeouts/non-2xx; the endpoint never fails on an unreachable link — the record is the result.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes |
Responses
| Status | Description |
|---|---|
200 | |
404 | external document not visible in scope |
Security: bearer