Développeurs
Sonny MCP Beta
Connectez à votre espace de travail des assistants IA compatibles MCP — Claude, et tout client qui parle le Model Context Protocol — avec les mêmes portées et les mêmes limites que l'API publique.
Lire le guide de l'API publiqueDémarrage rapide
- 01
Ajouter Sonny à Claude
Dans Claude ou Cowork, ajoutez un connecteur personnalisé avec l'URL
https://www.usesonny.com/api/mcp. Sonny prend en charge l'enregistrement automatique des clients : aucun identifiant ni secret client à copier. - 02
Approuver l'accès à l'espace de travail
Claude ouvre Sonny dans votre navigateur. Connectez-vous, vérifiez les permissions demandées et choisissez l'espace de travail à connecter. OAuth 2.1 avec PKCE limite les jetons d'accès et de rafraîchissement obtenus à cette approbation.
- 03
Demander à votre assistant d'utiliser Sonny
Les outils se décrivent eux-mêmes : une demande comme « Liste mes conversations ouvertes » suffit. Les assistants voient quels outils sont en lecture seule et lesquels sont destructifs, donc un bon client demande avant de modifier quoi que ce soit.
Claude Code
claude mcp add --transport http sonny https://www.usesonny.com/api/mcpConfiguration JSON du client
{
"mcpServers": {
"sonny": {
"url": "https://www.usesonny.com/api/mcp"
}
}
}Compatibilité avec les clés API
Si un client ne peut pas mener à bien OAuth, créez une clé à portée limitée dans Paramètres → Développeur et envoyez-la dans un en-tête Authorization Bearer. Les clés API restent entièrement prises en charge pour les échanges de serveur à serveur et les anciens clients.
"Authorization": "Bearer sonny_your_key"Comment Sonny sécurise les appels d'outils
- Un espace de travail, des portées choisies
- Chaque appel s'exécute dans l'espace de travail choisi lors du consentement OAuth ou dans celui qui possède la clé API. Un outil ne fonctionne que si son identifiant dispose de la portée requise.
- Des annotations d'outils fiables
- Les outils en lecture seule sont marqués comme tels ; les outils de mise à jour et de suppression sont marqués destructifs pour que votre client puisse demander confirmation avant d'agir.
- Les mêmes règles métier
- Les outils exécutent exactement les mêmes workflows que l'API publique — historique d'audit, notifications et webhooks se comportent comme si un collègue avait effectué la modification.
Garder un assistant dans une seule boîte de réception
Les canaux sélectionnés sur une clé API sont automatiquement appliqués à chaque appel d'outil. Les clés API et les connexions OAuth suivent aussi l'accès actuel aux canaux du collègue connecté. Pour les connexions OAuth ou les clés ayant accès à tous les canaux, les espaces de travail contiennent souvent plusieurs sources — une par produit ou par marque. Demandez à votre assistant d'appeler list_sources une fois pour les découvrir, puis de passer sourceId à list_conversations : les questions sur un produit ne renverront alors que les conversations de ce produit. Chaque conversation porte aussi son propre sourceId, ce qui rend les résultats vérifiables.
Faire tourner une boucle de support peu coûteuse
- Découvrir les changements : initialisez avec le flux durable
sync, enregistrez nextCursor après le traitement de chaque page et dédupliquez les identifiants d'événements. Pour choisir le travail, appelezlist_conversationsavec sourceId, awaitingReply: true, snoozed: "false" et compact: true. Les notes internes ne masquent pas les messages clients sans réponse. - Ne lire que le nouveau texte : pour chaque conversation modifiée, appelez
list_messagesavec votre dernier identifiant de message ou horodatage ISO dansafteret définissezincludeHtml: false, sauf si le HTML de l'e-mail est vraiment nécessaire. - Attendre les images et les vidéos : quand
list_messagesrenvoiereadsInProgress, effectuez l'appel indiqué dans sonnextStep. SonwaitSecondsretient la réponse jusqu'à ce que les lectures d'images et les transcriptions vidéo soient prêtes : inutile de mettre en pause. - Charger le contexte client :
get_conversationrenvoieidentityVerified, lesverifiedTraitssignés, ainsi que la page d'origine de la conversation et le contexte client. Lorsqu'elle comporte uncontact.id, passez cet identifiant àlist_conversationspour charger les conversations précédentes du client. - Réveiller à la demande : utilisez un webhook filtré par source pour
message.createdafin de réveiller l'agent immédiatement, puis rattrapez votre retard avec sync. Le flux durable fonctionne indépendamment de la livraison des webhooks. Utilisez un identifiant couvrant tous les canaux pour créer le webhook et restreindre ses identifiants de source ; l'agent conserve son identifiant d'exécution limité à la source.
Catalogue d'outils
Chaque opération de l'API publique est disponible sous forme d'outil. La portée requise est indiquée à côté de chacun.
- 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
Workflows d'agent
Trier, agir et rester synchronisé
REST et MCP partagent les mêmes permissions et les mêmes workflows. Les identifiants ne peuvent que restreindre votre accès actuel aux canaux ; retirer un canal de votre appartenance le retire aussi de vos intégrations.
Trouver les conversations qui demandent de l'attention
Filtrez par awaitingReply, unread, unassigned, assigneeId, agentGroupId, snoozed, priority ou tagIds. awaitingReply ignore les notes internes ; unread est propre au collègue authentifié. unassigned signifie sans responsable individuel, même si une équipe est attribuée. Les étiquettes correspondent à n'importe lequel des identifiants fournis.
list_conversations({ status: "open", awaitingReply: true, compact: true, sort: "waitingSince", direction: "asc" })Triez par waitingSince, lastMessageAt, createdAt ou priorité métier, avec la direction asc ou desc. Les identifiants départagent les égalités. Les filtres omis conservent compact=false et snoozed=any. En REST, tagIds accepte des identifiants séparés par des virgules ; MCP accepte aussi un tableau. waitingSince démarre au premier message entrant après la dernière réponse ; les relances et les notes internes ne le réinitialisent pas. Lancez cette analyse de la file d'attente de façon planifiée, même quand aucun webhook n'arrive, pour faire ressortir les anciens fils.
Rattraper son retard sans relire la boîte de réception
Utilisez sync avec conversations:read. Le flux durable inclut les changements de conversations, les étiquettes, les messages, les propriétés de contact, les souvenirs et les traces de suppression. Chaque charge utile exige aussi sa propre portée de lecture : le corps des messages nécessite messages:read et les souvenirs contact-memory:read. Les identifiants restreints ne reçoivent que les canaux autorisés.
- Commencez sans curseur, suivez nextCursor jusqu'à ce que hasMore soit false, puis enregistrez ce curseur.
- Lisez les listes actuelles de conversations et de contacts, ainsi que l'historique nécessaire à votre état initial.
- Rejouez depuis le curseur enregistré pour récupérer les changements survenus pendant cette lecture. Traitez chaque page, puis enregistrez nextCursor.
Dédupliquez par id d'événement : la relecture garantit au moins une livraison, donc les actions en aval doivent avoir leur propre protection contre les doublons. Une requête sans curseur couvre la dernière heure, pas un instantané complet. Les événements sont conservés 30 jours ; un HTTP 410 resync_required signifie qu'il faut tout recharger. Rechargez aussi après avoir élargi les portées ou l'accès aux canaux. Utilisez limit jusqu'à 100 et maxBodyChars jusqu'à 10 000 (500 par défaut). Définissez compact=true pour obtenir les champs de message textPreview/textTruncated limités à 200 caractères au lieu de body/bodyTruncated. Les webhooks peuvent réveiller un agent ; le flux reste disponible sans abonnement aux webhooks ou lorsque la livraison des webhooks prend du retard.
Enregistrer une vérification une fois et partager le résultat
Avant de recommencer une investigation, lisez list_conversation_checks (GET /api/v1/conversations/{conversationId}/checks). Enregistrez un résultat avec record_conversation_check (PUT sur le même chemin), en fournissant key, result, checkedBy et une reference optionnelle pour l'identifiant ou l'URL de la carte. Par exemple : key=product-version, result=Shopstar Go verified, checkedBy=Engineer, reference=card-X. Sonny enregistre l'actorId authentifié et l'horodatage checkedAt. Réutiliser une key remplace uniquement cette vérification ; il s'agit d'un état actuel, pas d'un historique. Les lectures nécessitent conversations:read et les écritures conversations:write, toutes deux limitées au canal de la conversation. Ces appels n'envoient pas de réponse et ne marquent pas le vendeur comme ayant répondu.
Attribuer et mettre à jour le travail par lots
Découvrez les collègues et équipes actifs et attribuables avec list_members / list_teams (members:read). Les réponses incluent la disponibilité et l'accès effectif aux canaux, sans les adresses e-mail. Utilisez conversations:write pour modifier status, priority, assigneeId, agentGroupId, snoozedUntil, snoozedUntilReply, addTagIds ou removeTagIds.
batch_update_conversations({
conversationIds: ["conversation_1", "conversation_2"],
updates: { agentGroupId: "team_1", assignment: "round_robin" }
})Le tourniquet choisit un membre d'équipe disponible qui a accès au canal de la conversation. Sans membre éligible, une mise à jour individuelle renvoie 409 et un élément de lot échoue. Chaque lot accepte jusqu'à 100 identifiants uniques et applique un correctif de façon atomique par conversation. Examinez chaque résultat { id, ok, error? } ; certains éléments peuvent échouer. Les lots utilisent la limite de débit actuelle par requête, sans décompte pondéré selon le nombre d'éléments.
Partager le contexte client avec Sonny AI
Listez, enregistrez et supprimez les souvenirs de contact avec contact-memory:read/write. Fournissez à la fois contactId et un sourceId accessible ; le contact doit avoir une conversation sur cette source. Les faits enregistrés suivent la même validation, la même gestion des doublons et les mêmes limites que l'application, et sont enregistrés comme souvenirs manuels.
Lisez les définitions de propriétés sur /api/v1/properties et lisez ou définissez les valeurs sur /api/v1/contacts/{contactId}/properties. MCP expose list_properties, get_contact_properties et set_contact_property. Ils nécessitent contacts:read/write et l'accès à tous les canaux. Définissez exactement un propertyId ou un propertyName, avec une valeur texte ou null pour l'effacer. Les valeurs texte, nombre, URL, date et liste sont validées par rapport à la définition du champ.
set_contact_property({ contactId: "contact_1", propertyName: "Plan", value: "Pro" })
list_contacts({ property: { Plan: "Pro" } })Les filtres de propriétés correspondent aux chaînes stockées exactes ; plusieurs propriétés doivent toutes correspondre. Les valeurs écrites via l'API sont signalées comme données API dans Co-Pilot et le répondeur automatique. Les règles existantes sur les clients vérifiés et les sources s'appliquent toujours. Les valeurs de champs internes saisies manuellement restent exclues de ce contexte IA.
Lire les mêmes rapports que votre équipe
Avec reporting:read, appelez get_report({ kind, filters }). Les types sont overview, volume, response-times, agents, sources, tags, csat, ai, knowledge, leads et online-hours. overview combine les totaux, les temps de réponse et le CSAT. Les filtres sont period (1 à 365 jours, 30 par défaut), les dates from/to appariées (to est exclusif), granularity (day/month), source, assigneeId et tagId. source accepte all, all-chat, all-email, website:{id} ou email:{id}.
Les rapports utilisent les requêtes du tableau de bord et les contrôles d'accès actuels. knowledge utilise les dates et les canaux autorisés, indépendamment de la source, du responsable ou de l'étiquette sélectionnés. online-hours mesure la présence des collègues accessibles dans l'espace de travail ; ses totaux de conversations restent limités aux canaux. Les points de terminaison /csat existants conservent leur portée distincte csat:read et peuvent décrire une population différente.
Envoyer des fichiers avec des réponses ou des notes internes
Accordez attachments:write et importez un fichier de 25 Mo maximum pour une conversation. upload_attachment prend conversationId, fileName, contentType et dataBase64. La réponse contient un id et expiresAt. Passez jusqu'à 10 attachmentIds à une réponse ou une note dans l'heure. Chaque fichier importé est lié à votre utilisateur et à la conversation et ne peut être utilisé qu'une seule fois. Les fichiers inutilisés sont nettoyés après expiration.
send_message({ conversationId: "conversation_1", attachmentIds: ["upload_1"] })Les réponses nécessitent messages:send ; les notes internes nécessitent messages:write et n'atteignent jamais les clients. Les messages contenant uniquement des pièces jointes sont pris en charge. Les réponses par e-mail incluent les fichiers dans la limite de taille de l'e-mail et des liens de téléchargement pour le reste ; les e-mails de chat hors ligne incluent des liens vers les fichiers. Les liens envoyés par e-mail restent utilisables tant que la pièce jointe existe, pour que les destinataires puissent les ouvrir plus tard. Transférer l'e-mail partage l'accès à ces fichiers. Consultez emailDeliveryStatus pour les échecs de livraison.
Les lectures de messages autorisées incluent downloadUrl, downloadExpiresAt, aiStatus, aiDescription et aiExtractedText, ainsi que videoTranscripts pour les vidéos liées (Loom, Vimeo et autres). Les liens de téléchargement durent 15 minutes ; relisez le message pour obtenir des liens frais. Les nouveaux fichiers importés via l'API/MCP sont stockés en privé. Les anciennes pièces jointes restent publiques et sont marquées access=legacy_public : leur URL d'origine n'expire pas. Lire un message lance la lecture de ses images lorsque l'espace de travail dispose de Sonny AI. Les lectures d'images et les transcriptions vidéo se terminent peu après l'arrivée d'un message : tant qu'elles sont en cours, la réponse commence par readsInProgress, dont nextStep indique l'appel exact à effectuer. Passez waitSeconds (jusqu'à 30) pour les attendre en une seule requête. Les messages du widget destinés aux clients et les messages en temps réel n'incluent jamais d'extraction ni de transcription.
Base de connaissances
Synchroniser depuis une source externe
Synchronisez articles et catégories avec des identifiants externes stables, importez du Markdown ou du HTML, importez des images, définissez l'ordre et gérez les audiences de lecteurs. Répéter un upsert met à jour le contenu existant.
- Choisissez le sourceId de votre canal et accordez kb:read et kb:write. Pour la découverte optionnelle,
list_sourcesnécessite aussi conversations:read. - Créez la catégorie, puis synchronisez un article en brouillon. Vérifiez sa mise en forme et ses accès avant de le publier.
- Configurez l'accès au centre d'aide, publiez et testez la vue lecteur. Utilisez la pagination et des identifiants externes stables pour les mises à jour ultérieures.
Gérer les audiences clients
Créez des groupes à partir d'attributs de clients vérifiés et appliquez-les à un centre d'aide, une catégorie ou un article. Toutes les restrictions héritées doivent correspondre. Les identifiants API et MCP agissent en tant que membres de l'équipe dans les limites de leurs portées ; prévisualisez et testez une vraie session client pour vérifier l'accès des lecteurs.
Configurer et tester les audiences du centre d'aideDocumentation associée
- API publiqueBeta
Triez et synchronisez les conversations, partagez le contexte client, lisez les rapports et envoyez des fichiers avec des clés API à portée limitée.
- WebhooksBeta
Abonnez-vous aux événements signés de l'espace de travail et inspectez les tentatives de livraison.
- Équipe et rôles
Invitez des utilisateurs, créez des équipes et comprenez les accès propriétaire, admin, agent et lecteur.