Push your help articles to Revvly Support.
If your help content lives in your own system, send it to Revvly instead of having a site crawled. The support AI answers from what you send, and you say who may read each article, so nothing is guessed.
#When to use this
#Create a key that can add articles
- Org Settings
- API keys
- Create key
- Can add knowledge articles
Admins and owners only. Revvly Support must be on for your workspace. The key is shown once.
The capability is called KNOWLEDGE_WRITE. It is separate from write access: a key that can add articles cannot change clients or subscriptions, and a write key cannot add articles. Keep it on your server only.
#Add or update articles
Call upsertKnowledgeArticles with the key as the Bearer token. Send up to 50 articles per call. Sending an article again with the same externalId updates it, and an article whose text, address and audience have not changed costs nothing.
Mutation and variablesmutation Push($articles: [KnowledgeArticleInput!]!) {
upsertKnowledgeArticles(source: "docs", syncId: "2026-10-11", articles: $articles) {
results { externalId status unchanged note error }
}
}
{
"articles": [
{
"externalId": "billing-invoices",
"title": "How to download an invoice",
"url": "https://help.acme.com/billing/invoices",
"markdown": "Open **Billing**, choose an invoice and select **Download PDF**.",
"roles": ["founder", "admin"],
"plans": ["growth", "scale"]
},
{
"externalId": "getting-started",
"title": "Getting started",
"html": "<p>Create your workspace, then invite your team.</p>",
"roles": []
}
]
}Response{
"data": {
"upsertKnowledgeArticles": {
"results": [
{ "externalId": "billing-invoices", "status": "INDEXED", "unchanged": false,
"note": null, "error": null },
{ "externalId": "getting-started", "status": "INDEXED", "unchanged": false,
"note": null, "error": null }
]
}
}
}Fields of each article
Sources and results
The source name (lowercase letters, digits, - and _; default default) groups your articles. The first push under a name creates the source, and you can have several. Each row succeeds or fails on its own: read results, which comes back in the order you sent, and look at error on each. Only a problem with the call itself fails the whole call.
#Remove articles
deleteKnowledgeArticles removes up to 200 articles by your externalId. Ids that are not there are ignored, so it is safe to repeat.
mutation Remove($ids: [String!]!) {
deleteKnowledgeArticles(source: "docs", externalIds: $ids) {
removed
}
}
{ "ids": ["billing-invoices"] }#Keep a source in step with yours
To mirror your content, send every article of a refresh with the same syncId (up to 128 characters), then close it with finishKnowledgeSync. Anything in the source that was not sent under that id is removed. This is the only way articles disappear without being named.
mutation Finish {
finishKnowledgeSync(source: "docs", syncId: "2026-10-11") {
removed
}
}A nightly job// A nightly job on your server: push every article, then finish the refresh.
const SYNC_ID = new Date().toISOString();
const articles = await loadArticlesFromYourCms();
for (let i = 0; i < articles.length; i += 50) {
const batch = articles.slice(i, i + 50).map((a) => ({
externalId: a.id,
title: a.title,
markdown: a.markdown,
url: a.publicUrl,
roles: a.audienceRoles, // [] means everyone
}));
await revvly(
`mutation($articles: [KnowledgeArticleInput!]!, $syncId: String) {
upsertKnowledgeArticles(source: "docs", syncId: $syncId, articles: $articles) {
results { externalId status error }
}
}`,
{ articles: batch, syncId: SYNC_ID },
);
}
// Anything in the source that was not sent under SYNC_ID is removed.
await revvly(
`mutation($syncId: String!) {
finishKnowledgeSync(source: "docs", syncId: $syncId) { removed }
}`,
{ syncId: SYNC_ID },
);#See it in the dashboard
- Support
- Knowledge
A pushed source shows as API, with its articles, their audience and the last result.
Pushed articles are searchable as soon as a row reports INDEXED. See also signing users in to the chat: the role value and attributes you send there decide which roles a person has, and the roles and plans you state here decide what their answers may draw on.