Ontwikkelaarsgids · REST en MCP
Sinkroniseer jou kennisbasis
Hou aan skryf in jou bestaande stelsel en stuur veranderinge na Sonny. Hierdie gids skep 'n Fakturering-kategorie, sinkroniseer 'n konsepartikel en publiseer dit dan vir 'n geverifieerde kliëntgehoor.
1. Kies 'n kanaal en skep 'n sleutel
- Maak Kanale → jou kanaal oop. Kopieer die ID ná /app/sources/ in sy paneelbord-URL. Die API noem hierdie kanaal-ID sourceId; dit verskil van die widget se siteId en die hulpsentrum se openbare slug.
- Gee in Instellings → Ontwikkelaar → API-sleutels → Skep sleutel die bestekke kb:read en kb:write. Beperk Kanaaltoegang tot die kanaal wat jy wil sinkroniseer. Stoor die eenmalige sleutel in jou bediener se geheimbestuurder.
- Stel die veranderlikes hieronder in jou agterkant-omgewing. Hierdie voorbeelde gebruik curl; vervang ID's in hoofletters met die waardes wat Sonny teruggee. Hardloop hulle teen 'n toetskanaal voordat jy 'n regstreekse hulpsentrum sinkroniseer.
# Load SONNY_API_KEY from your server's secret manager first.
# SOURCE_ID is the ID in the channel dashboard URL: /app/sources/SOURCE_ID
export SOURCE_ID="YOUR_SOURCE_ID"
export BASE="https://www.usesonny.com/api/v1/sources/$SOURCE_ID"Opsionele ontdekking: GET /api/v1/sources en die MCP-hulpmiddel list_sources gee toeganklike kanale terug en vereis conversations:read. Jy het nie daardie bestek nodig as jy reeds die kanaal-ID het nie. Domeinkoppeling bly 'n paneelbordtaak.
Volledige API-sleutelopstelling2. Skep of werk die kategorie by
Gebruik 'n stabiele ID uit jou bronstelsel in die URL. Om dieselfde eksterne ID weer te stuur, werk die bestaande kategorie by in plaas daarvan om 'n duplikaat te skep. Die eerste skepping inisialiseer hierdie kanaal se hulpsentrum outomaties.
curl --fail-with-body -X PUT "$BASE/categories/by-external-id/billing" \
-H "Authorization: Bearer $SONNY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Billing","position":0}'Verwag 201 by skepping of 200 by bywerking, met die kategorie onder data. Stoor data.id wanneer jy Sonny se interne kategorie-ID nodig het. URL-enkodeer eksterne ID's; hou hulle stabiel selfs wanneer titels verander.
3. Sinkroniseer 'n artikel as 'n konsep
curl --fail-with-body -X PUT "$BASE/articles/by-external-id/billing-guide" \
-H "Authorization: Bearer $SONNY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Manage billing","body":"## Find your invoices\n\nOpen **Settings → Billing** in your account.","bodyFormat":"markdown","categoryExternalId":"billing","status":"draft"}'Die antwoord bevat data.id en gesaniteerde HTML in data.body. Maak die artikel oop in Kanale → jou kanaal → Hulpsentrum om sy formatering na te gaan. Markdown word na HTML omgeskakel; rou HTML word ook aanvaar met bodyFormat: "html" (die verstek). Die artikel se titel is apart van opskrifte in die liggaam.
Gebruik categoryExternalId om na die kategorie uit stap 2 te verwys, of categoryId vir sy Sonny-ID. Verskaf net een. Stel enigeen op null om 'n artikel ongekategoriseer te maak. Elke upsert het 'n titel en liggaam nodig; PATCH is beskikbaar vir gedeeltelike wysigings. Nuwe artikels is by verstek konsepte wanneer status weggelaat word.
4. Stel toegang en publiseer dan
Vir hierdie voorbeeld van 'n privaat sentrum koppel jy eers geverifieerde kliëntaanmelding. Skep die gehoor en stoor sy teruggegewe data.id:
curl --fail-with-body -X POST "$BASE/audiences" \
-H "Authorization: Bearer $SONNY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Pro customers","rules":{"match":"all","conditions":[{"trait":"plan","op":"in","value":["pro","business"]}]}}'Vervang AUDIENCE_ID, ARTICLE_ID en die aanmeld-URL hieronder. Die eerste versoek maak die hulpsentrum Regstreeks en beperk dit tot Pro-kliënte. Die tweede publiseer die artikel. Jou app se aanmeldvloei moet 'n ondertekende kliënt-JWT met die hulpsentrum uitruil; om net signInUrl te stel, meld niemand aan nie.
curl --fail-with-body -X PATCH "$BASE/help-center" \
-H "Authorization: Bearer $SONNY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled":true,"title":"Acme Help Center","audience":"verified","audienceId":"AUDIENCE_ID","signInUrl":"https://app.example.com/login"}'
# Replace ARTICLE_ID and AUDIENCE_ID with the returned data.id values.
curl --fail-with-body -X PATCH "$BASE/articles/ARTICLE_ID" \
-H "Authorization: Bearer $SONNY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"audienceId":"AUDIENCE_ID","status":"published"}'Gebruik die URL wat GET /help-center teruggee om die aangemelde lesersaansig en 'n afgemelde blaaier te toets. API-sleutels en MCP tree as personeel op en kan inhoud binne hul bestekke lees; hul suksesvolle antwoord bewys nie dat 'n kliënt die artikel kan sien nie.
Vir 'n openbare sentrum gebruik jy audience: "everyone" en audienceId: null op die sentrum en artikel, en gaan die kategorie se toegang ook na. Om net 'n benoemde groep te verwyder, stuur audienceId: null; toegang net vir geverifieerdes bly tensy jy audience uitdruklik verander. 'n Weggelate audienceId behou die vorige toewysing. Alle hulpsentrum-, kategorie- en artikelbeperkings moet pas.
Benoemde reëls gebruik match: "all" of "any", tot 10 voorwaardes en streng getikte waardes. Operateurs: eq, neq, in, not_in, exists, not_exists, gt, gte, lt, lte. Numeriese vergelykings neem getalle; in/not_in neem skikkings van 1–100 skalaarwaardes; exists/not_exists laat value weg. Ontbrekende eienskappe misluk vergelykings. Sien reëlgedrag, oorerwing en probleemoplossing vir toegang.
5. Hou die sinkronisering op datum
Herhaal skrywes sonder om inhoud te dupliseer
Herhaal PUT met dieselfde eksterne ID wanneer jou bron verander. Eksterne ID's is uniek binne 'n hulpsentrum. Weggelate bywerkvelde behou hul huidige waardes. Laat status weg by latere upserts om publikasie te behou; om draft uitdruklik te stuur, onttrek 'n regstreekse artikel. publishedAt word by eerste publikasie gestel en bly onveranderd. Dit is leesalleen, so historiese publikasiedatums kan nie ingevoer word nie. Onveranderde inhoud en wysigings net aan metadata veroorsaak nie onnodige herinbedding nie.
Lees veranderinge en ontleding
curl --fail-with-body --get "$BASE/articles" \
-H "Authorization: Bearer $SONNY_API_KEY" \
--data-urlencode "page=1" --data-urlencode "limit=100" \
--data-urlencode "status=published" \
--data-urlencode "updatedSince=2026-09-01T00:00:00Z"
# Get the full sanitized HTML and read-only analytics for one article.
curl --fail-with-body "$BASE/articles/ARTICLE_ID" \
-H "Authorization: Bearer $SONNY_API_KEY"Artikel- en kategorielyste gee data plus pagination terug: page, limit, total. Bladsye begin by 1; limit is by verstek 50 en aanvaar tot 100. Hou dieselfde filters en versoek bladsye totdat page × limit total bereik. Albei lyste aanvaar externalId en updatedSince; artikels aanvaar ook categoryId en status (draft of published). Gebruik 'n ISO-tydstempel met 'n tydsone vir updatedSince; dit sluit rekords in wat op daardie tyd bygewerk is.
Lees elke artikel se besonderhede om sy volle body, viewCount, helpfulYes en helpfulNo te kry. Hierdie ontleding is leesalleen. updatedSince lys huidige rekords; dit rapporteer nie skrappings nie. Hou rekord van verwyderings in jou bronstelsel en skrap die ooreenstemmende Sonny-rekord uitdruklik wanneer dit bedoel is.
Laai 'n beeld op
curl --fail-with-body -X POST "$BASE/media" \
-H "Authorization: Bearer $SONNY_API_KEY" \
-F "file=@billing.png;type=image/png"Gebruik die teruggegewe data.url in Markdown-beeldsintaksis of 'n HTML-img-element, en sinkroniseer dan die artikel se liggaam. Oplaaie aanvaar JPEG, PNG, GIF en WebP tot 25 MB en vereis 'n geïnisialiseerde hulpsentrum. Opgelaaide URL's is openbaar; 'n artikel se gehoorbeperking beskerm nie die beeld-URL nie. MCP gebruik upload_kb_media met sourceId, fileName, contentType en die lêer se dataBase64 in plaas van multipart-vormdata.
Rangskik artikels en kategorieë
curl --fail-with-body -X PUT "$BASE/articles/reorder" \
-H "Authorization: Bearer $SONNY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ids":["ARTICLE_ID_1","ARTICLE_ID_2"]}'Haal eers elke bladsy sonder status-, kategorie- of datumfilters, insluitend konsepte. Vervang die voorbeeld-ID's met elke huidige artikel-ID presies een keer, in die gewenste volgorde. Gebruik /categories/reorder vir die volledige kategorielys. 'n Suksesvolle herrangskikking gee 204 sonder liggaam terug. As die lys verander het of vreemde, dubbele of ontbrekende ID's bevat, herlaai dit voordat jy weer probeer. Jy kan ook 'n nie-negatiewe position in individuele skrywes stel.
Gebruik dieselfde werkvloei deur MCP
- Koppel jou MCP-kliënt en kies die regte werkspasie. Bevestig dat dit kb:read en kb:write het, met toegang tot jou kanaal.
- Gebruik die paneelbord se kanaal-ID, of roep list_sources as jou geloofsbrief ook conversations:read het. Moet nooit die widget se siteId in die plek daarvan gebruik nie.
- Hardloop die eerste vyf voorbeelde hieronder in volgorde. Vervang SOURCE_ID met jou kanaal-ID, en ARTICLE_ID/AUDIENCE_ID met elke vroeëre resultaat se data.id. Vervang die aanmeld-URL en koppel aanmelding voordat jy publiseer.
- Gebruik list_kb_articles om veranderinge te hersien. Hardloop net 'n herrangskikking nadat jy die volledige ongefiltreerde lys versamel het, insluitend konsepte. Herlaai jou lyste ná suksesvolle skrywes.
Elke voorbeeld wys die hulpmiddel se naam en sy argumente. Upsert-velde gaan direk in arguments; bywerk-gereedskap sit veranderde velde binne updates. Dit is invoere vir gereedskapoproepe, nie 'n HTTP-versoek na die MCP-eindpunt nie.
1. upsert_kb_category
{
"name": "upsert_kb_category",
"arguments": {
"sourceId": "SOURCE_ID",
"externalId": "billing",
"name": "Billing",
"position": 0
}
}2. upsert_kb_article
{
"name": "upsert_kb_article",
"arguments": {
"sourceId": "SOURCE_ID",
"externalId": "billing-guide",
"title": "Manage billing",
"body": "## Find your invoices\n\nOpen **Settings → Billing** in your account.",
"bodyFormat": "markdown",
"categoryExternalId": "billing",
"status": "draft"
}
}3. create_kb_audience
{
"name": "create_kb_audience",
"arguments": {
"sourceId": "SOURCE_ID",
"name": "Pro customers",
"rules": {
"match": "all",
"conditions": [
{
"trait": "plan",
"op": "in",
"value": [
"pro",
"business"
]
}
]
}
}
}4. update_help_center
{
"name": "update_help_center",
"arguments": {
"sourceId": "SOURCE_ID",
"updates": {
"enabled": true,
"title": "Acme Help Center",
"audience": "verified",
"audienceId": "AUDIENCE_ID",
"signInUrl": "https://app.example.com/login"
}
}
}5. update_kb_article
{
"name": "update_kb_article",
"arguments": {
"sourceId": "SOURCE_ID",
"articleId": "ARTICLE_ID",
"updates": {
"audience": "verified",
"audienceId": "AUDIENCE_ID",
"status": "published"
}
}
}6. list_kb_articles
{
"name": "list_kb_articles",
"arguments": {
"sourceId": "SOURCE_ID",
"page": 1,
"limit": 100,
"updatedSince": "2026-09-01T00:00:00Z"
}
}7. reorder_kb_articles
{
"name": "reorder_kb_articles",
"arguments": {
"sourceId": "SOURCE_ID",
"ids": [
"ARTICLE_ID_1",
"ARTICLE_ID_2"
]
}
}8. update_kb_audience
{
"name": "update_kb_audience",
"arguments": {
"sourceId": "SOURCE_ID",
"audienceId": "AUDIENCE_ID",
"updates": {
"name": "Paid customers"
}
}
}Verwante bewerkings
REST-paaie hieronder is relatief tot BASE. Lees die API-verwysing vir elke veld en antwoordskema.
| Taak | REST | MCP |
|---|---|---|
| Lys / kry artikels | GET /articles · GET /articles/{articleId} | list_kb_articles · get_kb_article |
| Lys / kry kategorieë | GET /categories · GET /categories/{categoryId} | list_kb_categories · get_kb_category |
| Skep sonder 'n eksterne ID | POST /articles · POST /categories | create_kb_article · create_kb_category |
| Wysig bestaande inhoud | PATCH /articles/{articleId} · PATCH /categories/{categoryId} | update_kb_article · update_kb_category |
| Rangskik kategorieë | PUT /categories/reorder | reorder_kb_categories |
| Lees / wysig hulpsentrum-instellings | GET /help-center · PATCH /help-center | get_help_center · update_help_center |
| Lys / wysig gehore | GET /audiences · PATCH /audiences/{audienceId} | list_kb_audiences · update_kb_audience |
| Skrap | DELETE /articles/{articleId} · /categories/{categoryId} · /audiences/{audienceId} | delete_kb_article · delete_kb_category · delete_kb_audience |
Om 'n artikel te skrap, is permanent. Om 'n kategorie te skrap, maak sy artikels ongekategoriseer en verwyder daardie oorgeërfde kategoriebeperking. Om 'n gehoor te skrap, verwyder sy eienskapreëls terwyl gekoppelde inhoud net vir geverifieerdes bly. Hersien die geraakte toegang voordat jy skrap; gebruik konsepte om artikels te onttrek wanneer jy hulle wil hou.
Los 'n sinkronisering se probleme op
- 400 · Ongeldige versoek
- Gaan die verpligte title/body of name, presiese veldname, geldige reëltipes en volledige herrangskikkings-ID's na. Stuur categoryId of categoryExternalId, nie albei nie.
- 401 · Nie gemagtig nie
- Verskaf 'n geldige Bearer-sleutel. Gaan na of dit verval het of herroep is.
- 403 · Verbode
- Gaan die sleutel se bestekke, die sleuteleienaar se toestemmings en die werkspasie se fakturering na. Koppel 'n MCP-kliënt weer met die vereiste toegang as sy gereedskap leesalleen is.
- 404 · Nie gevind nie
- Bevestig dat die bron aan die gekose werkspasie behoort en deur die geloofsbrief toegelaat word. Inisialiseer 'n nuwe hulpsentrum deur eers inhoud te skep; lees skep dit nie.
- 409 · Konflik
- Haal die huidige inhoud weer op en versoen die botsende ID of verouderde volgorde voordat jy weer probeer.
- 413 · Te groot
- Maak die beeld kleiner as die limiet van 25 MB.
- 429 · Tempo beperk
- Wag vir Retry-After voordat jy weer probeer. Gebruik RateLimit-Limit, RateLimit-Remaining en RateLimit-Reset om versoeke te versprei.
Verwante dokumentasie
- Hulpsentrum
Publiseer antwoorde, organiseer kategorieë, kies lesertoegang en hou jou hulpsentrum op datum.
- Hulpsentrum-gehore
Skep kliëntegroepe, maak jou hulpsentrum privaat en toets wie elke antwoord kan lees.
- Openbare APIBeta
Sorteer en sinkroniseer gesprekke, deel kliëntkonteks, lees verslae en stuur lêers met API-sleutels met bestekke.
- Sonny MCPBeta
Koppel KI-assistente aan inkassiewerkvloeie, kliëntherinneringe, verslae en lêers met OAuth of sleutels met bestekke.