Knowledge base (direct)
Fetch KB collections and articles directly, outside the help-center channel scope.
- Use it for: Public website · Server integration
- Reads: public token — works in the browser
- Writes: Bearer (
apiKey) — server-side only - CLI:
uidu kb-collections,uidu kb-articles - Auth: what each token can do and where it may run — Authentication
The knowledge base is the content behind the Help Center:
collections of articles. The functions on this page read and write them at the workspace
level, with no channel in between — use them to list every collection across channels, to fetch an
article without knowing its collection, or to go past the 100-per-level cap of getChannel.
Mental model
Workspace
├── KbCollection { id, name, description, iconData, position, createdAt, updatedAt }
│ └── KbArticle { id, name, body, position, isDraft, createdAt, updatedAt, kbCollection { id, name } }
└── Channel a help center: shows some collections, in its own order (see Help Center)- Lists are flat arrays, one Relay page at a time:
listKbCollectionsandlistKbArticlestakefirst/after(orlast/before). For all of them,paginatewithListKbCollectionsDocumentorListKbArticlesDocument— see Pagination. listKbArticlesspans every collection and returns summaries —name,position,isDraft,kbCollection { id, name }, timestamps — withoutbody. OnlygetKbArticlereturns the body.getKbCollectionembeds its first 50 articles (id,name,position,isDraft,updatedAt) with theirpageInfo, ordered byposition. A bigger collection needslistKbArticles, filtered onkbCollection.id.- Drafts are left out of the article lists server-side, so
isDraftisfalseon everything a list returns. - Field shapes. A collection's
nameanddescriptionare JSON — often a string, possibly a localization map like{ en, it };iconDatais JSON. An article'snameis a string when you read it; itsbodyis Tiptap JSON, rendered with<RichText>. - Writes need the Bearer client.
createKbCollectionreturns the new collection atkbCollection.node;createKbArticlecreates the article inattributes.kbCollectionIdand returns it atkbArticle.node.update*take{ input: { id, attributes } },delete*{ input: { id } }. Validation failures come back inerrors, not as a throw: Writes. Collection attributes:name,description,iconData,position. Article attributes:name,body,isDraft,kbCollectionId,position,workspaceTagIds.
For a ready-made help center (channel → collections → articles in one request), use
getChannel; reach for these functions when you don't want channel
scoping.
Use cases
Cross-channel article index
Goal: one page listing every published article in the workspace, grouped by collection.
// src/app/kb/page.tsx
import Link from 'next/link';
import {
ListKbArticlesDocument,
listKbCollections,
paginate,
} from '@uidu/client';
import { uidu } from '@/lib/uidu';
export default async function KbIndexPage() {
const [collections, articles] = await Promise.all([
listKbCollections(uidu, { first: 100 }),
paginate(uidu, ListKbArticlesDocument, {
variables: { first: 100 },
extract: (data) => data.currentWorkspace?.kbArticles,
}),
]);
return collections
.sort((a, b) => a.position - b.position)
.map((c) => (
<section key={c.id}>
<h2>{typeof c.name === 'string' ? c.name : c.name?.en}</h2>
<ul>
{articles
.filter((a) => a.kbCollection?.id === c.id)
.sort((a, b) => a.position - b.position)
.map((a) => (
<li key={a.id}>
<Link href={`/kb/article/${encodeURIComponent(a.id)}`}>{a.name}</Link>
</li>
))}
</ul>
</section>
));
}paginatewalks every page of articles;listKbArticles(uidu, { first: 100 })would stop at the first 100.- The article page is
getKbArticle(uidu, { id })+<RichText doc={article.body} />— the same route as the Help Center article page.
Sync articles from your own docs
Goal: a server job that creates an article in a collection, then publishes it once its body is in.
// scripts/sync-kb.ts — runs with the apiKey client, never in a browser
import { createKbArticle, updateKbArticle } from '@uidu/client';
import { uiduAdmin } from '@/lib/uidu-admin';
export async function upsertArticle(kbCollectionId: string, title: string, body: unknown) {
const created = await createKbArticle(uiduAdmin, {
input: { attributes: { kbCollectionId, name: title, body, isDraft: true } },
});
if (!created || created.errors?.length) {
throw new Error(created?.errors?.map((e) => e.name).join(', ') ?? 'createKbArticle failed');
}
const id = created.kbArticle!.node!.id;
const published = await updateKbArticle(uiduAdmin, {
input: { id, attributes: { isDraft: false } },
});
if (published?.errors?.length) {
throw new Error(published.errors.map((e) => e.name).join(', '));
}
return id;
}- The new article is at
kbArticle.nodeon create, but atkbArticleon update — the payloads differ. bodyis Tiptap JSON ({ type: 'doc', content: [...] }), the same shapegetKbArticlereturns.- While
isDraftistruethe article stays out oflistKbArticles,getKbCollectionand the Help Center'sgetChannel. - From the terminal:
uidu kb-articles create --attributes '{"kbCollectionId":"…","name":"…"}' --json. Server client set-up: Server integration.
API at a glance
Every @uidu/client function in Knowledge base, generated from the source — the full reference has the rest of the SDK.
| Function | Kind | Auth | CLI | Description |
|---|---|---|---|---|
createKbArticle | write | Bearer | kb-articles create | Create a knowledge-base article in attributes.kbCollectionId. Returns the payload (with errors) or null. The new article is at kbArticle.node. |
createKbCollection | write | Bearer | kb-collections create | Create a knowledge-base collection. Returns the payload (with errors) or null. The new collection is at kbCollection.node. |
deleteKbArticle | write | Bearer | kb-articles delete | Delete a knowledge-base article by { input: { id } }. Returns the payload (with errors) or null. |
deleteKbCollection | write | Bearer | kb-collections delete | Delete a knowledge-base collection by { input: { id } }. Returns the payload (with errors) or null. |
getKbArticle | read | public token | kb-articles get | One knowledge-base article with its rich-text body and its collection, or null. |
getKbCollection | read | public token | kb-collections get | One knowledge-base collection with its first 50 articles, or null. |
listKbArticles | read | public token | kb-articles list | Knowledge-base articles across every collection, as a flat array; page with first/after (or last/before). |
listKbCollections | read | public token | kb-collections list | The workspace's knowledge-base collections as a flat array; page with first/after (or last/before). |
updateKbArticle | write | Bearer | kb-articles update | Update a knowledge-base article: { input: { id, attributes } }. Returns the payload (with errors) or null. |
updateKbCollection | write | Bearer | kb-collections update | Update a knowledge-base collection: { input: { id, attributes } }. Returns the payload (with errors) or null. |
Types: KbArticle, KbCollection
CLI:
| Entity | list | get | create | update | delete |
|---|---|---|---|---|---|
kb-collections | ✓ | ✓ | ✓ | ✓ | ✓ |
kb-articles | ✓ | ✓ | ✓ | ✓ | ✓ |