Anatomy
Where articles live
Articles sit inside a two-tier container:Knowledge base
Top-level scope. One org can host many knowledge bases. Set with
knowledge_base_id — required on every article, and it must belong to your organization. See Knowledge Bases.Category
A tree of folders inside a knowledge base.
category_id is the leaf the article belongs to; categories themselves nest via parent_id. null for articles at the KB root. The category must belong to your organization. See Article Categories.Send markdown — we derive the rest
Every article has two parallel bodies:contentis the source — your markdown, edited by humans, rendered to readers. This is the only body you write.content_plainis a plain-text mirror the server derives fromcontentand uses for search, embeddings, previews, and snippets.
content. It renders the markdown to HTML, strips tags, keeps <img alt> copy inline, and collapses whitespace — the same projection the dashboard editor produces, so what’s indexed via the API matches what’s indexed via the UI.
Don’t try to send
content_plain in the request body — the field isn’t accepted as input. The response includes it so you can verify what got indexed.Image re-hosting
Articles created or updated through the API have every external image incontent pulled into Awardee’s asset library — the same store the dashboard editor uses. This runs synchronously during the write, so the response body always reflects the canonical post-write state.
Each image — whether you sent markdown  or an HTML <img src="url"> — is replaced with an asset reference tag carrying the library asset’s id, not a URL:
What you send
What `content` stores
<img data-asset-id="2c1b4a9f-7e8d-4a3c-9b1f-6e5d4c3b2a1f" alt="Returns portal">Dedup
Images are content-hashed, so re-using the same picture across articles stores one asset and one set of bytes.
Smart alt text & vision
Every rehosted image is queued for AI enrichment: a concise
alt caption plus a rich, searchable description that’s folded into the article’s embeddings so the chatbot can reason about what each image shows. This happens asynchronously — the asset exists immediately; its caption and description populate shortly after.internal articles land in the private bucket; public and chatbot_only articles use the public bucket.
The cap per image is 15 MiB.
Publish lifecycle
Status transitions trigger server-side work:| Transition | What fires |
|---|---|
→ published | Article enters the indexing pipeline; embeddings computed; article.published webhook |
→ unpublished or archived (from published) | Embeddings removed; article.unpublished webhook |
| Any change | article.updated webhook |
| Indexing completes | article.indexed webhook |
| Indexing fails | article.indexing_failed webhook |
indexing_status === "indexed" is the supported signal that an article is searchable — but for non-interactive flows, subscribe to article.indexed instead. See Publishing & indexing.
Visibility
public
Surfaced on your public knowledge base site and to anonymous chatbot visitors.
internal
Hidden from public surfaces. Indexed for authenticated agents only.
chatbot_only
Not rendered in the KB UI. Available to chatbots as a retrieval source.
Translations, versions, and relations
Satellite resources hang off every article.Translations
Per-language copies of
title + content. The primary article’s language is the canonical one; translations cover everything else and index alongside the primary.Versions
Snapshots of
content. Auto-created on every PATCH that changes title or content, plus manual snapshots via POST /articles/{id}/versions. Restore with POST /articles/{id}/versions/{version}/restore.Related articles
Cross-links between articles in the same org. Manage them under
/articles/{id}/relations — list, add one, bulk replace/add, or remove one.Common workflows
- Import from external CMS
- Programmatic updates
- Multi-language KB
Sync a Notion, Contentful, or in-house CMS into Awardee on a schedule. Use
Idempotency-Key on the create so retries don’t duplicate, and PATCH on every subsequent run.- For each source article, compute a stable key like
cms-<source-id>. POST /articleswithIdempotency-Key: cms-<source-id>andstatus: "draft".- Later runs
PATCH /articles/{id}with the updatedcontent— auto-snapshots the prior version for you. - Flip
statusto"published"when ready — indexing fires automatically.
Webhook events
Subscribe in Dashboard → Webhooks. Article-related events:| Event | When it fires |
|---|---|
article.created | A new article row is written |
article.updated | Any field changes |
article.deleted | The article row is removed |
article.published | Status transitions to published; indexing kicked off |
article.unpublished | Status leaves published for unpublished or archived |
article.indexed | Embedding pipeline finished successfully |
article.indexing_failed | Embedding pipeline errored out |
article_category.created | New category created |
article_category.updated | Category fields change |
article_category.deleted | Category removed |

