REST API
Chatta con i tuoi agenti intoCHAT, leggi conversazioni, lead e fonti di conoscenza, mantieni sincronizzati i contatti e registra webhook dal tuo server o da uno strumento di automazione: chiavi API, scope, limiti di frequenza, errori, paginazione e tutti gli endpoint con esempi.
La REST API permette al tuo server di parlare con i tuoi agenti. Invia un messaggio e ricevi la risposta dell'agente, leggi conversazioni e lead, crea e aggiorna contatti, aggiungi o rimuovi fonti di conoscenza e registra webhook per gli eventi di un agente, con JSON su HTTPS. Le app per Zapier e Make si basano su di essa. Una risposta tramite l'API viene scritta dallo stesso codice di una risposta nel widget di chat, con la stessa conoscenza e le stesse impostazioni.
L'API è pensata per i server. Non invia intestazioni CORS, quindi una pagina web di un altro sito non può chiamarla, e la tua chiave API non deve mai comparire in un browser o nel tuo codice di incorporamento. Per mostrare una chat sul tuo sito usa il tag script. Per ricevere gli eventi nel momento in cui avvengono usa i webhook.
Quali piani includono l'API
L'API è inclusa nei piani Starter, Pro ed Enterprise. Con Free non puoi creare chiavi.
Se un account torna al piano Free, le sue chiavi restano nell'elenco ma ogni richiesta riceve un errore 403 con il codice plan_required. Tornano a funzionare non appena l'account passa a Starter o a un piano superiore.
Ogni risposta che un agente scrive tramite l'API conta come un messaggio del tuo piano, esattamente come una risposta nel widget, e conta anche per il tetto mensile di messaggi dell'agente, se ne hai impostato uno. Leggere dati, aggiungere o eliminare fonti non consuma messaggi. Vedi Che cosa conta come messaggio.
Creare una chiave API
- Nella barra laterale, sotto Settings, clicca su API keys.
- In Create a key, dai alla chiave un Name che riconoscerai in seguito, per esempio
CRM sync. - In Access, lascia Every scope, including ones added later, oppure scegli Only the scopes I choose e seleziona quelli che servono a questa chiave. Vedi Scope.
- Clicca su Create key.
- Clicca su Copy, conserva la chiave dove il tuo server può leggerla, per esempio in una variabile d'ambiente, e clicca su I've saved it.
Una chiave è composta da ic_live_ seguito da 32 lettere e cifre. Viene mostrata una sola volta: intoCHAT ne conserva solo un'impronta, quindi nessuno può mostrartela di nuovo. Se la perdi, revocala e creane una nuova.
Una chiave appartiene all'account, non alla persona che l'ha creata. Funziona per tutti gli agenti dell'account, nei limiti dei suoi scope, e continua a funzionare se quella persona lascia il team. Un account può avere fino a 20 chiavi attive.
Solo il proprietario dell'account e gli admin possono creare e revocare le chiavi. Editor e viewer vedono l'elenco delle chiavi, solo con i primi caratteri. Vedi Membri del team e ruoli.
L'elenco delle chiavi
Per ogni chiave vedi il nome, i primi caratteri (per esempio ic_live_3f9A…), gli scope, quando è stata creata e quando è stata usata l'ultima volta. Last used viene aggiornato al massimo una volta al minuto.
Revocare una chiave
Clicca su Revoke accanto alla chiave e conferma. La chiave smette di funzionare dalla richiesta successiva, e l'operazione non si può annullare. Revoca una chiave non appena pensi che qualcun altro possa averla.
Revocare una chiave elimina anche i webhook che ha registrato, per esempio per Zapier o Make, con la loro cronologia degli invii: altrimenti nulla potrebbe rimuoverli. I webhook che hai aggiunto nella scheda Leads non vengono toccati.
Autenticazione
Invia la chiave nell'intestazione Authorization di ogni richiesta:
curl https://www.intochat.ai/api/v1/agents \
-H "Authorization: Bearer ic_live_YOUR_KEY"
Tutti gli endpoint si trovano sotto https://www.intochat.ai/api/v1. Le richieste con un corpo inviano JSON con Content-Type: application/json, e ogni risposta è in JSON, tranne una risposta di chat in streaming. L'API non usa cookie né sessioni di accesso: è solo la chiave a decidere che cosa può fare una richiesta.
Una chiave mancante, malformata, sconosciuta o revocata riceve un errore 401 con il codice unauthorized.
Scope
Uno scope permette a una chiave di usare un gruppo di endpoint. Una chiave creata con Every scope, including ones added later può usare tutti gli endpoint, anche quelli che verranno aggiunti in futuro.
| Scope | Consente |
|---|---|
agents:read | Elencare gli agenti e leggere un agente |
chat | Inviare un messaggio a un agente. Ogni risposta conta come un messaggio del tuo piano. |
conversations:read | Elencare le conversazioni e leggere una conversazione con la sua trascrizione |
leads:read | Elencare i lead, elencare i contatti e leggere un contatto, e gli eventi di lead, moduli, prenotazioni e resi di Elencare gli eventi e Leggere eventi di esempio |
contacts:write | Creare o aggiornare un contatto, modificare un contatto ed eliminare un contatto |
sources:read | Elencare le fonti |
sources:write | Aggiungere una fonte ed eliminare una fonte, il che avvia anche l'addestramento |
webhooks:write | Registrare un webhook e annullare la registrazione di un webhook |
conversations:read copre anche gli eventi di passaggio, live chat e nuova conversazione di Elencare gli eventi.
Una richiesta a un endpoint per cui la chiave non ha lo scope riceve un errore 403 con il codice insufficient_scope. Per cambiare gli scope di una chiave, creane una nuova e revoca quella vecchia.
Limiti di frequenza
Ogni chiave può fare 60 richieste al minuto, su tutti gli endpoint insieme. Ogni risposta che ha superato il controllo della chiave contiene queste intestazioni:
| Intestazione | Valore |
|---|---|
X-RateLimit-Limit | 60 |
X-RateLimit-Remaining | Le richieste rimaste nel minuto in corso |
X-RateLimit-Reset | Quando finisce il minuto, in secondi Unix |
Oltre il limite, la richiesta riceve un errore 429 con il codice rate_limited e un'intestazione Retry-After con i secondi da attendere.
La chat ha altri due limiti che non dipendono dalla chiave: i messaggi del piano, e il fatto che un agente risponde al massimo a 1.000 messaggi all'ora, widget e API insieme. Oltre questa soglia, una richiesta di chat riceve un errore 429 con il codice agent_busy.
Errori
Ogni errore ha la stessa struttura:
{
"error": {
"code": "insufficient_scope",
"message": "This API key doesn't have the \"chat\" scope."
}
}
Nel tuo codice usa code; message lo spiega a una persona e può cambiare.
| Stato | Codice | Significato |
|---|---|---|
400 | invalid_request | Alla richiesta manca qualcosa o ha un valore errato. Il messaggio dice quale. |
401 | unauthorized | Nessuna chiave, oppure la chiave è malformata, sconosciuta o revocata. |
403 | insufficient_scope | La chiave non ha lo scope richiesto da questo endpoint. |
403 | plan_required | L'account è sul piano Free. L'API è inclusa da Starter in su. |
403 | message_limit_reached | L'account ha usato tutti i messaggi inclusi nel suo piano per questo periodo. |
403 | agent_cap_reached | L'agente ha raggiunto il tetto mensile di messaggi impostato in Share, Limits and access. |
403 | agent_private | L'agente è privato, quindi risponde solo nella dashboard. Vedi Agenti privati. |
403 | character_limit_exceeded | Una nuova fonte porterebbe l'agente oltre i caratteri di addestramento del suo piano. |
403 | contact_limit_reached | Un nuovo contatto porterebbe l'agente oltre i contatti per agente del suo piano. |
404 | not_found | In questo account non esiste un agente, una conversazione, una fonte, un contatto o un webhook con questo ID. |
409 | conflict | Un altro contatto dell'agente ha già questo external ID o questa email. |
429 | rate_limited | La chiave ha fatto più di 60 richieste in questo minuto. |
429 | agent_busy | In questo momento l'agente sta rispondendo a troppi messaggi. |
500 | internal_error | Qualcosa è andato storto da parte nostra. Riprova. |
504 | timeout | L'agente ha impiegato troppo tempo a rispondere. |
Un agente, una conversazione o una fonte che appartiene a un altro account riceve 404, come uno che non esiste.
Paginazione
Elencare le conversazioni ed elencare i lead restituiscono una pagina alla volta, dalla più recente. Accettano questi parametri di query:
| Parametro | Contenuto |
|---|---|
limit | Elementi per pagina, da 1 a 100. Il valore predefinito è 20. |
cursor | Il nextCursor della pagina precedente, per ottenere quella successiva. |
since | Un orario ISO 8601, per esempio 2026-10-01T00:00:00Z. Vengono restituiti solo gli elementi con attività in quel momento o dopo: una conversazione con un messaggio da allora, oppure un lead salvato o inviato di nuovo da allora. |
Una pagina ha questo aspetto:
{
"data": [ ],
"hasMore": true,
"nextCursor": "MjAyNi0xMC0wNFQwOTowMDowMC4wMDBafGNsdjEyMw"
}
Richiedi la pagina successiva con ?cursor= e quel valore, mantenendo gli stessi limit e since, finché hasMore è false e nextCursor è null. L'ordine è fissato dall'orario di creazione, quindi una nuova attività mentre sfogli le pagine non fa comparire un elemento due volte né lo fa sparire. Per sincronizzare regolarmente, salva l'orario in cui hai avviato l'ultima sincronizzazione e passalo come since la volta successiva.
Elencare gli agenti
GET /api/v1/agents · scope agents:read
Tutti gli agenti dell'account, dal più recente.
curl https://www.intochat.ai/api/v1/agents \
-H "Authorization: Bearer ic_live_YOUR_KEY"
{
"data": [
{
"id": "AGENT_ID",
"name": "Acme Assistant",
"private": false,
"status": "trained",
"trainedAt": "2026-10-02T09:00:00.000Z",
"characters": 48210,
"counts": { "conversations": 312, "messages": 2240, "leads": 41, "sources": 18 },
"createdAt": "2026-09-01T09:00:00.000Z",
"updatedAt": "2026-10-02T09:00:00.000Z"
}
]
}
status è untrained, training, trained o error (l'ultimo addestramento non è riuscito). characters indica quanti caratteri di addestramento usano le fonti addestrate dell'agente.
Leggere un agente
GET /api/v1/agents/{agentId} · scope agents:read
Un solo agente, in data, con gli stessi campi di Elencare gli agenti.
Inviare un messaggio
POST /api/v1/agents/{agentId}/chat · scope chat
Invia un messaggio all'agente e restituisce la sua risposta. L'agente risponde come nel widget: in base alla sua conoscenza e alle sue istruzioni, con le tue azioni API, i pulsanti personalizzati, i moduli in chat, la prenotazione, il passaggio via email e la live chat, dove li hai configurati.
| Campo | Contenuto |
|---|---|
message | Obbligatorio. Il testo, fino a 10.000 caratteri. |
conversationId | Facoltativo. Continua una conversazione che hai iniziato tramite l'API, con il conversationId di una risposta precedente. |
sessionId | Facoltativo. Un tuo ID per la persona per cui chatti, per esempio il tuo ID utente, fino a 100 caratteri. Lo stesso valore continua sempre la stessa conversazione. Puoi anche inviare il sessionId di una risposta precedente. |
stream | Facoltativo. true invia il testo della risposta in streaming; vedi Streaming. Il valore predefinito è false. |
timeZone | Facoltativo. Il fuso orario IANA della persona, per esempio Europe/Berlin, per gli orari delle prenotazioni. Senza questo campo, gli orari sono in UTC. |
Senza conversationId e sessionId, ogni messaggio avvia una nuova conversazione.
curl https://www.intochat.ai/api/v1/agents/AGENT_ID/chat \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "message": "Do you ship to Switzerland?", "sessionId": "customer-4821" }'
{
"reply": "Yes, we ship to Switzerland. Delivery takes 3 to 5 working days.",
"conversationId": "CONVERSATION_ID",
"sessionId": "icapi5f0c2b9e4d7a41f8a3c6e1b2d9f07a64",
"sources": [
{ "title": "Shipping", "url": "https://www.example.com/shipping" }
],
"followUps": ["How much does shipping cost?", "Can I track my order?"],
"buttons": [],
"products": [],
"form": null,
"leadForm": null,
"booking": null,
"liveChat": null
}
| Campo | Contenuto |
|---|---|
reply | La risposta dell'agente come testo semplice con Markdown, senza i blocchi di controllo del widget. Vuota mentre qualcuno del tuo team ha la chat (vedi liveChat). |
conversationId | La conversazione, come in Leggere una conversazione. |
sessionId | La sessione della conversazione in intoCHAT. Inizia sempre con icapi. |
sources | Le pagine su cui si basa la risposta, come title e url, quando Show sources under replies è attivo. Le pagine della ricerca web sono sempre elencate, con "web": true. |
followUps | Le domande successive suggerite, quando Suggest follow-up questions è attivo. |
buttons | I pulsanti personalizzati scelti dall'agente, come label e url. |
products | Le schede prodotto del tuo negozio o delle azioni API, con name, url e, quando sono noti, image, price, compareAtPrice, currency e available. |
form | Un modulo in chat proposto dall'agente, con formId, name, fields e submitLabel, oppure null. L'API non può inviarlo; mostralo nella tua interfaccia o ignoralo. |
leadForm | Il modulo lead, con message, i fields di contatto e form, quando l'agente ha chiesto i dati di contatto, oppure null. I contatti scritti in un messaggio vengono salvati come lead quando Save contact details written in the chat è attivo, come nel widget. |
booking | Gli orari liberi per un appuntamento, con provider, eventTitle, eventLength in minuti, timeZone e days, ognuno con la sua date e gli slots come orari UTC, oppure null. L'API non può prenotare un orario. |
liveChat | null, oppure lo stato della live chat: offered (l'agente può chiedere al tuo team di intervenire), requested (l'ha chiesto) o paused (un membro del team ha la chat, quindi l'agente non ha risposto). |
Differenze tra le chat via API e il widget
- La conversazione viene salvata come una chat del widget e compare nella scheda Conversations dell'agente, con i suoi lead, le valutazioni e le statistiche. Non ha un paese né una pagina.
- I domini consentiti, i paesi bloccati e i messaggi per visitatore non valgono: non c'è una pagina o un indirizzo del visitatore da controllare. Valgono invece i messaggi del piano, il tetto mensile dell'agente e il limite di frequenza della chiave.
- Un agente privato rifiuta le chat via API con
agent_private. - Le azioni lato client vengono eseguite nel browser di un visitatore, quindi nelle chat via API l'agente non le ha a disposizione. Azioni API, pulsanti, moduli e prenotazioni funzionano.
- Non si possono allegare file e non ci sono chat temporanee.
- Tramite l'API si possono continuare solo le conversazioni iniziate tramite l'API. L'agente vede come cronologia gli ultimi 40 messaggi della conversazione.
- Mentre qualcuno del tuo team ha preso in carico la chat nella casella Live chat, il tuo messaggio viene salvato,
replyè vuoto eliveChatèpaused. Le risposte del membro del team compaiono nella conversazione: leggile con Leggere una conversazione, dove hanno unauthorName. Un messaggio durante una presa in carico non consuma messaggi del tuo piano. - Una risposta che richiede più di 55 secondi termina con un errore
504e il codicetimeout. Può comunque contare come messaggio.
Streaming
Con "stream": true, la risposta è il testo della risposta man mano che viene scritto, come text/plain, senza i campi JSON. Le intestazioni X-Conversation-Id e X-Session-Id riportano conversazione e sessione, e X-Live-Chat lo stato della live chat, quando c'è. Fonti, pulsanti e gli altri blocchi non vengono inviati in streaming; leggili dopo con Leggere una conversazione. Gli errori sono in JSON, come senza streaming.
curl -N https://www.intochat.ai/api/v1/agents/AGENT_ID/chat \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "message": "What are your opening hours?", "stream": true }'
Elencare le conversazioni
GET /api/v1/agents/{agentId}/conversations · scope conversations:read
Le conversazioni dell'agente, dal widget e dall'API, dalla più recente, senza i loro messaggi. Accetta limit, cursor e since; vedi Paginazione.
curl "https://www.intochat.ai/api/v1/agents/AGENT_ID/conversations?limit=50&since=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer ic_live_YOUR_KEY"
{
"data": [
{
"id": "CONVERSATION_ID",
"sessionId": "8f14e45f-ceea-467a-9575-1a2b3c4d5e6f",
"channel": "widget",
"createdAt": "2026-10-04T09:00:00.000Z",
"lastActivityAt": "2026-10-04T09:12:00.000Z",
"country": "CH",
"page": "https://www.example.com/pricing",
"messageCount": 6,
"topics": ["Pricing"],
"sentiment": "positive",
"liveChat": null,
"csatScore": null
}
],
"hasMore": false,
"nextCursor": null
}
channel è api per una conversazione iniziata tramite l'API, altrimenti widget (il tag script, l'iframe incorporato, il link diretto e il Playground). topics e sentiment vengono impostati dall'analisi degli argomenti, quando è attiva. liveChat è null, requested, active o ended. csatScore è la valutazione da 1 a 5 data dal visitatore dopo una live chat, oppure null.
Leggere una conversazione
GET /api/v1/conversations/{conversationId} · scope conversations:read
Una conversazione di qualsiasi agente dell'account, con tutti i messaggi in ordine.
{
"data": {
"id": "CONVERSATION_ID",
"agentId": "AGENT_ID",
"sessionId": "icapi5f0c2b9e4d7a41f8a3c6e1b2d9f07a64",
"channel": "api",
"createdAt": "2026-10-04T09:00:00.000Z",
"lastActivityAt": "2026-10-04T09:14:00.000Z",
"country": null,
"page": null,
"topics": [],
"sentiment": null,
"handoffRequestedAt": null,
"liveChat": { "status": "ended", "startedAt": "2026-10-04T09:05:00.000Z", "endedAt": "2026-10-04T09:13:00.000Z" },
"csat": { "score": 5, "comment": "Quick and friendly.", "ratedAt": "2026-10-04T09:14:00.000Z" },
"messages": [
{ "id": "MESSAGE_ID", "role": "assistant", "content": "Hello! How can I help you today?", "createdAt": "2026-10-04T09:00:00.000Z", "authorName": null, "sources": [] },
{ "id": "MESSAGE_ID", "role": "user", "content": "Can I change my delivery address?", "createdAt": "2026-10-04T09:01:00.000Z", "authorName": null, "sources": [] },
{ "id": "MESSAGE_ID", "role": "assistant", "content": "Yes, I'm on it. What's your order number?", "createdAt": "2026-10-04T09:06:00.000Z", "authorName": "Anna", "sources": [] }
]
}
}
role è user per il visitatore o per i tuoi messaggi via API, e assistant per l'agente e il tuo team. authorName è il nome del membro del team che ha scritto una risposta in live chat, oppure null quando l'ha scritta l'agente. content è il testo senza i blocchi di controllo del widget; le sources di una risposta dell'agente elencano le pagine che ha mostrato. handoffRequestedAt indica quando l'agente ha inviato la conversazione al tuo team via email, oppure null. liveChat e csat sono null quando non c'è stata una live chat o una valutazione.
Elencare i lead
GET /api/v1/agents/{agentId}/leads · scope leads:read
I lead dell'agente, dal più recente. Accetta limit, cursor e since; vedi Paginazione.
{
"data": [
{
"id": "LEAD_ID",
"email": "jane@example.com",
"phone": null,
"name": "Jane",
"customFields": [{ "id": "FIELD_ID", "label": "Company", "value": "Acme" }],
"source": "form",
"conversationId": "CONVERSATION_ID",
"collectedAt": "2026-10-04T09:03:00.000Z",
"lastSeenAt": "2026-10-04T09:03:00.000Z",
"submissionCount": 1
}
],
"hasMore": false,
"nextCursor": null
}
source è form per il modulo lead o chat per i contatti scritti in un messaggio. customFields usa le etichette che il tuo modulo ha adesso. lastSeenAt e submissionCount cambiano quando la stessa persona invia di nuovo i dati. conversationId è null quando la conversazione è stata eliminata.
Contatti
I contatti di un agente: visitatori verificati, lead, contatti importati e quelli che aggiungi qui, ognuno con fino a 50 attributi personalizzati. Per leggerli serve leads:read; per crearli, modificarli ed eliminarli serve contacts:write. Le chiavi create con Every scope li hanno entrambi.
Un contatto ha questo aspetto:
{
"id": "CONTACT_ID",
"agentId": "AGENT_ID",
"externalId": "user-4711",
"email": "jane@example.com",
"phone": "+41441234567",
"name": "Jane",
"attributes": { "plan": "pro", "seats": 5, "vip": true },
"source": "api",
"firstSeenAt": "2026-10-04T09:03:00.000Z",
"lastSeenAt": "2026-10-04T09:03:00.000Z",
"createdAt": "2026-10-04T09:03:00.000Z",
"updatedAt": "2026-10-04T09:03:00.000Z"
}
source è identity, lead, import o api: da dove è arrivato il contatto la prima volta. externalId è l'ID utente della persona sul tuo sito. Le email vengono salvate in minuscolo.
Elencare i contatti
GET /api/v1/agents/{agentId}/contacts · scope leads:read
I contatti dell'agente, dal più recente. Accetta limit, cursor e since (i contatti modificati in quel momento o dopo); vedi Paginazione. Aggiungi email= o external_id= per cercare un solo contatto.
curl "https://www.intochat.ai/api/v1/agents/AGENT_ID/contacts?external_id=user-4711" \
-H "Authorization: Bearer ic_live_YOUR_KEY"
{ "data": [ { "id": "CONTACT_ID", "externalId": "user-4711", "email": "jane@example.com", "attributes": { "plan": "pro" } } ], "hasMore": false, "nextCursor": null }
data ha tutti i campi mostrati sopra; qui alcuni sono omessi.
Creare o aggiornare un contatto
POST /api/v1/agents/{agentId}/contacts · scope contacts:write
curl https://www.intochat.ai/api/v1/agents/AGENT_ID/contacts \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "external_id": "user-4711", "email": "jane@example.com", "name": "Jane", "attributes": { "plan": "pro", "seats": 5 } }'
| Campo | Note |
|---|---|
external_id | Fino a 200 caratteri. Invia questo o email. |
email | Un indirizzo email valido. |
phone | Da 7 a 15 cifre, eventualmente precedute da +. |
name | Fino a 100 caratteri. |
attributes | Un oggetto con nomi e valori degli attributi. I nomi iniziano con una lettera minuscola e usano lettere minuscole, cifre e trattini bassi, fino a 40 caratteri; vedi Attributi. Un valore è un testo fino a 1.000 caratteri, un numero o true/false, e null rimuove l'attributo. |
Viene aggiornato il contatto con questo external_id, altrimenti quello con questa email, altrimenti viene creato un nuovo contatto. Un contatto con la sola email trovato in questo modo riceve l'external_id. I campi che invii sostituiscono quelli salvati, un campo impostato a null viene svuotato, e i campi che non invii restano come sono. Gli attributi vengono uniti: quelli che invii vengono impostati, gli altri restano.
{ "data": { "id": "CONTACT_ID", "externalId": "user-4711", "email": "jane@example.com", "attributes": { "plan": "pro", "seats": 5 } }, "result": "created" }
result è created (stato 201) o updated (stato 200). Un'email che appartiene a un contatto con un external ID diverso, oppure un external ID o un'email che un altro contatto ha già, riceve un errore 409 con il codice conflict. Un nuovo contatto oltre i contatti per agente del tuo piano riceve un errore 403 con il codice contact_limit_reached.
Leggere un contatto
GET /api/v1/contacts/{contactId} · scope leads:read
Un contatto di qualsiasi agente dell'account, come { "data": { … } }.
Modificare un contatto
PATCH /api/v1/contacts/{contactId} · scope contacts:write
Accetta gli stessi campi di Creare o aggiornare un contatto, tutti facoltativi, e risponde con il contatto come { "data": { … } }. Un contatto deve mantenere un external ID, un'email o un numero di telefono.
Eliminare un contatto
DELETE /api/v1/contacts/{contactId} · scope contacts:write
{ "data": { "id": "CONTACT_ID", "deleted": true } }
I lead e le conversazioni del contatto vengono mantenuti.
Elencare le fonti
GET /api/v1/agents/{agentId}/sources · scope sources:read
Le fonti di conoscenza dell'agente nell'ordine della scheda Knowledge, con l'avanzamento dell'addestramento. Il testo di una fonte non è incluso, tranne la domanda e la risposta di una coppia di Q&A.
{
"data": [
{
"id": "SOURCE_ID",
"type": "qa",
"title": "Do you ship to Switzerland?",
"url": null,
"filename": null,
"question": "Do you ship to Switzerland?",
"answer": "Yes, in 3 to 5 working days.",
"characters": 71,
"status": "trained",
"error": null,
"trainedAt": "2026-10-02T09:00:00.000Z",
"createdAt": "2026-10-02T08:59:00.000Z",
"updatedAt": "2026-10-02T09:00:00.000Z"
}
],
"training": { "total": 18, "trained": 18, "pending": 0, "processing": 0, "failed": 0, "done": true },
"characters": { "used": 48210, "limit": 500000 }
}
type è website, file, text, qa o notion. status è pending, processing, trained o failed, con il motivo in error. characters.limit è il numero di caratteri di addestramento per agente del tuo piano.
Aggiungere una fonte
POST /api/v1/agents/{agentId}/sources · scope sources:write
Aggiunge un testo o una coppia di Q&A e avvia l'addestramento, come fa la scheda Knowledge. L'agente usa la nuova fonte una volta addestrata; segui il suo status con Elencare le fonti.
Un testo:
curl https://www.intochat.ai/api/v1/agents/AGENT_ID/sources \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "type": "text", "title": "Opening hours", "content": "We are open Monday to Friday, 9:00 to 17:00." }'
Una coppia di Q&A:
{ "type": "qa", "question": "Do you ship to Switzerland?", "answer": "Yes, in 3 to 5 working days." }
{
"data": { "id": "SOURCE_ID", "type": "text", "title": "Opening hours", "status": "pending", "characters": 44 },
"result": "created",
"training": { "total": 19, "trained": 18, "pending": 1, "processing": 0, "failed": 0, "done": false }
}
data contiene tutti i campi di Elencare le fonti; qui sopra alcuni sono omessi. result è created (stato 201), updated quando esisteva già una coppia di Q&A con la stessa domanda, senza distinguere maiuscole e minuscole, che ora ha la nuova risposta, oppure unchanged quando aveva esattamente questa risposta (entrambi con stato 200). Un testo viene sempre aggiunto come nuova fonte. Un titolo e una domanda possono avere ciascuno fino a 200 caratteri.
La fonte conta nei caratteri di addestramento dell'agente. Una fonte che supererebbe il limite del tuo piano riceve un errore 403 con il codice character_limit_exceeded, e non viene aggiunto nulla. Vedi Caratteri di addestramento per agente.
Eliminare una fonte
DELETE /api/v1/agents/{agentId}/sources/{sourceId} · scope sources:write
Elimina subito la fonte e ciò che l'agente ha imparato da essa, come quando la elimini nella scheda Knowledge. Nient'altro deve essere addestrato di nuovo.
{ "id": "SOURCE_ID", "deleted": true, "training": { "total": 17, "trained": 17, "pending": 0, "processing": 0, "failed": 0, "done": true } }
Registrare un webhook
POST /api/v1/agents/{agentId}/webhooks · scope webhooks:write
Registra un webhook per gli eventi dell'agente: un REST hook, come lo usano i trigger istantanei di Zapier e Make. intoCHAT invia poi ogni evento all'indirizzo come descritto in Webhook, firmato e ritentato come un webhook aggiunto nella scheda Leads.
| Campo | Contenuto |
|---|---|
url | Obbligatorio. L'indirizzo a cui inviare gli eventi. Come nella scheda Leads, deve iniziare con https:// e puntare a un server pubblico; gli indirizzi di reti private o interne vengono rifiutati. |
events | Obbligatorio. Uno o più tra lead.created, handoff.requested, form.submitted, booking.created, live_chat.requested e return.requested. Vedi Eventi. |
source | Facoltativo. zapier, make o api (il valore predefinito): ciò che la scheda Leads mostra accanto al webhook, per esempio via Zapier. |
curl https://www.intochat.ai/api/v1/agents/AGENT_ID/webhooks \
-H "Authorization: Bearer ic_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://hooks.example.com/intochat", "events": ["lead.created"], "source": "api" }'
{
"id": "WEBHOOK_ID",
"agentId": "AGENT_ID",
"url": "https://hooks.example.com/intochat",
"events": ["lead.created"],
"source": "api",
"secret": "whsec_…",
"createdAt": "2026-10-08T09:00:00.000Z"
}
La risposta ha lo stato 201. Conserva id per annullare la registrazione in seguito. secret è il segreto di firma del webhook, restituito solo qui; usalo per verificare la firma se il tuo ricevitore può farlo. Gli strumenti che non possono controllare le firme, come Zapier e Make, possono ignorarlo.
Un webhook registrato compare nella scheda Leads dell'agente con un'etichetta via Zapier, via Make o via API, dove il proprietario può metterlo in pausa o rimuoverlo. Ricorda la chiave che l'ha registrato: revocare quella chiave lo elimina. Un agente può avere fino a 25 webhook registrati, oltre ai 5 aggiunti nella scheda Leads; oltre questo numero, la richiesta riceve un errore 400.
Annullare la registrazione di un webhook
DELETE /api/v1/webhooks/{webhookId} · scope webhooks:write
Elimina un webhook registrato tramite l'API, con la sua cronologia degli invii. Può farlo qualsiasi chiave dello stesso account. Un webhook aggiunto nella scheda Leads, il webhook di un altro account o uno già rimosso riceve 404.
{ "id": "WEBHOOK_ID", "deleted": true }
Elencare gli eventi
GET /api/v1/agents/{agentId}/events/{event} · scope agents:read, più leads:read o conversations:read
Gli ultimi eventi di un tipo dell'agente, dal più recente, ognuno con esattamente la stessa forma del corpo di un invio webhook. Gli strumenti di automazione lo interrogano periodicamente invece di aspettare un webhook, per esempio per mostrare dati di esempio reali. Accetta limit, da 1 a 100 (valore predefinito 20).
event | Richiede anche | Costruito da |
|---|---|---|
lead.created | leads:read | Lead, dal salvato più di recente |
form.submitted | leads:read | Invii dei moduli |
booking.created | leads:read | Prenotazioni |
return.requested | leads:read | Richieste di reso |
handoff.requested | conversations:read | Conversazioni passate al team via email |
live_chat.requested | conversations:read | Conversazioni in cui l'agente ha chiesto al tuo team di intervenire |
conversation.created | conversations:read | Nuove conversazioni. Questo evento non ha un webhook; si può solo elencare. |
curl "https://www.intochat.ai/api/v1/agents/AGENT_ID/events/lead.created?limit=5" \
-H "Authorization: Bearer ic_live_YOUR_KEY"
{
"data": [
{
"id": "LEAD_ID",
"event": "lead.created",
"created_at": "2026-10-07T09:30:00.000Z",
"agent": { "id": "AGENT_ID", "name": "Acme Assistant" },
"data": {
"leadId": "LEAD_ID",
"agentId": "AGENT_ID",
"agentName": "Acme Assistant",
"email": "jane@example.com",
"phone": null,
"name": "Jane",
"customFields": [],
"source": "form",
"conversationId": "CONVERSATION_ID",
"collectedAt": "2026-10-07T09:30:00.000Z"
}
}
]
}
Le differenze rispetto a un invio:
idè l'ID del record, non un ID di invio, quindi lo stesso evento ha sempre lo stessoid: l'ID del lead, dell'invio del modulo, della prenotazione, della richiesta di reso o della conversazione. Per i passaggi e le richieste di live chat è l'ID della conversazione, due punti e l'orario in millisecondi, perché una conversazione può chiedere di nuovo in seguito.created_atindica quando è stato salvato il record.- I dati vengono ricostruiti da ciò che intoCHAT conserva. Il
summarydi un passaggio non viene conservato, quindi ènull, etestèfalse. Un passaggio che ha aperto un ticket helpdesk contiene il suoticket, come il webhook. IlproviderStatusdi una prenotazione èpendingfinché attende la tua conferma, altrimentiaccepted. Una richiesta di reso ha il suostatusattuale,requestedohandled. - I dati di
conversation.createdcontengonoconversationId,channel(widgetoapi),page,countryecreatedAt.
Leggere eventi di esempio
GET /api/v1/agents/{agentId}/events/{event}/samples · scope agents:read
Fino a 3 degli ultimi eventi dell'agente, come in Elencare gli eventi, così uno strumento ha sempre dati da cui associare i campi. Quando l'agente non ne ha ancora, o la chiave non ha lo scope richiesto da quell'evento (leads:read o conversations:read), restituisce invece un esempio documentato con gli stessi campi, e sample è true.
{
"data": [
{
"id": "sample_booking.created",
"event": "booking.created",
"created_at": "2026-10-07T09:30:00.000Z",
"agent": { "id": "AGENT_ID", "name": "Acme Assistant" },
"data": { "bookingId": "sample_booking", "eventTitle": "30 min intro call", "attendeeEmail": "jane@example.com" }
}
],
"sample": true
}
I data dell'esempio contengono tutti i campi dell'evento; qui sopra alcuni sono omessi.
Limiti
- L'API è inclusa da Starter in su. Con Free non si possono creare chiavi e quelle esistenti ricevono
plan_required. - 60 richieste al minuto per chiave, e al massimo 20 chiavi attive per account.
- Ogni risposta in chat conta come un messaggio del tuo piano. Un agente risponde al massimo a 1.000 messaggi all'ora, widget e API insieme.
- Una risposta in chat deve terminare entro 55 secondi.
- Fonti: solo testi e coppie di Q&A. Pagine web, file e pagine Notion si aggiungono nella dashboard.
- Fino a 25 webhook registrati per agente, oltre ai 5 aggiunti nella scheda Leads.
- I contatti si creano e si aggiornano uno alla volta. Per aggiungerne molti in una volta, usa Importare un file CSV nella dashboard.
- Non ci sono ancora endpoint per creare o modificare agenti, inviare moduli, prenotare appuntamenti o prendere in carico live chat.
Passi successivi
- Ricevi lead e passaggi sul tuo server nel momento in cui avvengono: Webhook.
- Usa intoCHAT in Zapier o Make: Zapier e Make.
- Fai chiamare la tua API all'agente mentre risponde: Azioni API.
- Scrivi buoni testi e coppie di Q&A: Testo e Q&A.
- Controlla che cosa include il tuo piano: Piani e limiti.