Ontwikkelaars
Openbare API Beta
Bouw integraties voor je werkruimte met veilige API-sleutels met beperkte rechten en een stabiel, geversioneerd JSON-contract.
Open de interactieve API-referentieSnel aan de slag
- 01
Open API-sleutels
Open Instellingen, kies Ontwikkelaar, zoek API-sleutels en kies Sleutel aanmaken. Eigenaren en beheerders kunnen sleutels aanmaken.
- 02
API-sleutel aanmaken
Vul een Naam in, kies Verloopt over (dagen), kies bij Toegang tot kanalen voor Alle kanalen of Geselecteerde kanalen, en kies onder Rechten de minimale rechten die je integratie nodig heeft. Een request slaagt alleen als de sleutel precies de resource-actie heeft die het endpoint vereist. Kies Sleutel aanmaken.
- 03
Bewaar je API-sleutel
De volledige sleutel wordt maar één keer getoond. Kopieer hem naar je geheimenbeheer en kies daarna Ik heb hem bewaard.
- 04
Stuur de sleutel mee
Gebruik een Bearer-token, of stuur dezelfde waarde mee in
x-api-key. Zet sleutels nooit in querystrings of browsercode.
cURL
curl https://www.usesonny.com/api/v1/contacts?limit=25 \
--header "Authorization: Bearer sonny_your_key"Sleutels blijven veilig
- Beveiliging van sleutels
- Sleutels hebben het voorvoegsel
sonny_, 64 willekeurige tekens, worden eenrichtings gehasht opgeslagen, hebben een instelbare vervaldatum en een limiet van 600 requests per minuut per sleutel. Een sleutel hoort bij één werkruimte. - Wil je een sleutel intrekken? Kies de prullenbakknop ernaast. Bevestig API-sleutel intrekken? met Verwijderen. De sleutel werkt dan direct niet meer.
- Autorisatie bij elke aanroep
- Sonny controleert de hash en de rechten, en daarna opnieuw het actieve werkruimtelidmaatschap, de rol en de facturatiestatus van de maker. Verwijder of deactiveer je die gebruiker, dan worden diens sleutels direct uitgeschakeld.
- Geselecteerde kanalen worden afgedwongen bij elke REST API- en MCP-aanroep. Endpoints voor contacten, eigenschappen, labels en webhookbeheer vereisen toegang tot alle kanalen. Voor formulierinzendingen kun je contacts:write samen met conversations:write op geselecteerde kanalen gebruiken; losse contact-endpoints blijven voor de hele werkruimte gelden.
Rechten
contacts:readcontacts:writetags:readtags:writeconversations:readconversations:writemessages:readmessages:writemessages:sendwebhooks:readwebhooks:writekb:readkb:writecsat:readattachments:writemembers:readcontact-memory:readcontact-memory:writereporting:read
Resources
- Contacten
- Beheer contacten, getypeerde eigenschappen, filters op exacte waarden en klantgeheugen. Archiveer een contact, of wis het definitief met al zijn gesprekken bij verzoeken om gegevensbescherming.
- Bronnen
- Vind de ingestelde bronnen en zie of elke bron chat, e-mail of allebei ondersteunt.
- Gesprekken
- Maak aanvragen aan vanuit formulieren, filter op wat aandacht nodig heeft, wijs medewerkers of teams toe, snooze, label en werk in bulk bij.
- Synchronisatie
- Speel duurzame wijzigingen in de werkruimte en verwijderrecords opnieuw af met een opgeslagen cursor.
- Leden en teams
- Vind teamleden aan wie je kunt toewijzen, hun beschikbaarheid en hun daadwerkelijke kanaaltoegang.
- Rapportages
- Lees rapporten over support, teams, AI, kennis, leads en beschikbaarheid.
- Berichten
- Lees de berichtgeschiedenis en uit bijlagen gehaalde inhoud, upload privébestanden, voeg interne notities toe en verstuur of bewerk antwoorden aan klanten.
- Webhooks
- Beheer endpoints, abonnementen, tests, afleveringen en nieuwe pogingen.
- Kennisbank
- Maak, lees, wijzig en verwijder artikelen en categorieën van het helpcentrum per bron.
- Klanttevredenheid
- Lees CSAT-scores voor de werkruimte, elk kanaal en elk gesprek, en toon losse beoordelingen, gefilterd op score, opmerking, toegewezen persoon of periode.
Sonny gebruiken vanuit een AI-tool
Sonny MCP biedt elke bewerking van de openbare API aan als tool. Clients koppelen door in te loggen met OAuth 2.1 — of met een API-sleutel met beperkte rechten — en elke aanroep houdt dezelfde rechten, werkruimtegrenzen en bedrijfsregels.
Lees de handleiding voor Sonny MCPResponses en fouten
Responses met verzamelingen gebruiken data en bevatten waar nodig paginering. Elke response bevat x-request-id; je kunt zelf een veilige request-ID meesturen, dan stuurt Sonny die terug. Fouten geven een veilige melding zonder gevoelige implementatiedetails prijs te geven.
{
"error": {
"type": "validation_error",
"message": "Invalid email address",
"requestId": "req_01J..."
}
}400- Ongeldige invoer, JSON, query of cursor.
401- API-sleutel ontbreekt, is ongeldig, verlopen of heeft niet de juiste rechten.
402- De facturatiestatus van de werkruimte blokkeert dit request.
403- De werkruimterol van de maker van de sleutel is niet toegestaan.
404- De resource bestaat niet in de werkruimte van de sleutel.
409- Het request conflicteert met een bestaande resource.
410- De sync-cursor is verlopen. Laad de huidige stand opnieuw en speel af vanaf een nieuwe cursor.
413- De upload is groter dan toegestaan.
422- De bron heeft geen e-mailkanaal of een ingestuurde veldwaarde is ongeldig.
429- De limiet per sleutel is overschreden.
500- Er is een onverwachte fout opgetreden. Probeer het opnieuw met de request-ID.
503- De wachtrij voor webhookafleveringen zit vol. Probeer het later opnieuw.
Limieten
Elke API-sleutel mag maximaal 600 requests per minuut doen. Elke response meldt het huidige venster via de standaardheaders RateLimit-Limit, RateLimit-Remaining en RateLimit-Reset, zodat clients zelf kunnen afremmen in plaats van te gokken. Wordt de limiet overschreden, dan geeft de API 429 terug met een Retry-After-header — wacht dat aantal seconden voordat je het opnieuw probeert.
Versies en uitfasering
De API heeft een versie in het URL-pad (/api/v1). Binnen een versie voegen we alleen dingen toe — nieuwe endpoints, nieuwe optionele velden, nieuwe enumwaarden. Ingrijpende wijzigingen komen in een nieuwe versie, en voordat een v1-endpoint verdwijnt, kondigen we dat minstens zes maanden van tevoren aan: op deze pagina, per e-mail aan eigenaren van werkruimtes met actieve API-sleutels, en via Deprecation- en Sunset-headers op de betreffende endpoints.
Een verzonden antwoord bewerken
- Geef je API-sleutel of MCP-koppeling de rechten
messages:readenmessages:senden toegang tot het kanaal van het antwoord. - Lees de berichten van het gesprek en kopieer de ID van een antwoord dat jij als mens hebt verstuurd. Een API-sleutel handelt namens de maker; OAuth handelt namens het gekoppelde teamlid.
- Stuur de nieuwe tekst met het request hieronder, of roep in MCP
edit_messageaan metconversationId,messageIdenbody. - Controleer het teruggegeven bericht. De ID, bijlagen, leesbevestiging en oorspronkelijke verzendtijd blijven gelijk.
curl --request PATCH \
https://www.usesonny.com/api/v1/conversations/conversation_1/messages/message_1 \
--header "Authorization: Bearer sonny_your_key" \
--header "Content-Type: application/json" \
--data '{"body":"The corrected reply"}'Bewerken corrigeert het transcript en de gekoppelde chatclients. Er wordt geen nieuwe e-mail of melding verstuurd, en al afgeleverde e-mails blijven ongewijzigd. Je kunt alleen je eigen menselijke antwoorden aan klanten bewerken; inkomende berichten, botantwoorden, interne notities en antwoorden van andere teamleden niet. Wacht tot een lopende e-mailaflevering klaar is voordat je bewerkt. De nieuwe tekst moet 1–50.000 tekens bevatten; eerdere HTML en linkvoorbeelden worden gewist. Integraties ontvangen een message.updated-webhook en een sync-event. Wie alleen pollt op nieuwere bericht-ID's, mist bewerkingen; gebruik de duurzame sync-feed.
Een gesprek aanmaken vanuit een formulier
Stuur een formulierinzending naar POST /api/v1/conversations. Sonny zoekt het contact op e-mailadres of maakt het aan, slaat de antwoorden op en opent een inkomend gesprek op het e-mailkanaal van de bron die je kiest. Het team, de toewijzingsregels en de meldingen van het kanaal zijn van toepassing. Medewerkers antwoorden per e-mail.
- Maak een sleutel aan met
conversations:writeencontacts:write. Je kunt hem beperken tot de geselecteerde kanalen van de klant. Zoek de bron-ID op metGET /api/v1/sources, waarvoor ookconversations:readnodig is. - Voeg in n8n een HTTP Request-node toe: methode POST, URL
https://www.usesonny.com/api/v1/conversations. Bewaar de sleutel in een Header Auth-credential:Authorizationmet de waardeBearer sonny_your_key. - Zet Send Body aan, kies JSON en Using JSON, zet daarna het hele JSON-veld op Expression en plak dit voorbeeld. Vervang de bron-ID en koppel de invoervelden aan je formulier. Gebruik de vaste, unieke inzendings-ID van het formulier, zodat een nieuwe poging dezelfde waarde gebruikt.
{{ {
sourceId: "YOUR_CLIENT_SOURCE_ID",
contact: { email: $json.email, name: $json.name },
subject: "Website enquiry",
message: $json.message,
fields: {
Company: String($json.company ?? ""),
Budget: String($json.budget ?? ""),
Service: String($json.service ?? "")
},
externalId: "website-form-" + $json.submissionId
} }}Meer node-opties vind je in de n8n-handleiding voor HTTP Request. De bijbehorende MCP-tool is create_conversation, met dezelfde payload en rechten.
Nieuwe veldnamen worden teksteigenschappen. Bestaande getal-, URL-, datum- en keuzevelden moeten geldige tekstwaarden krijgen; een ongeldige waarde geeft 422 met de naam van het veld, en er wordt niets opgeslagen. Datums accepteren ISO-datums of tijdstempels; keuzewaarden moeten overeenkomen met een optie. Er worden maximaal 50 velden geaccepteerd, met namen tot 100 tekens en waarden tot 5.000 tekens. Eigenschappen verschijnen bij het contact en in de zijbalk van het gesprek. Beide berichtteksten bevatten een kopie van de antwoorden, ook als je de optionele htmlMessage meestuurt.
De optionele tags accepteert maximaal 20 bestaande label-ID's uit de werkruimte. De response bevat conversation, een samenvatting van contact, message en deduplicated. Nieuwe inzendingen geven 201 terug. Gebruik je externalId opnieuw op dezelfde bron, dan krijg je 200 met de oorspronkelijke ID's en deduplicated: true; gewijzigde inhoud wordt genegeerd. Zonder externe ID maakt elke aanroep een nieuw gesprek aan. Bijlagen bij het aanmaken en automatische AI-antwoorden worden niet ondersteund.
Agent-workflows
Triëren, handelen en gesynchroniseerd blijven
REST en MCP delen dezelfde rechten en workflows. Inloggegevens kunnen je huidige kanaaltoegang alleen verder beperken; haal je een kanaal uit je lidmaatschap, dan verdwijnt het ook uit je integraties.
Gesprekken vinden die aandacht nodig hebben
Filter op awaitingReply, unread, unassigned, assigneeId, agentGroupId, snoozed, priority of tagIds. Wacht op antwoord negeert interne notities; ongelezen geldt specifiek voor het ingelogde teamlid. Niet toegewezen betekent geen individuele toegewezen persoon, ook als er wel een team is toegewezen. Labels matchen op elke opgegeven ID.
GET /api/v1/conversations?status=open&awaitingReply=true&compact=true&sort=waitingSince&direction=ascSorteer op waitingSince, lastMessageAt, createdAt of zakelijke prioriteit, met direction asc of desc. ID's beslissen bij gelijke waarden. Weggelaten filters houden compact=false en snoozed=any aan. REST-tagIds accepteert ID's gescheiden door komma's; MCP accepteert ook een array. waitingSince begint bij het eerste inkomende bericht na het laatste antwoord; vervolgberichten en interne notities resetten het niet. Laat deze scan van de wachtrij volgens een schema draaien, ook als er geen webhook binnenkomt, zodat oude threads weer bovenkomen.
Bijblijven zonder de inbox opnieuw te lezen
Gebruik GET /api/v1/sync met conversations:read. De duurzame feed bevat gesprekswijzigingen, labels, berichten, contacteigenschappen, geheugen en verwijderrecords. Elke payload vereist ook een eigen leesrecht: berichtteksten hebben messages:read nodig en geheugen heeft contact-memory:read nodig. Beperkte inloggegevens ontvangen alleen toegestane kanalen.
- Begin zonder cursor, volg nextCursor tot hasMore false is en sla die cursor op.
- Lees de huidige lijsten met gesprekken en contacten en de geschiedenis die je nodig hebt voor je beginstand.
- Speel af vanaf de opgeslagen cursor om wijzigingen tijdens dat lezen op te vangen. Verwerk elke pagina en sla daarna nextCursor op.
Ontdubbel op event-id: het afspelen gebeurt minstens één keer, dus acties verderop hebben hun eigen bescherming tegen dubbele verwerking nodig. Een request zonder cursor beslaat het laatste uur, geen volledige momentopname. Events worden 30 dagen bewaard; HTTP 410 resync_required betekent dat je opnieuw moet beginnen. Begin ook opnieuw na het verruimen van rechten of kanaaltoegang. Gebruik limit tot 100 en maxBodyChars tot 10.000 (standaard 500). Zet compact=true voor de berichtvelden textPreview/textTruncated, begrensd op 200 tekens, in plaats van body/bodyTruncated. Webhooks kunnen een agent wekken; de feed blijft beschikbaar zonder webhookabonnementen of als de webhookaflevering achterloopt.
Controles één keer vastleggen en het resultaat delen
Lees list_conversation_checks (GET /api/v1/conversations/{conversationId}/checks) voordat je een onderzoek herhaalt. Sla een resultaat op met record_conversation_check (PUT naar hetzelfde pad), met key, result, checkedBy en een optionele reference voor de kaart-ID of URL. Bijvoorbeeld: key=product-version, result=Shopstar Go verified, checkedBy=Engineer, reference=card-X. Sonny legt de ingelogde actorId en het tijdstempel checkedAt vast. Hergebruik je een key, dan wordt alleen die controle vervangen; dit is de huidige stand, geen geschiedenislog. Lezen vereist conversations:read en schrijven conversations:write, allebei beperkt tot het kanaal van het gesprek. Deze aanroepen versturen geen antwoord en markeren het gesprek niet als beantwoord.
Werk in bulk toewijzen en bijwerken
Vind actieve teamleden en teams aan wie je kunt toewijzen met GET /api/v1/members and /teams (members:read). Responses bevatten beschikbaarheid en daadwerkelijke kanaaltoegang, zonder e-mailadressen. Gebruik conversations:write om status, priority, assigneeId, agentGroupId, snoozedUntil, snoozedUntilReply, addTagIds of removeTagIds te wijzigen.
POST /api/v1/conversations/batch
{
"conversationIds": ["conversation_1", "conversation_2"],
"updates": { "agentGroupId": "team_1", "assignment": "round_robin" }
}Round-robin kiest een beschikbaar teamlid dat toegang heeft tot het kanaal van het gesprek. Is er niemand geschikt, dan geeft een losse update 409 terug en mislukt een item in de bulkactie. Elke bulkactie accepteert maximaal 100 unieke ID's en past per gesprek één patch atomair toe. Controleer elk { id, ok, error? }-resultaat; sommige items kunnen mislukken. Bulkacties vallen onder de huidige limiet per request, zonder extra gewicht per aantal items.
Klantcontext delen met Sonny AI
Toon, bewaar en verwijder contactgeheugen met contact-memory:read/write. Geef zowel contactId als een toegankelijke sourceId mee; het contact moet een gesprek op die bron hebben. Opgeslagen feiten gebruiken dezelfde validatie, verwerking van dubbelingen en limieten als de app en worden vastgelegd als handmatig geheugen.
Lees eigenschapsdefinities via /api/v1/properties en lees of stel waarden in via /api/v1/contacts/{contactId}/properties. MCP biedt list_properties, get_contact_properties en set_contact_property. Hiervoor zijn contacts:read/write en toegang tot alle kanalen nodig. Geef precies één propertyId of propertyName op, met een tekstwaarde of null om hem te wissen. Waarden voor tekst, getal, URL, datum en keuze worden gevalideerd tegen de velddefinitie.
PUT /api/v1/contacts/contact_1/properties
{ "propertyName": "Plan", "value": "Pro" }
GET /api/v1/contacts?property[Plan]=ProEigenschapsfilters matchen op exact opgeslagen tekst; bij meerdere eigenschappen moeten ze allemaal overeenkomen. Waarden die via de API zijn ingesteld, worden in AI Copilot en de autoresponder gelabeld als API-gegevens. Bestaande regels voor geverifieerde klanten en bronnen blijven gelden. Gewone handmatige interne veldwaarden blijven buiten deze AI-context.
Dezelfde rapporten lezen als je team
Roep met reporting:read GET /api/v1/reporting/{kind} aan. De soorten zijn overview, volume, response-times, agents, sources, tags, csat, ai, knowledge, leads en online-hours. Overview combineert aantallen, reactietijden en CSAT. Filters zijn period (1–365 dagen, standaard 30), from/to als paar (to telt niet mee), granularity (day/month), source, assigneeId en tagId. Source accepteert all, all-chat, all-email, website:{id} of email:{id}.
Rapporten gebruiken dezelfde queries als het dashboard en de huidige toegangscontroles. Knowledge gebruikt datums en toegestane kanalen, los van de gekozen bron, toegewezen persoon of label. Online-hours meet de aanwezigheid van toegankelijke teamleden in de werkruimte; de gespreksaantallen daarin blijven beperkt tot kanalen. De bestaande /csat-endpoints houden hun eigen recht csat:read en kunnen een andere groep beschrijven.
Bestanden meesturen met antwoorden of interne notities
Geef attachments:write en upload een bestand van maximaal 25 MB voor een gesprek. POST /api/v1/attachments gebruikt de multipart-velden file en conversationId. De response bevat een id en expiresAt. Geef binnen een uur maximaal 10 attachmentIds mee aan een antwoord of notitie. Elke upload is gekoppeld aan jouw gebruiker en gesprek en kan maar één keer worden gebruikt. Ongebruikte uploads worden na het verlopen opgeruimd.
POST /api/v1/conversations/conversation_1/reply
{ "attachmentIds": ["upload_1"] }Antwoorden vereisen messages:send; interne notities vereisen messages:write en bereiken klanten nooit. Berichten met alleen bijlagen worden ondersteund. E-mailantwoorden bevatten bestanden binnen de maximale e-mailgrootte en downloadlinks voor de rest; offline chatmails bevatten links naar bestanden. Gemailde links blijven bruikbaar zolang de bijlage bestaat, zodat ontvangers ze later kunnen openen. Wie de e-mail doorstuurt, deelt ook toegang tot die bestanden. Controleer emailDeliveryStatus op mislukte afleveringen.
Geautoriseerde berichten bevatten downloadUrl, downloadExpiresAt, aiStatus, aiDescription en aiExtractedText, plus videoTranscripts voor gelinkte video's (Loom, Vimeo en andere). Downloadlinks zijn 15 minuten geldig; lees het bericht opnieuw voor verse links. Nieuwe uploads via API/MCP worden privé opgeslagen. Oudere bijlagen blijven openbaar en zijn gemarkeerd met access=legacy_public: hun oorspronkelijke URL verloopt niet. Het lezen van een bericht start het lezen van de afbeeldingen als de werkruimte Sonny AI heeft. Het lezen van afbeeldingen en videotranscripten is kort na binnenkomst van een bericht klaar: zolang er nog iets loopt, begint de response met readsInProgress, waarvan nextStep precies aangeeft welke aanroep je moet doen. Geef waitSeconds (maximaal 30) mee om er in één request op te wachten. Widget- en realtimeberichten voor klanten bevatten nooit uitgelezen inhoud of transcripten.
Kennisbank
Synchroniseren vanuit een externe bron
Synchroniseer artikelen en categorieën met vaste externe ID's, importeer Markdown of HTML, upload afbeeldingen, stel de volgorde in en beheer lezersdoelgroepen. Een upsert herhalen werkt de bestaande inhoud bij.
- Kies de sourceId van je kanaal en geef kb:read en kb:write. Houd de API-sleutel op je server en beperk de Toegang tot kanalen.
- Maak de categorie aan en synchroniseer daarna een artikel als concept. Controleer de opmaak en toegang voordat je publiceert.
- Stel de toegang tot het helpcentrum in, publiceer en test de lezersweergave. Gebruik paginering en vaste externe ID's voor latere updates.
Klantdoelgroepen beheren
Maak groepen op basis van geverifieerde klantkenmerken en pas ze toe op een helpcentrum, categorie of artikel. Alle overgenomen beperkingen moeten overeenkomen. API- en MCP-inloggegevens handelen als medewerker binnen hun rechten; bekijk een voorbeeld en test met een echte klantsessie om de lezerstoegang te controleren.
Doelgroepen voor het helpcentrum instellen en testenGerelateerde handleidingen
- Sonny MCPBeta
Koppel AI-assistenten aan inboxworkflows, klantherinneringen, rapportages en bestanden met OAuth of sleutels met beperkte rechten.
- WebhooksBeta
Abonneer je op ondertekende werkruimtegebeurtenissen en bekijk afleverpogingen.
- Contacten
Lees hoe contacten in Sonny worden aangemaakt, beheerd, gelabeld en samengevoegd.
- Inbox
Begrijp statussen, prioriteiten, toewijzen, snoozen, bulkacties en sneltoetsen.