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

  1. 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.
  2. 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.
  3. 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.
bash
# 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-sleutelopstelling

2. 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.

bash
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

bash
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:

bash
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.

bash
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

bash
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

bash
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ë

bash
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

  1. Koppel jou MCP-kliënt en kies die regte werkspasie. Bevestig dat dit kb:read en kb:write het, met toegang tot jou kanaal.
  2. 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.
  3. 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.
  4. 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
MCP-gereedskapoproep
{
  "name": "upsert_kb_category",
  "arguments": {
    "sourceId": "SOURCE_ID",
    "externalId": "billing",
    "name": "Billing",
    "position": 0
  }
}
2. upsert_kb_article
MCP-gereedskapoproep
{
  "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
MCP-gereedskapoproep
{
  "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
MCP-gereedskapoproep
{
  "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
MCP-gereedskapoproep
{
  "name": "update_kb_article",
  "arguments": {
    "sourceId": "SOURCE_ID",
    "articleId": "ARTICLE_ID",
    "updates": {
      "audience": "verified",
      "audienceId": "AUDIENCE_ID",
      "status": "published"
    }
  }
}
6. list_kb_articles
MCP-gereedskapoproep
{
  "name": "list_kb_articles",
  "arguments": {
    "sourceId": "SOURCE_ID",
    "page": 1,
    "limit": 100,
    "updatedSince": "2026-09-01T00:00:00Z"
  }
}
7. reorder_kb_articles
MCP-gereedskapoproep
{
  "name": "reorder_kb_articles",
  "arguments": {
    "sourceId": "SOURCE_ID",
    "ids": [
      "ARTICLE_ID_1",
      "ARTICLE_ID_2"
    ]
  }
}
8. update_kb_audience
MCP-gereedskapoproep
{
  "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.

Verwante REST- en MCP-bewerkings vir die kennisbasis
TaakRESTMCP
Lys / kry artikelsGET /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 IDPOST /articles · POST /categoriescreate_kb_article · create_kb_category
Wysig bestaande inhoudPATCH /articles/{articleId} · PATCH /categories/{categoryId}update_kb_article · update_kb_category
Rangskik kategorieëPUT /categories/reorderreorder_kb_categories
Lees / wysig hulpsentrum-instellingsGET /help-center · PATCH /help-centerget_help_center · update_help_center
Lys / wysig gehoreGET /audiences · PATCH /audiences/{audienceId}list_kb_audiences · update_kb_audience
SkrapDELETE /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