Sviluppatori

API pubblica Beta

Crea integrazioni per il tuo spazio di lavoro con chiavi API sicure e con ambiti, e un contratto JSON stabile e versionato.

Apri il riferimento API interattivo

Guida rapida

  1. 01

    Apri Chiavi API

    Apri Impostazioni, seleziona Sviluppatori, trova Chiavi API, poi seleziona Crea chiave. Proprietari e amministratori possono creare chiavi.

  2. 02

    Crea una chiave API

    Inserisci un Nome, scegli Scade tra (giorni), imposta Accesso ai canali su Tutti i canali o Canali selezionati e scegli in Ambiti gli ambiti minimi di cui ha bisogno la tua integrazione. Una richiesta va a buon fine solo se la chiave ha esattamente l'azione sulla risorsa richiesta dall'endpoint. Seleziona Crea chiave.

  3. 03

    Salva la tua chiave API

    La chiave completa viene mostrata una sola volta. Copiala nel tuo gestore dei segreti, poi seleziona L'ho salvato.

  4. 04

    Invia la chiave

    Usa un token Bearer, oppure invia lo stesso valore in x-api-key. Non inserire mai le chiavi nelle query string o nel codice del browser.

cURL

curl https://www.usesonny.com/api/v1/contacts?limit=25 \
  --header "Authorization: Bearer sonny_your_key"

Le chiavi restano al sicuro

Sicurezza delle chiavi
Le chiavi usano il prefisso sonny_, 64 caratteri casuali, hashing unidirezionale a riposo, scadenza configurabile e un limite di 600 richieste al minuto per chiave. Una chiave è legata a un solo spazio di lavoro.
Per revocarne una, seleziona il pulsante del cestino accanto alla chiave. Conferma Revocare la chiave API? selezionando Elimina. La chiave smette subito di funzionare.
Autorizzazione a ogni chiamata
Sonny verifica l'hash e l'ambito, poi ricontrolla l'appartenenza attiva allo spazio di lavoro, il ruolo e lo stato di fatturazione di chi ha creato la chiave. Rimuovere o disattivare quell'utente disabilita subito le sue chiavi.
I canali selezionati vengono applicati a ogni chiamata REST API e MCP. Gli endpoint per contatti, proprietà, etichette e gestione dei webhook richiedono l'accesso a tutti i canali. La creazione da moduli può usare contacts:write con conversations:write sui canali selezionati; gli endpoint autonomi dei contatti restano validi per tutto lo spazio di lavoro.

Ambiti

  • contacts:read
  • contacts:write
  • tags:read
  • tags:write
  • conversations:read
  • conversations:write
  • messages:read
  • messages:write
  • messages:send
  • webhooks:read
  • webhooks:write
  • kb:read
  • kb:write
  • csat:read
  • attachments:write
  • members:read
  • contact-memory:read
  • contact-memory:write
  • reporting:read

Risorse

Contatti
Gestisci contatti, proprietà tipizzate, filtri per valore esatto e memorie dei clienti. Archivia un contatto, oppure cancellalo definitivamente con tutte le sue conversazioni per le richieste di protezione dei dati.
Sorgenti
Scopri le sorgenti configurate e se ciascuna supporta chat, email o entrambe.
Conversazioni
Crea richieste dai moduli, filtra ciò che richiede attenzione, assegna agenti o team, posticipa, aggiungi etichette e aggiorna in blocco.
Sincronizzazione
Riproduci le modifiche persistenti dello spazio di lavoro e i record delle eliminazioni con un cursore salvato.
Membri e team
Scopri i colleghi assegnabili, la loro disponibilità e l'accesso effettivo ai canali.
Report
Leggi i report su assistenza, team, AI, conoscenze, lead e disponibilità.
Messaggi
Leggi la cronologia dei messaggi e i contenuti estratti dagli allegati, carica file privati, aggiungi note interne e invia o modifica le risposte ai clienti.
Webhook
Gestisci endpoint, iscrizioni, test, consegne e nuovi tentativi.
Base di conoscenza
Crea, leggi, aggiorna ed elimina articoli e categorie del centro assistenza per ogni sorgente.
Soddisfazione dei clienti
Leggi i punteggi CSAT dello spazio di lavoro, di ogni canale e di ogni conversazione, ed elenca le singole valutazioni filtrate per valore, commento, assegnatario o intervallo di tempo.

Usare Sonny da uno strumento AI

Sonny MCP espone ogni operazione dell'API pubblica come strumento. I client si connettono accedendo con OAuth 2.1, oppure con una chiave API con ambiti, e ogni chiamata mantiene gli stessi ambiti, gli stessi confini dello spazio di lavoro e le stesse regole di business.

Leggi la guida a Sonny MCP

Risposte ed errori

Le risposte con raccolte usano data e includono la paginazione dove previsto. Ogni risposta include x-request-id; puoi fornire un ID di richiesta sicuro e Sonny lo restituirà. Gli errori restituiscono un messaggio sicuro senza esporre dettagli sensibili dell'implementazione.

{
  "error": {
    "type": "validation_error",
    "message": "Invalid email address",
    "requestId": "req_01J..."
  }
}
400
Input, JSON, query o cursore non validi.
401
Chiave API mancante, non valida, scaduta o senza l'ambito necessario.
402
Lo stato di fatturazione dello spazio di lavoro blocca questa richiesta.
403
Il ruolo nello spazio di lavoro di chi ha creato la chiave non è consentito.
404
La risorsa non esiste nello spazio di lavoro della chiave.
409
La richiesta è in conflitto con una risorsa esistente.
410
Il cursore di sincronizzazione è scaduto. Ricarica lo stato attuale e riparti da un nuovo cursore.
413
Il file caricato supera la dimensione consentita.
422
La sorgente non ha un canale email oppure il valore di un campo inviato non è valido.
429
È stato superato il limite di richieste per chiave.
500
Si è verificato un errore imprevisto. Riprova indicando l'ID della richiesta.
503
La coda di consegna dei webhook è satura. Riprova più tardi.

Limiti di richieste

Ogni chiave API può effettuare fino a 600 richieste al minuto. Ogni risposta indica la finestra attuale tramite gli header standard RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset, così i client possono regolarsi da soli invece di tirare a indovinare. Quando il limite viene superato, l'API restituisce 429 con un header Retry-After: attendi quel numero di secondi prima di riprovare.

Versioni e deprecazione

L'API è versionata nel percorso dell'URL (/api/v1). All'interno di una versione facciamo solo modifiche additive: nuovi endpoint, nuovi campi facoltativi, nuovi valori enum. Le modifiche non retrocompatibili escono come nuova versione e, prima di ritirare qualsiasi endpoint v1, diamo almeno sei mesi di preavviso: su questa pagina, via email ai proprietari degli spazi di lavoro con chiavi API attive e tramite gli header Deprecation e Sunset sugli endpoint interessati.

Modifica una risposta inviata

  1. Assegna alla tua chiave API o connessione MCP gli ambiti messages:read e messages:send e l'accesso al canale della risposta.
  2. Leggi i messaggi della conversazione e copia l'ID di una risposta umana che hai inviato. Una chiave API agisce come chi l'ha creata; OAuth agisce come il collega collegato.
  3. Invia il testo sostitutivo con la richiesta qui sotto, oppure chiama edit_message in MCP con conversationId, messageId e body.
  4. Controlla il messaggio restituito. ID, allegati, conferma di lettura e orario di invio originale restano invariati.
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"}'

La modifica corregge la trascrizione e i client di chat collegati. Non invia un'altra email o notifica, e le email già consegnate non cambiano. Puoi modificare solo le tue risposte umane ai clienti; non si possono modificare messaggi in arrivo, risposte del bot, note interne e risposte di altri colleghi. Attendi che l'eventuale consegna email in corso sia completata prima di modificare. Il testo sostitutivo deve contenere da 1 a 50.000 caratteri; l'HTML e le anteprime dei link precedenti vengono rimossi. Le integrazioni ricevono un webhook message.updated e un evento di sincronizzazione. Interrogare solo gli ID dei messaggi più recenti non rileva le modifiche: usa il feed di sincronizzazione persistente.

Crea una conversazione da un modulo

Invia l'invio di un modulo a POST /api/v1/conversations. Sonny trova o crea il contatto tramite l'email, salva le risposte e apre una conversazione in arrivo sul canale email della sorgente scelta. Si applicano il team, le regole di assegnazione e le notifiche del canale. Gli agenti rispondono via email.

  1. Crea una chiave con conversations:write e contacts:write. Puoi limitarla ai canali selezionati del cliente. Trova l'ID della sorgente con GET /api/v1/sources, che richiede anche conversations:read.
  2. In n8n, aggiungi un nodo HTTP Request: metodo POST, URL https://www.usesonny.com/api/v1/conversations. Salva la chiave in una credenziale Header Auth: Authorization con valore Bearer sonny_your_key.
  3. Attiva Send Body, scegli JSON e Using JSON, poi passa l'intero campo JSON a Expression e incolla questo esempio. Sostituisci l'ID della sorgente e associa i campi di input al tuo modulo. Usa l'ID di invio stabile e univoco del modulo, così un nuovo tentativo usa lo stesso valore.
{{ {
  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
} }}

Per altre opzioni del nodo, consulta la guida n8n a HTTP Request. Lo strumento MCP equivalente è create_conversation, con lo stesso payload e gli stessi permessi.

I nomi di campo nuovi diventano proprietà di testo. I campi esistenti di tipo numero, URL, data e selezione devono ricevere stringhe valide; un valore errato restituisce 422 indicando il campo e non salva nulla. Le date accettano date o timestamp ISO; i valori di selezione devono corrispondere a un'opzione. Sono accettati fino a 50 campi, con nomi fino a 100 caratteri e valori fino a 5.000. Le proprietà compaiono sul contatto e nella barra laterale della conversazione. Entrambi i corpi del messaggio conservano una copia delle risposte, anche quando fornisci il campo facoltativo htmlMessage.

Il campo facoltativo tags accetta fino a 20 ID di etichette esistenti dello spazio di lavoro. La risposta contiene conversation, un riepilogo di contact, message e deduplicated. I nuovi invii restituiscono 201. Riutilizzare externalId sulla stessa sorgente restituisce 200 con gli ID originali e deduplicated: true; i contenuti modificati vengono ignorati. Senza un ID esterno, ogni chiamata crea una nuova conversazione. Gli allegati in fase di creazione e le risposte automatiche dell'AI non sono supportati.

Flussi di lavoro degli agenti

Smista, agisci e resta sincronizzato

REST e MCP condividono gli stessi permessi e flussi di lavoro. Le credenziali possono solo restringere il tuo accesso attuale ai canali; rimuovere un canale dalla tua appartenenza lo rimuove anche dalle tue integrazioni.

Trova le conversazioni che richiedono attenzione

Filtra per awaitingReply, unread, unassigned, assigneeId, agentGroupId, snoozed, priority o tagIds. In attesa di risposta ignora le note interne; non letto è specifico del collega autenticato. Non assegnata significa senza assegnatario individuale, anche se è assegnato un team. Le etichette corrispondono a uno qualsiasi degli ID forniti.

GET /api/v1/conversations?status=open&awaitingReply=true&compact=true&sort=waitingSince&direction=asc

Ordina per waitingSince, lastMessageAt, createdAt o priorità di business con direction asc o desc. Gli ID risolvono i pareggi. I filtri omessi mantengono compact=false e snoozed=any. In REST tagIds accetta ID separati da virgola; MCP accetta anche un array. waitingSince parte dal primo messaggio in arrivo dopo l'ultima risposta; solleciti e note interne non lo azzerano. Esegui questa scansione della coda in attesa in modo programmato anche quando non arriva alcun webhook, così i thread vecchi riemergono.

Recupera gli aggiornamenti senza rileggere la posta in arrivo

Usa GET /api/v1/sync con conversations:read. Il feed persistente include modifiche alle conversazioni, etichette, messaggi, proprietà dei contatti, memorie e record delle eliminazioni. Ogni payload richiede anche il proprio ambito di lettura: i corpi dei messaggi richiedono messages:read e le memorie contact-memory:read. Le credenziali limitate ricevono solo i canali consentiti.

  1. Parti senza cursore, segui nextCursor finché hasMore non è false e salva quel cursore.
  2. Leggi gli elenchi attuali di conversazioni e contatti e la cronologia che ti serve per lo stato iniziale.
  3. Riparti dal cursore salvato per recuperare le modifiche avvenute durante quella lettura. Elabora ogni pagina, poi salva nextCursor.

Elimina i duplicati in base all'id dell'evento: la riproduzione avviene almeno una volta, quindi le azioni a valle devono avere una propria protezione dai duplicati. Una richiesta senza cursore copre l'ultima ora, non un'istantanea completa. Gli eventi vengono conservati per 30 giorni; HTTP 410 resync_required significa che devi ricaricare lo stato da capo. Fallo anche dopo aver ampliato ambiti o accesso ai canali. Usa limit fino a 100 e maxBodyChars fino a 10.000 (predefinito 500). Imposta compact=true per avere i campi del messaggio textPreview/textTruncated limitati a 200 caratteri invece di body/bodyTruncated. I webhook possono riattivare un agente; il feed resta disponibile anche senza iscrizioni ai webhook o quando la consegna dei webhook è in arretrato.

Registra i controlli una volta e condividi il risultato

Prima di ripetere un'indagine, leggi list_conversation_checks (GET /api/v1/conversations/{conversationId}/checks). Salva un risultato con record_conversation_check (PUT sullo stesso percorso), fornendo key, result, checkedBy e un reference facoltativo per l'ID o l'URL della scheda. Ad esempio: key=product-version, result=Shopstar Go verified, checkedBy=Engineer, reference=card-X. Sonny registra l'actorId autenticato e il timestamp checkedAt. Riutilizzare una key sostituisce solo quel controllo; è lo stato attuale, non uno storico. Le letture richiedono conversations:read e le scritture conversations:write, entrambe limitate al canale della conversazione. Queste chiamate non inviano una risposta e non segnano il venditore come risposto.

Assegna e aggiorna il lavoro in blocco

Trova colleghi e team attivi e assegnabili con GET /api/v1/members and /teams (members:read). Le risposte includono la disponibilità e l'accesso effettivo ai canali, senza indirizzi email. Usa conversations:write per cambiare status, priority, assigneeId, agentGroupId, snoozedUntil, snoozedUntilReply, addTagIds o removeTagIds.

POST /api/v1/conversations/batch
{
  "conversationIds": ["conversation_1", "conversation_2"],
  "updates": { "agentGroupId": "team_1", "assignment": "round_robin" }
}

L'assegnazione a rotazione sceglie un membro del team disponibile che può accedere al canale della conversazione. Se nessun membro è idoneo, un aggiornamento singolo restituisce 409 e l'elemento di un'operazione in blocco non riesce. Ogni operazione in blocco accetta fino a 100 ID univoci e applica una patch in modo atomico per ogni conversazione. Esamina ogni risultato { id, ok, error? }: alcuni elementi potrebbero non riuscire. Le operazioni in blocco usano l'attuale limite basato sulle richieste, senza addebiti ponderati in base al numero di elementi.

Condividi il contesto dei clienti con Sonny AI

Elenca, salva e rimuovi le memorie dei contatti con contact-memory:read/write. Fornisci sia contactId sia un sourceId accessibile; il contatto deve avere una conversazione su quella sorgente. I fatti salvati usano la stessa validazione, gestione dei duplicati e limiti dell'app e vengono registrati come memorie manuali.

Leggi le definizioni delle proprietà in /api/v1/properties e leggi o imposta i valori in /api/v1/contacts/{contactId}/properties. MCP espone list_properties, get_contact_properties e set_contact_property. Richiedono contacts:read/write e l'accesso a tutti i canali. Imposta esattamente uno tra propertyId e propertyName, con un valore stringa o null per cancellarlo. I valori di testo, numero, URL, data e selezione vengono validati in base alla definizione del campo.

PUT /api/v1/contacts/contact_1/properties
{ "propertyName": "Plan", "value": "Pro" }

GET /api/v1/contacts?property[Plan]=Pro

I filtri sulle proprietà corrispondono alle stringhe esatte salvate; più proprietà devono corrispondere tutte. I valori scritti tramite API sono etichettati come dati API in Co-Pilot e nel risponditore automatico. Restano valide le regole esistenti sui clienti verificati e sulle sorgenti. I normali valori interni inseriti a mano restano esclusi da questo contesto AI.

Leggi gli stessi report del tuo team

Con reporting:read, chiama GET /api/v1/reporting/{kind}. I tipi sono overview, volume, response-times, agents, sources, tags, csat, ai, knowledge, leads e online-hours. Overview combina conteggi, tempi di risposta e CSAT. I filtri sono period (1–365 giorni, predefinito 30), date from/to abbinate (to è esclusa), granularity (day/month), source, assigneeId e tagId. Source accetta all, all-chat, all-email, website:{id} o email:{id}.

I report usano le stesse query della dashboard e gli attuali controlli di accesso. Knowledge usa le date e i canali consentiti, indipendentemente da sorgente, assegnatario o etichetta selezionati. Online hours misura la presenza nello spazio di lavoro dei colleghi accessibili; i conteggi delle conversazioni restano limitati ai canali. Gli endpoint /csat esistenti mantengono il loro ambito separato csat:read e possono descrivere un insieme diverso.

Invia file con risposte o note interne

Concedi attachments:write e carica un file fino a 25 MB per una conversazione. POST /api/v1/attachments accetta i campi multipart file e conversationId. La risposta contiene un id ed expiresAt. Passa fino a 10 attachmentIds a una risposta o nota entro un'ora. Ogni file caricato è legato al tuo utente e alla conversazione e può essere usato una sola volta. I file non usati vengono eliminati dopo la scadenza.

POST /api/v1/conversations/conversation_1/reply
{ "attachmentIds": ["upload_1"] }

Le risposte richiedono messages:send; le note interne richiedono messages:write e non arrivano mai ai clienti. Sono supportati messaggi con soli allegati. Le risposte via email includono i file entro il limite di dimensione dell'email e link per scaricare gli altri; le email delle chat offline includono link ai file. I link inviati via email restano utilizzabili finché l'allegato esiste, così i destinatari possono aprirli in seguito. Inoltrare l'email condivide l'accesso a quei file. Controlla emailDeliveryStatus per gli errori di consegna.

Le letture autorizzate dei messaggi includono downloadUrl, downloadExpiresAt, aiStatus, aiDescription e aiExtractedText, più videoTranscripts per i video collegati (Loom, Vimeo e altri). I link di download durano 15 minuti; rileggi il messaggio per ottenerne di nuovi. I nuovi caricamenti via API/MCP hanno un'archiviazione privata. Gli allegati più vecchi restano pubblici e sono contrassegnati con access=legacy_public: il loro URL originale non scade. Leggere un messaggio avvia la lettura delle sue immagini quando lo spazio di lavoro ha Sonny AI. Le letture delle immagini e le trascrizioni dei video si completano poco dopo l'arrivo di un messaggio: finché qualcuna è in corso, la risposta inizia con readsInProgress, il cui nextStep indica la chiamata esatta da fare. Passa waitSeconds (fino a 30) per attenderle in un'unica richiesta. I messaggi del widget per i clienti e quelli in tempo reale non includono mai estrazioni o trascrizioni.

Esplora i contratti completi di richieste e risposte

Base di conoscenza

Sincronizza da una fonte esterna

Sincronizza articoli e categorie con ID esterni stabili, importa Markdown o HTML, carica immagini, imposta l'ordinamento e gestisci i pubblici dei lettori. Ripetere un upsert aggiorna i contenuti esistenti.

  1. Scegli il sourceId del tuo canale e concedi kb:read e kb:write. Tieni la chiave API sul tuo server e limitane l'Accesso ai canali.
  2. Crea la categoria, poi sincronizza un articolo come bozza. Controlla formattazione e accesso prima di pubblicare.
  3. Configura l'accesso al centro assistenza, pubblica e prova la vista del lettore. Usa la paginazione e ID esterni stabili per gli aggiornamenti successivi.
Segui la guida completa alla sincronizzazione via REST

Gestisci i pubblici di clienti

Crea gruppi a partire dagli attributi dei clienti verificati e applicali a un centro assistenza, una categoria o un articolo. Tutte le restrizioni ereditate devono essere soddisfatte. Le credenziali API e MCP agiscono come staff entro i loro ambiti; visualizza l'anteprima e prova una sessione reale di un cliente per verificare l'accesso dei lettori.

Configura e prova i pubblici del centro assistenza

Guide correlate