Entwickler
Sonny MCP Beta
Verbinde MCP-fähige KI-Assistenten – Claude und jeden Client, der das Model Context Protocol spricht – mit deinem Arbeitsbereich, mit denselben Berechtigungen und Grenzen wie bei der öffentlichen API.
Leitfaden zur öffentlichen API lesenSchnellstart
- 01
Sonny zu Claude hinzufügen
Füge in Claude oder Cowork einen benutzerdefinierten Connector mit der URL
https://www.usesonny.com/api/mcphinzu. Sonny unterstützt die automatische Client-Registrierung, du musst also keine Client-ID und kein Secret kopieren. - 02
Zugriff auf den Arbeitsbereich freigeben
Claude öffnet Sonny in deinem Browser. Melde dich an, prüfe die angefragten Berechtigungen und wähle den Arbeitsbereich, den du verbinden möchtest. OAuth 2.1 mit PKCE beschränkt die daraus entstehenden Access- und Refresh-Tokens auf genau diese Freigabe.
- 03
Bitte deinen Assistenten, Sonny zu nutzen
Tools beschreiben sich selbst, ein Prompt wie „Liste meine offenen Unterhaltungen auf“ reicht also aus. Assistenten sehen, welche Tools nur lesen und welche etwas verändern oder löschen – ein guter Client fragt also nach, bevor er etwas ändert.
Claude Code
claude mcp add --transport http sonny https://www.usesonny.com/api/mcpJSON-Konfiguration für Clients
{
"mcpServers": {
"sonny": {
"url": "https://www.usesonny.com/api/mcp"
}
}
}Kompatibilität mit API-Schlüsseln
Kann ein Client OAuth nicht abschließen, erstelle unter Einstellungen → Entwickler einen Schlüssel mit eingeschränkten Berechtigungen und sende ihn als Authorization-Bearer-Header. API-Schlüssel werden für Server-zu-Server-Verbindungen und ältere Clients weiterhin voll unterstützt.
"Authorization": "Bearer sonny_your_key"So hält Sonny Tool-Aufrufe sicher
- Ein Arbeitsbereich, gewählte Berechtigungen
- Jeder Aufruf läuft im Arbeitsbereich, der bei der OAuth-Zustimmung gewählt wurde, oder in dem Arbeitsbereich, zu dem der API-Schlüssel gehört. Ein Tool funktioniert nur, wenn die Zugangsdaten die nötige Berechtigung haben.
- Ehrliche Tool-Annotationen
- Tools, die nur lesen, sind als schreibgeschützt markiert; Tools, die aktualisieren oder löschen, sind als destruktiv markiert, damit dein Client vor dem Handeln nachfragen kann.
- Dieselben Geschäftsregeln
- Tools führen genau die Workflows der öffentlichen API aus – Änderungsverlauf, Benachrichtigungen und Webhooks verhalten sich so, als hätte ein Teammitglied die Änderung vorgenommen.
Einen Assistenten auf einen Posteingang beschränken
Ausgewählte Kanäle eines API-Schlüssels gelten automatisch für jeden Tool-Aufruf. API-Schlüssel und OAuth-Verbindungen folgen außerdem dem aktuellen Kanalzugriff des verbundenen Teammitglieds. Bei OAuth-Verbindungen oder Schlüsseln mit Zugriff auf alle Kanäle enthalten Arbeitsbereiche oft mehrere Quellen – eine pro Produkt oder Marke. Lass deinen Assistenten einmal list_sources aufrufen, um sie zu finden, und dann sourceId an list_conversations übergeben, damit Fragen zu einem Produkt nur dessen Unterhaltungen liefern. Jede Unterhaltung trägt außerdem ihre eigene sourceId, sodass sich die Ergebnisse überprüfen lassen.
Eine kostengünstige Support-Schleife betreiben
- Änderungen finden: Initialisiere mit dem dauerhaften
sync-Feed, speichere nextCursor nach jeder verarbeiteten Seite und dedupliziere Ereignis-IDs. Um Arbeit auszuwählen, rufelist_conversationsmit sourceId, awaitingReply: true, snoozed: "false" und compact: true auf. Interne Notizen verdecken keine unbeantworteten Kundennachrichten. - Nur neuen Text lesen: Rufe für jede geänderte Unterhaltung
list_messagesmit deiner letzten Nachrichten-ID oder einem ISO-Zeitstempel inafterauf und setzeincludeHtml: false, sofern du das E-Mail-HTML nicht wirklich brauchst. - Auf Bilder und Videos warten: Wenn
list_messagesreadsInProgresszurückgibt, führe den Aufruf aus dessennextStepaus. SeinwaitSecondshält die Antwort zurück, bis Bildauswertungen und Video-Transkripte fertig sind – du musst also nicht selbst warten. - Kundenkontext laden:
get_conversationliefertidentityVerified, signierteverifiedTraitssowie die Ursprungsseite und den Client-Kontext der Unterhaltung. Gibt es einecontact.id, übergib diese ID anlist_conversations, um die früheren Unterhaltungen des Kunden zu laden. - Bei Bedarf wecken: Nutze einen nach Quellen gefilterten Webhook für
message.created, um den Agent sofort zu wecken, und hole dann per Sync auf. Der dauerhafte Feed funktioniert unabhängig von der Webhook-Zustellung. Richte den Webhook mit Zugangsdaten für alle Kanäle ein und beschränke seine Quellen-IDs; der Agent behält seine auf die Quelle beschränkten Zugangsdaten für den laufenden Betrieb.
Tool-Katalog
Jede Operation der öffentlichen API ist als Tool verfügbar. Die nötige Berechtigung steht jeweils daneben.
- get_connection_info
- Read connection access
conversations:read- get_conversation_context
- Read support context
conversations:read- list_conversation_checks
- Read conversation checks
conversations:read- record_conversation_check
- Record a conversation check
conversations:write- get_status
- Check Sonny status
conversations:read- create_conversation
- Create a conversation from a form
conversations:write- upload_attachment
- Upload a message attachment
attachments:write- list_properties
- List custom properties
contacts:read- get_contact_properties
- Read contact properties
contacts:read- set_contact_property
- Set a contact property
contacts:write- list_contact_memories
- Read customer memories
contact-memory:read- create_contact_memory
- Save a customer memory
contact-memory:write- delete_contact_memory
- Remove a customer memory
contact-memory:write- get_report
- Read a support report
reporting:read- sync
- Read workspace changes
conversations:read- batch_update_conversations
- Update conversations in a batch
conversations:write- list_members
- List members
members:read- list_teams
- List teams
members:read- list_tags
- List tags
tags:read- create_tag
- Create a tag
tags:write- get_tag
- Get a tag
tags:read- update_tag
- Update a tag
tags:write- delete_tag
- Delete a tag
tags:write- add_conversation_tag
- Add a conversation tag
conversations:write- remove_conversation_tag
- Remove a conversation tag
conversations:write- list_contacts
- List contacts
contacts:read- create_contact
- Create a contact
contacts:write- get_contact
- Get a contact
contacts:read- update_contact
- Update a contact
contacts:write- archive_contact
- Archive a contact
contacts:write- erase_contact
- Permanently erase a contact
contacts:write- list_channels
- List conversation channels
conversations:read- list_sources
- List sources
conversations:read- list_conversations
- List conversations
conversations:read- get_conversation
- Get a conversation
conversations:read- update_conversation
- Update a conversation
conversations:write- list_messages
- List messages
messages:read- create_internal_note
- Create an internal note
messages:write- edit_message
- Edit a sent reply
messages:send- send_message
- Send a reply to the customer
messages:send- list_webhooks
- List webhook endpoints
webhooks:read- create_webhook
- Create a webhook endpoint
webhooks:write- list_webhook_events
- List webhook event types
webhooks:read- update_webhook
- Update a webhook endpoint
webhooks:write- delete_webhook
- Delete a webhook endpoint
webhooks:write- test_webhook
- Queue a test event
webhooks:write- list_webhook_deliveries
- List webhook deliveries
webhooks:read- retry_webhook_delivery
- Retry a failed delivery
webhooks:write- list_kb_articles
- List knowledge base articles
kb:read- create_kb_article
- Create a knowledge base article
kb:write- get_kb_article
- Get a knowledge base article
kb:read- update_kb_article
- Update a knowledge base article
kb:write- delete_kb_article
- Delete a knowledge base article
kb:write- list_kb_categories
- List knowledge base categories
kb:read- create_kb_category
- Create a knowledge base category
kb:write- update_kb_category
- Update a knowledge base category
kb:write- delete_kb_category
- Delete a knowledge base category
kb:write- get_csat_summary
- Get CSAT scores
csat:read- list_csat_ratings
- List CSAT ratings
csat:read- get_conversation_csat
- Get a conversation's CSAT rating
csat:read- reorder_kb_articles
- Reorder knowledge base articles
kb:write- upsert_kb_article
- Sync a knowledge base article
kb:write- reorder_kb_categories
- Reorder knowledge base categories
kb:write- upsert_kb_category
- Sync a knowledge base category
kb:write- get_kb_category
- Get a knowledge base category
kb:read- get_help_center
- Get help center settings
kb:read- update_help_center
- Update help center settings
kb:write- upload_kb_media
- Upload a help center image
kb:write- list_kb_audiences
- List audiences
kb:read- create_kb_audience
- Create audience
kb:write- update_kb_audience
- Update audience
kb:write- delete_kb_audience
- Delete audience
kb:write
Agent-Workflows
Sichten, handeln und synchron bleiben
REST und MCP teilen dieselben Berechtigungen und Workflows. Zugangsdaten können deinen aktuellen Kanalzugriff nur einschränken; entfernst du einen Kanal aus deiner Mitgliedschaft, verschwindet er auch aus deinen Integrationen.
Unterhaltungen mit Handlungsbedarf finden
Filtere nach awaitingReply, unread, unassigned, assigneeId, agentGroupId, snoozed, priority oder tagIds. awaitingReply ignoriert interne Notizen; unread bezieht sich auf das authentifizierte Teammitglied. unassigned bedeutet: keine einzelne zuständige Person, auch wenn ein Team zugewiesen ist. Labels passen, wenn eine der angegebenen IDs zutrifft.
list_conversations({ status: "open", awaitingReply: true, compact: true, sort: "waitingSince", direction: "asc" })Sortiere nach waitingSince, lastMessageAt, createdAt oder geschäftlicher Priorität mit der Richtung asc oder desc. Bei Gleichstand entscheidet die ID. Ohne Angabe gelten compact=false und snoozed=any. In REST akzeptiert tagIds kommagetrennte IDs; MCP akzeptiert auch ein Array. waitingSince beginnt mit der ersten eingehenden Nachricht nach der letzten Antwort; Nachfragen und interne Notizen setzen den Wert nicht zurück. Führe diesen Scan der Warteschlange regelmäßig aus, auch wenn kein Webhook eintrifft, damit alte Threads wieder auftauchen.
Aufholen, ohne den Posteingang neu zu lesen
Nutze sync mit conversations:read. Der dauerhafte Feed enthält Änderungen an Unterhaltungen, Labels, Nachrichten, Kontakteigenschaften, Gedächtnis-Einträgen sowie Löschvorgänge. Jede Payload braucht zusätzlich ihre eigene Lese-Berechtigung: Nachrichtentexte brauchen messages:read, Gedächtnis-Einträge contact-memory:read. Eingeschränkte Zugangsdaten erhalten nur erlaubte Kanäle.
- Starte ohne Cursor, folge nextCursor, bis hasMore false ist, und speichere diesen Cursor.
- Lies die aktuellen Unterhaltungs- und Kontaktlisten sowie den Verlauf, den du für deinen Ausgangszustand brauchst.
- Spiele ab dem gespeicherten Cursor erneut ab, um Änderungen während dieses Lesens aufzufangen. Verarbeite jede Seite und speichere dann nextCursor.
Dedupliziere anhand der Ereignis-id: Die Wiedergabe erfolgt mindestens einmal, nachgelagerte Aktionen brauchen also einen eigenen Duplikatschutz. Eine Anfrage ohne Cursor deckt die letzte Stunde ab, keinen vollständigen Snapshot. Ereignisse werden 30 Tage aufbewahrt; HTTP 410 resync_required heißt: neu initialisieren. Initialisiere auch neu, nachdem du Berechtigungen oder Kanalzugriff erweitert hast. Verwende limit bis 100 und maxBodyChars bis 10.000 (Standard 500). Setze compact=true für die Nachrichtenfelder textPreview/textTruncated mit maximal 200 Zeichen statt body/bodyTruncated. Webhooks können einen Agent wecken; der Feed bleibt auch ohne Webhook-Abonnements oder bei einem Rückstau in der Webhook-Zustellung verfügbar.
Prüfungen einmal festhalten und das Ergebnis teilen
Bevor du eine Untersuchung wiederholst, lies list_conversation_checks (GET /api/v1/conversations/{conversationId}/checks). Speichere ein Ergebnis mit record_conversation_check (PUT auf denselben Pfad) und gib key, result, checkedBy und optional eine reference für die Karten-ID oder URL an. Zum Beispiel: key=product-version, result=Shopstar Go verified, checkedBy=Engineer, reference=card-X. Sonny speichert die authentifizierte actorId und den Zeitstempel checkedAt. Wird ein key erneut verwendet, ersetzt das nur diese Prüfung; es ist der aktuelle Stand, kein Verlaufsprotokoll. Lesen braucht conversations:read, Schreiben conversations:write, beides beschränkt auf den Kanal der Unterhaltung. Diese Aufrufe senden keine Antwort und markieren die Anfrage nicht als beantwortet.
Arbeit im Stapel zuweisen und aktualisieren
Finde aktive, zuweisbare Teammitglieder und Teams mit list_members / list_teams (members:read). Die Antworten enthalten Verfügbarkeit und tatsächlichen Kanalzugriff, aber keine E-Mail-Adressen. Mit conversations:write änderst du status, priority, assigneeId, agentGroupId, snoozedUntil, snoozedUntilReply, addTagIds oder removeTagIds.
batch_update_conversations({
conversationIds: ["conversation_1", "conversation_2"],
updates: { agentGroupId: "team_1", assignment: "round_robin" }
})Round-Robin wählt ein verfügbares Teammitglied, das Zugriff auf den Kanal der Unterhaltung hat. Gibt es kein passendes Mitglied, liefert eine einzelne Aktualisierung 409 und ein Stapel-Eintrag schlägt fehl. Jeder Stapel akzeptiert bis zu 100 eindeutige IDs und wendet pro Unterhaltung einen Patch atomar an. Prüfe jedes { id, ok, error? }-Ergebnis; einzelne Einträge können fehlschlagen. Stapel unterliegen dem normalen anfragebasierten Rate-Limit, ohne Gewichtung nach Anzahl der Einträge.
Kundenkontext mit Sonny AI teilen
Liste, speichere und entferne Gedächtnis-Einträge zu Kontakten mit contact-memory:read/write. Gib sowohl contactId als auch eine zugängliche sourceId an; der Kontakt muss auf dieser Quelle eine Unterhaltung haben. Gespeicherte Fakten durchlaufen dieselbe Validierung, Duplikatbehandlung und dieselben Limits wie in der App und werden als manuelle Gedächtnis-Einträge gespeichert.
Lies Eigenschaftsdefinitionen unter /api/v1/properties und lies oder setze Werte unter /api/v1/contacts/{contactId}/properties. MCP stellt list_properties, get_contact_properties und set_contact_property bereit. Dafür sind contacts:read/write und Zugriff auf alle Kanäle nötig. Gib genau eine propertyId oder einen propertyName an, mit einem String-Wert oder null zum Leeren. Text-, Zahlen-, URL-, Datums- und Auswahlwerte werden gegen die Felddefinition geprüft.
set_contact_property({ contactId: "contact_1", propertyName: "Plan", value: "Pro" })
list_contacts({ property: { Plan: "Pro" } })Eigenschaftsfilter vergleichen exakt gespeicherte Strings; mehrere Eigenschaften müssen alle zutreffen. Per API geschriebene Werte sind im Co-Pilot und im Autoresponder als API-Daten gekennzeichnet. Bestehende Regeln für verifizierte Kunden und Quellen gelten weiterhin. Normale, manuell gepflegte interne Feldwerte bleiben aus diesem KI-Kontext ausgeschlossen.
Dieselben Berichte lesen wie dein Team
Rufe mit reporting:read get_report({ kind, filters }) auf. Verfügbare Arten sind overview, volume, response-times, agents, sources, tags, csat, ai, knowledge, leads und online-hours. overview kombiniert Anzahlen, Antwortzeiten und CSAT. Filter sind period (1–365 Tage, Standard 30), from/to als Paar (to ist exklusiv), granularity (day/month), source, assigneeId und tagId. source akzeptiert all, all-chat, all-email, website:{id} oder email:{id}.
Berichte nutzen dieselben Abfragen wie das Dashboard und die aktuellen Zugriffsprüfungen. knowledge berücksichtigt Datum und erlaubte Kanäle, unabhängig von gewählter Quelle, zuständiger Person oder Label. online-hours misst die Anwesenheit zugänglicher Teammitglieder im Arbeitsbereich; die Anzahl der Unterhaltungen bleibt auf Kanäle beschränkt. Die bestehenden /csat-Endpunkte behalten ihre eigene Berechtigung csat:read und können eine andere Grundgesamtheit beschreiben.
Dateien mit Antworten oder internen Notizen senden
Erteile attachments:write und lade für eine Unterhaltung eine Datei bis 25 MB hoch. upload_attachment erwartet conversationId, fileName, contentType und dataBase64. Die Antwort enthält eine id und expiresAt. Übergib innerhalb einer Stunde bis zu 10 attachmentIds an eine Antwort oder Notiz. Jeder Upload ist an deinen Benutzer und die Unterhaltung gebunden und kann nur einmal verwendet werden. Ungenutzte Uploads werden nach Ablauf entfernt.
send_message({ conversationId: "conversation_1", attachmentIds: ["upload_1"] })Antworten erfordern messages:send; interne Notizen erfordern messages:write und erreichen niemals Kunden. Nachrichten nur mit Anhängen werden unterstützt. E-Mail-Antworten enthalten Dateien bis zur E-Mail-Größengrenze und Download-Links für den Rest; Offline-Chat-E-Mails enthalten Datei-Links. Links in E-Mails bleiben nutzbar, solange der Anhang existiert, sodass Empfänger sie auch später öffnen können. Wer die E-Mail weiterleitet, teilt den Zugriff auf diese Dateien. Prüfe emailDeliveryStatus auf Zustellfehler.
Autorisierte Nachrichten-Abrufe enthalten downloadUrl, downloadExpiresAt, aiStatus, aiDescription und aiExtractedText sowie videoTranscripts für verlinkte Videos (Loom, Vimeo und andere). Download-Links gelten 15 Minuten; lies die Nachricht erneut für frische Links. Neue Uploads über API/MCP werden privat gespeichert. Ältere Anhänge bleiben öffentlich und sind mit access=legacy_public gekennzeichnet: Ihre ursprüngliche URL läuft nicht ab. Das Lesen einer Nachricht startet die Bildauswertung, wenn der Arbeitsbereich Sonny AI hat. Bildauswertungen und Video-Transkripte sind kurz nach Eingang einer Nachricht fertig: Solange noch welche laufen, beginnt die Antwort mit readsInProgress, dessen nextStep den genauen nächsten Aufruf angibt. Übergib waitSeconds (bis 30), um in einer einzigen Anfrage darauf zu warten. Kundenseitige Widget- und Echtzeit-Nachrichten enthalten nie Extraktionen oder Transkripte.
Wissensdatenbank
Aus einer externen Quelle synchronisieren
Synchronisiere Artikel und Kategorien über stabile externe IDs, importiere Markdown oder HTML, lade Bilder hoch, lege die Reihenfolge fest und verwalte Leser-Zielgruppen. Ein wiederholtes Upsert aktualisiert die vorhandenen Inhalte.
- Wähle die sourceId deines Kanals und erteile kb:read und kb:write. Für die optionale Erkennung braucht
list_sourceszusätzlich conversations:read. - Erstelle die Kategorie und synchronisiere dann einen Artikel als Entwurf. Prüfe Formatierung und Zugriff, bevor du veröffentlichst.
- Richte den Zugriff auf das Hilfecenter ein, veröffentliche und teste die Leseransicht. Nutze Paginierung und stabile externe IDs für spätere Aktualisierungen.
Kunden-Zielgruppen verwalten
Erstelle Gruppen aus verifizierten Kundenmerkmalen und wende sie auf ein Hilfecenter, eine Kategorie oder einen Artikel an. Alle geerbten Einschränkungen müssen zutreffen. API- und MCP-Zugangsdaten handeln innerhalb ihrer Berechtigungen als Mitarbeitende; nutze die Vorschau und teste eine echte Kundensitzung, um den Leserzugriff zu prüfen.
Hilfecenter-Zielgruppen einrichten und testenVerwandte Anleitungen
- Öffentliche APIBeta
Sichte und synchronisiere Unterhaltungen, teile Kundenkontext, lies Berichte und sende Dateien – mit API-Schlüsseln mit gezielten Berechtigungen.
- WebhooksBeta
Abonniere signierte Ereignisse aus deinem Arbeitsbereich und prüfe die Zustellversuche.
- Team & Rollen
Lade Nutzer ein, erstelle Teams und versteh die Rechte von Inhaber, Admin, Agent und Betrachter.