Messaggi e conversazioni
Le API dei messaggi ti consentono di inviare un messaggio a qualsiasi contatto, rileggere una conversazione, correggere o rimuovere un messaggio già inviato, reagire a un messaggio, recuperare l’intero thread di una sessione di chat, esportare una trascrizione e contrassegnare le chat come lette o non lette, il tutto senza aprire la posta in arrivo.
Tutti i percorsi in questa pagina sono relativi all’URL di base https://api.youraiconnector.com/v1. Ogni richiesta richiede la tua chiave API: consulta Autenticazione per l’elenco completo delle modalità di invio. Gli esempi seguenti utilizzano l’intestazione X-API-Key, con un esempio cURL che mostra anche il formato di query ?apiKey=.
Come funziona la consegna: L’invio di un messaggio non attende che arrivi a destinazione. L’API accetta il messaggio, risponde immediatamente con un ID messaggio e quindi lo consegna in background sul canale del contatto (WhatsApp, SMS, Instagram, ecc.). Per monitorare se un messaggio è stato effettivamente consegnato o letto, ascolta gli aggiornamenti di stato con i Webhook: non eseguire il polling. La risposta di invio conferma solo che il messaggio è stato accettato.
Inviare un messaggio
Esistono due modi per inviare un messaggio. Scegli quello più adatto al modo in cui identifichi già il contatto:
- Invia tramite ID contatto — conosci già l’ID del contatto (ad esempio, hai creato il contatto tramite l’API o l’hai ottenuto da un webhook). Usa
POST /contacts/{contactId}/send-message. - Invia tramite identità del contatto — conosci il numero di telefono del contatto, l’ID Instagram, ecc., ma non il suo ID interno. Usa
POST /contacts/sende lascia che la piattaforma trovi il contatto corretto.
Entrambi mettono in coda il messaggio allo stesso modo e lo consegnano sul canale in cui si trova il contatto. Non devi scegliere un trasporto: la piattaforma instrada i contatti WhatsApp su WhatsApp, i contatti SMS su SMS e così via.
Entrambi trovano solo contatti già esistenti. Nessuna delle due chiamate ne crea uno: un ID o un’identità che non corrispondono a nulla vengono restituiti come 404, non diventano un nuovo contatto. Quindi, se stai scrivendo a qualcuno per la prima volta, crea prima il contatto con POST /contacts oppure, su WhatsApp Web, usa Invia direttamente a un numero WhatsApp Web qui sotto, che crea il contatto nella stessa chiamata.
Invia tramite ID contatto
POST /contacts/{contactId}/send-message
| Campo | Obbligatorio | Descrizione |
|---|---|---|
body |
Sì | Il testo del messaggio da inviare, fino a 65.536 caratteri. Un corpo più lungo di quanto consentito dal canale in un singolo messaggio (1.500 su WhatsApp Business API e SMS, 1.000 su Instagram, 2.000 su Messenger, 4.096 su Telegram e LinkedIn, 5.000 su LINE, 6.000 su TikTok, 7.000 su Viber, 65.536 su WhatsApp Web; nessun limite per email, widget chat e canali personalizzati) viene recapitato come più messaggi in ordine, suddivisi in corrispondenza di interruzioni di paragrafo o di frase. La risposta contiene quindi messageIds per ogni parte e autoSplit: true. |
mediaUrl |
No | URL di un file multimediale (immagine, audio, video, documento) da allegare. |
mediaContentType |
No | Tipo MIME del file multimediale allegato, ad es. image/jpeg. Viene ricavato dall’estensione del file dell’URL se omesso (.mp3 → audio/mpeg, .pdf → application/pdf); impostalo per un URL senza estensione. |
sendAsVoiceNote |
No | Solo WhatsApp Web, solo audio: recapita l’audio come nota vocale (il fumetto di riproduzione). L’audio che non è in formato OGG/Opus viene convertito al momento dell’invio. Il valore predefinito è false. |
pauseBot |
No | true mette in pausa l’IA per questo contatto mentre il messaggio viene inviato, per consentire a un umano di prendere il controllo. Vedi Metti in pausa o riprendi l’IA. |
clearIncompleteReply |
No | true scarta una risposta del bot a metà, in modo che non riprenda dopo il tuo messaggio. |
human_reply |
No | true contrassegna il messaggio come scritto da una persona del tuo team anziché da un’integrazione. L’IA lo tratterà quindi come una risposta di un collega nella conversazione e una risposta che l’IA aveva messo in coda per l’ultimo messaggio del contatto verrà annullata, in modo che il contatto non riceva due risposte. Non mette in pausa l’IA; usa pauseBot per questo. Il valore predefinito è false. |
Su LinkedIn, un messaggio inviato in questo modo, o dalla posta in arrivo, viene recapitato anche mentre una persona sta gestendo la conversazione sul lato LinkedIn. Le risposte dell’IA e i suoi follow-up vengono trattenuti in tale conversazione. Una risposta trattenuta viene rimossa dalla chat invece di essere mostrata come fallita, poiché non è stato inviato nulla e non viene utilizzato alcun credito. L’ultima risposta dell’IA prima di passare la conversazione a una persona viene comunque recapitata.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."
}'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/send-message",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
body: "Hi! Your appointment is confirmed for tomorrow at 10:00.",
}),
}
);
const data = await res.json();
console.log(data.messageId);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/send-message",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."},
)
print(res.json()["messageId"])
Risposta (200 OK):
{
"success": true,
"messageId": "aB3dE5fG7hI9jK1lM2nO",
"contactId": "contact123",
"channel": "whatsapp",
"message": "Message created successfully. Delivery is being processed."
}
Invia tramite identità del contatto
POST /contacts/send
Utilizza questo metodo quando non disponi dell’ID interno del contatto. Fornisci il body del messaggio più o un contact_id, o un channel insieme al campo di identità che corrisponde a quel canale.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
body |
Sì | Il testo del messaggio da inviare, fino a 65.536 caratteri. Un corpo più lungo di quanto consentito dal canale in un singolo messaggio (1.500 su WhatsApp Business API e SMS, 1.000 su Instagram, 2.000 su Messenger, 4.096 su Telegram e LinkedIn, 5.000 su LINE, 6.000 su TikTok, 7.000 su Viber, 65.536 su WhatsApp Web; nessun limite per email, chat widget e canali personalizzati) viene recapitato come più messaggi in ordine, suddivisi in corrispondenza di interruzioni di paragrafo o di frase. La risposta conterrà quindi messageIds per ogni parte e autoSplit: true. |
contact_id |
No | ID di un contatto esistente. Quando impostato, i campi di identità sottostanti non sono necessari. |
channel |
No | Canale su cui inviare. Obbligatorio quando contact_id non è specificato. Uno dei 14 canali di invio in uscita: whatsapp, whatsapp_web, sms, instagram, instagram_private, messenger, telegram, chat-widget, custom, email, line, imessage, linkedin, viber. |
phone_number |
No | Numero di telefono del contatto in formato internazionale. Utilizzato con whatsapp, whatsapp_web e sms. |
instagram_id |
No | ID utente Instagram del contatto. Utilizzato con instagram. |
messenger_id |
No | ID utente Messenger del contatto. Utilizzato con messenger. |
telegram_user_id |
No | ID utente Telegram del contatto. Utilizzato con telegram. |
media_url |
No | URL di un file multimediale da allegare. |
media_content_type |
No | Tipo MIME del file multimediale allegato, ad es. image/jpeg. |
Quali canali possono essere risolti tramite identità. Solo sei dei 14 accettano un campo di identità invece di un contact_id: whatsapp, whatsapp_web e sms vengono cercati tramite phone_number, instagram tramite instagram_id, messenger tramite messenger_id e telegram tramite telegram_user_id. Gli altri otto — instagram_private, chat-widget, custom, email, line, imessage, linkedin e viber — non hanno un’identità pubblica da ricercare, quindi l’invio su tali canali richiede contact_id; passare solo channel restituisce un 400 che indica che contact_id è richiesto.
cURL (utilizzando il formato di query ?apiKey=)
curl -X POST "https://api.youraiconnector.com/v1/contacts/send?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "whatsapp",
"phone_number": "+31612345678",
"body": "Hi! Your appointment is confirmed."
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/contacts/send", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
channel: "whatsapp",
phone_number: "+31612345678",
body: "Hi! Your appointment is confirmed.",
}),
});
const data = await res.json();
console.log(data.message_id, data.channel);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/send",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"channel": "whatsapp",
"phone_number": "+31612345678",
"body": "Hi! Your appointment is confirmed.",
},
)
data = res.json()
print(data["message_id"], data["channel"])
Risposta (201 Created):
{
"success": true,
"message_id": "aB3dE5fG7hI9jK1lM2nO",
"contact_id": "contact123",
"channel": "whatsapp"
}
Perché un messaggio potrebbe essere rifiutato: Un contatto con la modalità non disturbare o privata attivata non può ricevere messaggi in uscita — la richiesta fallisce con un
422. Se nessun contatto corrisponde all’ID o all’identità fornita, si ottiene un404.
Invio su WhatsApp Web: variazioni e protezione dai burst
Due aspetti si applicano a body quando il contatto utilizza WhatsApp Web.
Le parentesi Spintax vengono espanse a ogni invio. Un body di {Hi|Hello|Hey} there, quick question viene inviato come uno dei tre saluti, scelto per quello specifico invio: le parentesi non raggiungono mai il contatto. Usale per fornire a ogni contatto un messaggio di apertura diverso dallo stesso codice di integrazione. Il testo senza parentesi viene inviato esattamente come scritto.
I burst di messaggi di apertura identici vengono rifiutati. Se dieci messaggi di apertura quasi identici partono da un numero WhatsApp Web entro un’ora, verso contatti che non ti hanno mai scritto, quelli successivi non vengono consegnati: l’invio viene accettato come di consueto (riceverai comunque un messageId), ma il messaggio rimarrà con status: "failed" e error_code: "opener_burst", accompagnato da una motivazione leggibile dal cliente. Riprovare con lo stesso testo non serve: varia il testo, attendi un’ora e invia di nuovo. Le risposte all’interno di conversazioni esistenti non sono mai interessate. La spiegazione è disponibile in I messaggi di apertura identici portano alla limitazione dei numeri.
Invia direttamente a un numero WhatsApp Web
POST /whatsapp-web/send
Invia a un numero di telefono su WhatsApp Web senza dover prima cercare un contatto. Se il numero non è ancora un contatto, questo viene creato nella stessa chiamata, con l’IA disattivata per esso, in modo che il messaggio appaia come inviato manualmente e nessun assistente prenda il controllo della conversazione in seguito. Un contatto esistente viene riutilizzato così com’è.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
phoneNumber |
Sì | Il numero a cui inviare il messaggio, in formato internazionale (+31612345678). |
message |
No | Il testo da inviare. Deve essere presente message o mediaUrl. |
mediaUrl |
No | URL pubblico di un file da inviare. Deve essere presente message o mediaUrl. |
mediaContentType |
No | Tipo MIME del file, ad esempio image/jpeg. Viene determinato dall’URL se omesso. |
sendAsVoiceNote |
No | true invia un file audio come nota vocale anziché come allegato. |
fromPhoneNumber |
No | Da quale dei tuoi numeri WhatsApp Web collegati inviare, in formato internazionale. Per impostazione predefinita, utilizza il numero a cui appartiene già il contatto. |
campaignId |
No | Utilizza gli orari di attività di questo Agente invece di quelli predefiniti dell’account. Deve essere un Agente dello stesso account. |
ignoreActiveHours |
No | true invia immediatamente, indipendentemente dagli orari di attività. |
sub_account_id |
No | Per le agenzie: invia per conto di uno dei tuoi account cliente. |
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-web/send?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+31612345678",
"message": "Hi Alex, your quote is ready."
}'
Una chiamata riuscita risponde con 202:
{ "success": true, "queued": true, "contactId": "abc123" }
202 significa accettato, non ancora consegnato. Al di fuori degli orari di attività, l’invio viene trattenuto e parte nel primo slot consentito, a meno che non sia stato passato ignoreActiveHours. Leggi lo stato del messaggio con Elenca i messaggi di un contatto utilizzando l’contactId ottenuto qui.
Quando l’invio non va a buon fine:
| Stato | Codice | Cosa è successo |
|---|---|---|
400 |
INVALID_PHONE_FORMAT |
Il numero non è in formato internazionale, oppure manca phoneNumber, o mancano sia message che mediaUrl. |
400 |
CONTACT_DND |
Quel contatto è impostato su Non disturbare, quindi non viene inviato nulla in uscita verso di lui. |
400 |
CONTACT_PRIVATE |
Quel contatto è contrassegnato come privato. |
404 |
CAMPAIGN_NOT_FOUND |
Nessun Agente corrisponde all’campaignId passato. |
403 |
CAMPAIGN_FORBIDDEN |
Quell’Agente appartiene a un altro account. |
402 |
L’account non ha più crediti, o non è collegato alcun numero WhatsApp Web. |
Una seconda chiamata per lo stesso contatto mentre un invio è ancora in attesa risponde con 409, in modo che non si accumuli mai una coda dietro una singola persona.
Registra una nota in una conversazione
POST /contacts/notes
Aggiunge una riga alla conversazione di un contatto senza inviarla. Usala per il contesto che il tuo team e l’IA dovrebbero avere, ma che il contatto non dovrebbe mai ricevere: un riepilogo di una telefonata appena effettuata dal tuo assistente vocale, un’osservazione dal tuo CRM o una nota di un collega. Funziona su ogni canale (WhatsApp, SMS, Instagram, Messenger, Telegram, il widget della chat, canali personalizzati e così via).
Cosa succede a una nota:
- Viene visualizzata nella chat nella posta in arrivo come una scheda Nota gialla, con l’autore se ne hai indicato uno.
- L’IA la legge come parte della cronologia della conversazione, contrassegnata come nota interna, in modo che la sua risposta successiva ne tenga conto.
- Non viene mai inviata al contatto, non comporta costi di crediti di messaggi e non attiva nulla: nessuna risposta dell’IA, nessuna automazione, nessun webhook, nessuna notifica, nessun badge di messaggio non letto. Non mette in pausa l’IA e non conta come una risposta da parte del tuo team.
Trova il contatto nello stesso modo di Invia tramite identità del contatto: ovvero il suo ID, o un channel più l’identificativo corrispondente. Una nota viene inviata solo a un contatto già esistente; se non c’è corrispondenza, si ottiene un 404.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
contact_id |
Uno dei due | L’ID del contatto. |
channel + identifier |
Uno dei due | channel più phone_number (WhatsApp, WhatsApp Web, SMS), instagram_id, messenger_id o telegram_user_id, come in Invia tramite identità del contatto. |
body |
Sì | Il testo della nota, fino a 4.000 caratteri. Le interruzioni di riga vengono mantenute. |
author |
No | Chi o cosa l’ha scritta, fino a 80 caratteri, ad esempio Voice agent o Sarah (sales). Mostrato sulla scheda e all’IA. |
timestamp |
No | Quando è successo, in millisecondi epoch. Il valore predefinito è adesso. Usa l’orario di fine della chiamata in modo che la nota si posizioni correttamente nel thread. Non può essere più di 5 minuti nel futuro; un orario successivo viene rifiutato con un 400. |
external_id |
No | Il tuo ID per questa nota, fino a 200 caratteri, ad esempio l’ID della chiamata. L’invio dello stesso external_id per lo stesso contatto non aggiunge una seconda nota; la risposta conterrà quindi duplicate: true. Usalo in modo che un webhook ritentato non possa registrare la stessa chiamata due volte. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/notes" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "whatsapp",
"phone_number": "+31612345678",
"author": "Voice agent",
"body": "Voice call, 3:12. Asked about knee surgery waiting times, prefers a call back on Tuesday morning.",
"external_id": "call_8f2k1"
}'
Risposta (201, o 200 con duplicate: true quando il external_id era già stato registrato)
{
"success": true,
"messageId": "note_4c1f0e...",
"contactId": "contact123"
}
Una nota appare in Elenca i messaggi di un contatto con type: "note".
Genera una bozza di risposta con l’IA
POST /contacts/{contactId}/draft-reply
Chiede all’agente IA che gestisce una conversazione di scrivere la risposta successiva e ti restituisce il testo. Non viene inviato nulla. È la stessa bozza che scrive il pulsante Genera risposta nella posta in arrivo: l’agente utilizza la sua configurazione, la sua base di conoscenza e la conversazione finora, e risponde nella lingua del contatto. Usalo per inserire un essere umano (o la tua app) tra l’IA e il contatto: recupera la bozza, mostrala per l’approvazione, quindi inviala con Invia tramite ID contatto, modificata o così com’è.
- La bozza viene scritta dall’agente assegnato al contatto. Un contatto che non ha ancora un agente riceve l’agente che risponderebbe al suo prossimo messaggio.
- Durante la stesura, l’agente non esegue alcuno strumento o funzione, quindi non avviene alcuna prenotazione, etichettatura, trasferimento o altra azione.
- Non viene memorizzato nulla nella conversazione e il contatto non vede nulla.
- Una bozza costa gli stessi crediti di una risposta IA da parte di quell’agente in questa conversazione, e nulla quando è collegata la tua chiave IA.
- La conversazione deve contenere almeno un messaggio.
Tutti i campi del corpo sono facoltativi; un corpo vuoto (o nessun corpo) redige la risposta successiva.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
instruction |
No | Un’istruzione una tantum per questa bozza, fino a 2.000 caratteri, uguale alla pressione prolungata di Genera risposta nella posta in arrivo. Ad esempio Offer Tuesday at 3pm o Ask for their email address. |
campaign_id |
No | Redigi sotto questa campagna invece che con l’agente del contatto. |
purpose |
No | chat_reply (predefinito) scrive un messaggio al contatto. faq_answer scrive una breve risposta alla domanda del contatto che funziona da sola, per una FAQ della base di conoscenza. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/draft-reply" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "instruction": "Offer Tuesday at 3pm for the consultation" }'
Risposta (200)
{
"success": true,
"contact_id": "contact123",
"draft": "Hi Sara, Tuesday at 3pm works for the consultation. Shall I put you down for it?"
}
Un 400 significa che la conversazione non ha ancora messaggi, i tuoi crediti sono esauriti o il contatto non ha un agente o una campagna da cui redigere ( error indica quale). Un 404 significa che il contatto non esiste o che la chiave di un membro del team è limitata ai contatti che non può vedere. La chiave o il membro del team deve avere l’autorizzazione per modificare i messaggi.
Utilizzi un client IA tramite MCP? La stessa azione è disponibile come strumento
generate_reply_draft.
Elenca i messaggi di un contatto
GET /contacts/{contactId}/messages
Restituisce i messaggi di un contatto, dal più recente, con paginazione basata su cursore.
| Parametro di query | Obbligatorio | Descrizione |
|---|---|---|
limit |
No | Dimensione della pagina. Predefinito 50, massimo 100. |
cursor |
No | Il valore next_cursor da una risposta precedente. Restituisce i messaggi precedenti al cursore. |
filter |
No | Filtra per tipo di contenuto: all (predefinito), text, media o tool_use. |
direction |
No | Filtra per direzione: all (predefinito), inbound (ricevuto dal contatto) o outbound (inviato da te). |
Nota sul filtraggio e la paginazione: I filtri
filteredirectionvengono applicati a ogni pagina dopo la lettura, quindi una pagina filtrata può contenere meno elementi dilimit. Ilnext_cursoravanza comunque attraverso l’intera conversazione, quindi continua la paginazione finchénext_cursornon ènull.
cURL
curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&direction=inbound" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const params = new URLSearchParams({ limit: "50", direction: "inbound" });
const res = await fetch(
`https://api.youraiconnector.com/v1/contacts/contact123/messages?${params}`,
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.messages, data.next_cursor);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/contacts/contact123/messages",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"limit": 50, "direction": "inbound"},
)
data = res.json()
print(data["messages"], data["next_cursor"])
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123",
"messages": [
{
"id": "aB3dE5fG7hI9jK1lM2nO",
"body": "Hi! Thanks for reaching out.",
"direction": "inbound",
"channel": "whatsapp",
"status": "delivered",
"type": null,
"timestamp": "2026-06-01T10:00:00.000Z",
"media_url": null,
"media_content_type": null,
"bot_reply": false
}
],
"next_cursor": "cD4eF6gH8iJ0kL2mN3oP"
}
Campi del messaggio
| Campo | Descrizione |
|---|---|
id |
ID univoco del messaggio. |
body |
Contenuto testuale del messaggio. Per un messaggio con un allegato, body inizia con una nota tra parentesi di ciò che è arrivato, seguita da qualsiasi didascalia, ad esempio [THE CONTACT UPLOADED AN IMAGE] Here is my CV o [THE CONTACT UPLOADED A VOICE NOTE] - [TRANSCRIPTION: ...]. Le note vocali e i video includono la trascrizione. |
direction |
inbound (ricevuto dal contatto) o outbound (inviato dal tuo account). |
channel |
Canale su cui il messaggio è stato inviato o ricevuto (es. whatsapp, sms, instagram). |
status |
Stato di consegna attuale, es. Created, sent, delivered, read, failed. |
type |
Tipo di messaggio. I messaggi di solo testo hanno un tipo null; l’attività dello strumento di assistenza automatizzata è contrassegnata come tool_use. |
timestamp |
Orario ISO 8601 in cui il messaggio è stato creato. |
media_url |
URL di un file multimediale allegato, se presente. Questo link smette di funzionare 7 giorni dopo l’arrivo del messaggio, su ogni canale (WhatsApp Business API, WhatsApp Web, Instagram, Messenger, Telegram, widget chat e il resto). Ottienine uno nuovo con Scarica l’allegato di un messaggio. |
media_content_type |
Tipo MIME del supporto allegato, se presente. |
bot_reply |
true quando il messaggio è stato generato dall’assistente IA. |
score |
La tua valutazione del messaggio: 1 pollice in su, -1 pollice in giù, 0 quando non è stato valutato. Vedi Valuta o aggiungi ai preferiti un messaggio. |
is_important |
true quando il messaggio è stato aggiunto ai preferiti. |
is_deleted |
true quando il messaggio è stato eliminato. I messaggi eliminati rimangono nell’elenco ma il loro body e media_url sono vuoti. |
reactions |
Reazioni emoji al messaggio, da entrambe le parti. Sempre un array: vuoto quando non ce ne sono. Ogni voce ha emoji, from_phone_number, from_me (true quando la reazione è la tua) e reacted_at. |
faq_ids_used |
ID delle FAQ della Knowledge Base che l’IA aveva davanti a sé quando ha scritto questa risposta: quelle scelte per l’ultimo messaggio più quelle conservate dall’inizio della conversazione. Lo stesso elenco si trova su ogni messaggio di una risposta inviata in più parti. Sempre un array, vuoto per i messaggi in entrata, i messaggi inviati da persone, i follow-up automatici e le risposte dell’IA inviate prima del 25 settembre 2026. |
faqs_used |
Le stesse FAQ con la loro domanda: ogni voce ha id e question. question è null quando la FAQ è stata eliminata nel frattempo. |
Scarica l’allegato di un messaggio
POST /chat-exports/media/download-url
Fornisce un nuovo link di download per il file allegato a un messaggio: un’immagine, un messaggio vocale, un video o un documento. Il link è valido per 1 ora. Usalo quando vuoi salvare gli allegati altrove (ad esempio, per archiviare CV o messaggi vocali inviati da un contatto), o quando il media_url su un messaggio o un webhook di Nuovo Messaggio non si apre più.
Per trovare messaggi con allegati, elenca i messaggi di un contatto con filter=media. Il id di ogni messaggio e l’ID del contatto formano il messagePath.
| Campo del corpo | Obbligatorio | Descrizione |
|---|---|---|
messagePath |
Sì | Quale messaggio, nel formato contacts/{contactId}/messages/{messageId}. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/chat-exports/media/download-url" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messagePath": "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO"}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/chat-exports/media/download-url", {
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ messagePath: "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO" }),
});
const { data } = await res.json();
console.log(data.url); // download the file within the hour
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/chat-exports/media/download-url",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"messagePath": "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO"},
)
file_url = res.json()["data"]["url"]
Risposta (200 OK):
{
"success": true,
"data": {
"url": "https://storage.googleapis.com/...",
"expiresInMs": 3600000
}
}
| Campo | Descrizione |
|---|---|
data.url |
Il link per il download. Recupera il file direttamente da esso, non è necessaria alcuna chiave API. |
data.expiresInMs |
Per quanto tempo funziona il link, in millisecondi (3600000 = 1 ora). Chiama nuovamente l’endpoint per un nuovo link. |
| Stato | Quando |
|---|---|
400 |
messagePath manca o non è nel formato contacts/{contactId}/messages/{messageId}, oppure il messaggio non ha alcun allegato che possa essere scaricato in questo modo. Alcuni allegati meno recenti sono archiviati presso il provider del canale e non possono essere riemessi, e un reel o un post di Instagram condiviso è un link a Instagram piuttosto che un file. |
403 |
Il contatto non appartiene al tuo account. |
404 |
Non esiste alcun messaggio con quell’ID per quel contatto. |
Utilizzi un client AI tramite MCP? La stessa azione è disponibile come strumento
get_chat_media_download_url.
Elenca sessioni di chat
Una sessione di chat è una finestra di conversazione con un contatto. Si apre al primo messaggio in arrivo quando non c’è alcuna sessione aperta e si chiude automaticamente 48 ore dopo l’ultimo messaggio in arrivo del contatto (ogni nuovo messaggio in arrivo posticipa la chiusura di altre 48 ore). L’IA che conclude una chat non chiude la sessione; attiva solo il webhook Chat Concluded. Le sessioni sono il modo in cui suddividi una lunga cronologia in conversazioni leggibili invece di un unico elenco infinito.
Sessioni recenti per tutti i contatti
GET /chat-sessions/recent
Restituisce le sessioni iniziate nelle ultime X ore, dalla più recente, per ogni contatto sull’account.
| Parametro di query | Obbligatorio | Descrizione |
|---|---|---|
hours |
Sì | Quante ore indietro controllare. Deve essere un numero intero positivo. |
status |
No | Restituisci solo le sessioni con questo stato: ChatSessionOpened o ChatSessionClosed. |
limit |
No | Numero massimo di sessioni da restituire. Predefinito 100, massimo 100. |
includeMessages |
No | true aggiunge un array messages a ogni sessione. Disattivato per impostazione predefinita perché rende la risposta molto più grande. |
cURL
curl "https://api.youraiconnector.com/v1/chat-sessions/recent?hours=24&status=ChatSessionClosed" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const params = new URLSearchParams({ hours: "24", status: "ChatSessionClosed" });
const res = await fetch(`https://api.youraiconnector.com/v1/chat-sessions/recent?${params}`, {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data.total_sessions, data.data.sessions);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/chat-sessions/recent",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"hours": 24, "status": "ChatSessionClosed"},
)
data = res.json()["data"]
print(data["total_sessions"], data["sessions"])
Risposta (200 OK):
{
"success": true,
"data": {
"hours_ago": 24,
"total_sessions": 2,
"sessions": [
{
"session_id": "session456",
"contact_id": "contact123",
"contact_name": "Jane Doe",
"contact_phone": "+31612345678",
"contact_email": "jane@example.com",
"start_date_time": "2026-06-01T09:55:00.000Z",
"end_date_time": "2026-06-01T10:20:00.000Z",
"status": "ChatSessionClosed",
"tag": "Booking enquiry"
}
]
}
}
Tutte le sessioni per un singolo contatto
GET /chat-sessions/{contactId}
Restituisce ogni sessione di chat per un singolo contatto. Stessi parametri status, limit e includeMessages di cui sopra: hours non si applica qui.
cURL
curl "https://api.youraiconnector.com/v1/chat-sessions/contact123?limit=20" \
-H "X-API-Key: YOUR_API_KEY"
Risposta (200 OK):
{
"success": true,
"data": {
"contact_id": "contact123",
"contact_name": "Jane Doe",
"total_sessions": 2,
"sessions": [
{
"id": "session456",
"start_date_time": "2026-06-01T09:55:00.000Z",
"end_date_time": "2026-06-01T10:20:00.000Z",
"status": "ChatSessionClosed",
"tag": "Booking enquiry"
}
]
}
}
I nomi dei campi ID sessione differiscono tra i due endpoint. L’elenco delle sessioni recenti lo chiama
session_id(contiene anche i dettagli del contatto, poiché le sessioni provengono da molti contatti); l’elenco per contatto lo chiamaid. Entrambi i valori sono ciò che passi come{sessionId}quando recuperi l’intero thread qui sotto.
Quando includeMessages=true, ogni sessione ottiene un array messages le cui voci contengono id, body, direction, timestamp, type, channel e status.
Recupera un thread di sessione chat
GET /contacts/{contactId}/chat-sessions/{sessionId}/messages
Una sessione di chat raggruppa i messaggi di un contatto in un’unica finestra di conversazione. Questo endpoint restituisce l’intero thread di una singola sessione, dal più vecchio al più recente, insieme ai metadati della sessione. È possibile trovare gli ID delle sessioni per un contatto tramite gli endpoint delle sessioni di chat.
cURL
curl "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.session, data.messages);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["session"], data["messages"])
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123",
"session": {
"id": "session456",
"status": "ChatSessionClosed",
"start_date_time": "2026-06-01T09:55:00.000Z",
"end_date_time": "2026-06-01T10:20:00.000Z",
"tag": "Booking enquiry"
},
"messages": [
{
"id": "aB3dE5fG7hI9jK1lM2nO",
"body": "Hi! Thanks for reaching out.",
"direction": "inbound",
"channel": "whatsapp",
"status": "delivered",
"type": null,
"timestamp": "2026-06-01T09:55:00.000Z",
"media_url": null,
"media_content_type": null,
"bot_reply": false
}
]
}
L’oggetto session riporta status (ChatSessionOpened se attiva, ChatSessionClosed una volta terminata), start_date_time, end_date_time e un tag leggibile dall’utente. L’array messages utilizza gli stessi campi del messaggio dell’endpoint di elenco.
Modifica, elimina e reagisci ai messaggi
Questi endpoint modificano un messaggio dopo che è stato inviato. Due di essi raggiungono il canale del contatto oltre alla tua copia, quindi leggi l’introduzione della sezione prima di implementarli: ciò che è possibile dipende interamente dal canale su cui si trova la conversazione.
Cosa consente ogni canale
| Azione | Canali che possono modificare la copia del contatto | Limite di tempo |
|---|---|---|
| Modifica un messaggio inviato | Widget chat, WhatsApp Web (solo messaggi di testo), Telegram, LinkedIn | Nessuno sul widget chat, 15 minuti su WhatsApp Web, 48 ore su Telegram, 60 minuti su LinkedIn |
| Elimina per tutti | Widget chat, WhatsApp Web, Telegram, LinkedIn | 60 minuti su LinkedIn; gli altri non hanno un limite pubblicato |
| Reagisci con un’emoji | WhatsApp Web, Telegram | Nessuno |
Su ogni altro canale — WhatsApp Business API, SMS, Instagram, Messenger, email, LINE, canali personalizzati — un’eliminazione rimuove comunque il messaggio dalla tua casella di posta, ma il contatto mantiene la propria copia, e la modifica o la reazione non sono affatto possibili.
Modifica un messaggio
POST /contacts/{contactId}/messages/{messageId}/edit
Riscrive un messaggio che hai già inviato, sul dispositivo del contatto e nella tua copia.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
body |
Sì | Il nuovo testo del messaggio. Non deve essere vuoto e non deve superare la lunghezza consentita dal canale in un singolo messaggio (gli stessi limiti per canale di Invia per ID contatto; 4.096 quando il messaggio non ha un canale). |
A differenza dell’eliminazione, questa operazione fallisce in modo evidente quando il canale rifiuta: riceverai un 409 e la tua copia rimarrà esattamente come quella del contatto, poiché mostrare una modifica mai ricevuta creerebbe una discrepanza tra le due parti. Il campo edit_reason ti spiega il motivo: la finestra di modifica del canale è scaduta, il canale è disconnesso, il messaggio contiene un allegato che il canale non può modificare (media_not_editable: su WhatsApp Web è possibile modificare solo i messaggi di testo, non il testo sotto una foto, un video o un file), o si è verificato un altro problema.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "body": "Sorry - I meant Thursday at 3pm." }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ body: "Sorry - I meant Thursday at 3pm." }),
}
);
const data = await res.json();
console.log(data.edited, data.edit_reason);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"body": "Sorry - I meant Thursday at 3pm."},
)
data = res.json()
print(data.get("edited"), data.get("edit_reason"))
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"edited": true,
"edit_reason": "edit_dispatched"
}
Se il canale non accetta la modifica, ricevi invece un 409 e nulla viene modificato:
{
"success": false,
"error": "The message could not be edited",
"edit_reason": "channel_disconnected"
}
Un messaggio che è già stato eliminato, un canale che non può affatto modificare e un messaggio troppo vecchio per il suo canale restituiscono tutti 400 — la richiesta non raggiunge mai il canale.
Elimina un messaggio
DELETE /contacts/{contactId}/messages/{messageId}
Rimuove il messaggio dalla tua conversazione e, dove il canale lo consente, ritira anche la copia del contatto. Nessun corpo della richiesta.
Questa operazione risponde sempre 200 quando il messaggio esisteva, anche se la copia del contatto non poteva essere ritirata — la tua copia è sparita, quindi un errore sarebbe fuorviante. Leggi i tre campi nella risposta per comunicare all’utente cosa è successo realmente:
| Campo | Descrizione |
|---|---|
revoke_supported |
Se questo canale può ritirare i messaggi. |
revoked |
Se la copia sul dispositivo del contatto è stata rimossa. |
revoke_reason |
Perché non è stata rimossa, quando revoked è false — ad esempio revoke_window_closed o already_deleted. |
cURL
curl -X DELETE "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
{ method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.revoked, data.revoke_reason);
Python
import requests
res = requests.delete(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["revoked"], data["revoke_reason"])
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"revoke_supported": true,
"revoked": true,
"revoke_reason": "revoke_dispatched"
}
I messaggi eliminati non vengono rimossi dalla cronologia della conversazione. Rimangono in
GET /contacts/{contactId}/messagesconis_deleted: truee unbodyvuoto emedia_url.
Eliminare più messaggi contemporaneamente
POST /contacts/{contactId}/messages/bulk-delete
Cancella un gruppo di messaggi solo dal tuo lato. I corpi e gli allegati vengono svuotati, ma nulla viene ritirato sul dispositivo del contatto: per ritirare anche un messaggio, eliminalo uno alla volta con l’endpoint per singolo messaggio qui sopra.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
message_ids |
Sì | Un array non vuoto di ID messaggio, fino a 500 per richiesta. messageIds è accettato come alias. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "message_ids": ["msg_1", "msg_2"] }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ message_ids: ["msg_1", "msg_2"] }),
}
);
console.log((await res.json()).deleted);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"message_ids": ["msg_1", "msg_2"]},
)
print(res.json()["deleted"])
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123",
"deleted": 2
}
Reagire a un messaggio
POST /contacts/{contactId}/messages/{messageId}/react
Inserisce la tua reazione emoji su un messaggio, o la rimuove inviando una stringa vuota. Le reazioni del contatto non vengono mai toccate.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
emoji |
Sì | L’emoji con cui reagire, o "" per rimuovere la tua reazione. Deve essere una singola stringa senza spazi, di massimo 16 caratteri. |
Come per la modifica, questa operazione fallisce invece di mostrare una reazione che il contatto non ha mai ricevuto, e l’errore ti indica se vale la pena riprovare:
422— non può mai essere consegnata in questa conversazione: il canale non supporta le reazioni, il messaggio non ha un ID lato canale, o l’emoji è al di fuori del set consentito dal canale.409— il canale era momentaneamente irraggiungibile. Un nuovo tentativo potrebbe funzionare.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "emoji": "👍" }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ emoji: "👍" }),
}
);
const data = await res.json();
console.log(data.reactions);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"emoji": "👍"},
)
print(res.json()["reactions"])
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"reaction_supported": true,
"reaction_reason": "reaction_dispatched",
"reactions": [
{
"emoji": "👍",
"from_phone_number": "+31612345678",
"from_me": true,
"reacted_at": "2026-06-01T10:05:00.000Z"
}
]
}
L’array reactions è l’insieme completo delle reazioni presenti sul messaggio, le tue e quelle del contatto. In caso di 409 o 422 viene restituito invariato, quindi un client che esegue il rendering direttamente da esso non mostrerà mai una reazione che non è stata consegnata.
Valutare o aggiungere un messaggio ai preferiti
PATCH /contacts/{contactId}/messages/{messageId}
Valuta un messaggio con pollice in su o in giù e/o lo contrassegna come importante. Si tratta di una gestione contabile solo dal tuo lato: nulla viene inviato al contatto.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
score |
No | 1 pollice in su, -1 pollice in giù, 0 rimuove la valutazione. |
is_important |
No | true aggiunge una stella al messaggio, false la rimuove. Deve essere un valore booleano reale, non la stringa "true". |
Invia almeno uno dei due, altrimenti riceverai un 400. Viene scritto solo ciò che invii, quindi aggiungere una stella a un messaggio non rimuove mai la sua valutazione e viceversa — e la risposta riporta solo i campi che hai inviato.
cURL
curl -X PATCH "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "score": 1, "is_important": true }'
JavaScript
await fetch("https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1", {
method: "PATCH",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ score: 1, is_important: true }),
});
Python
import requests
requests.patch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"score": 1, "is_important": True},
)
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"score": 1,
"is_important": true
}
Contrassegna i messaggi come letti
È possibile rimuovere lo stato di non letto per messaggi specifici o per l’intera conversazione.
Contrassegna messaggi specifici come letti
POST /contacts/{contactId}/messages/mark-read
Passa gli ID dei messaggi da contrassegnare come letti.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
message_ids |
Sì | Un array non vuoto di ID messaggio (fino a 500 per richiesta). |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]
}'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
message_ids: ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"],
}),
}
);
const data = await res.json();
console.log(data.marked_read);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]},
)
print(res.json()["marked_read"])
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123",
"marked_read": 2
}
Contrassegna l’intera chat come letta
POST /contacts/{contactId}/mark-read
Rimuove l’indicatore di non letto per l’intera conversazione del contatto nella posta in arrivo. Non è richiesto alcun corpo della richiesta.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-read" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
{ method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123"
}
Contrassegna l’intera chat come non letta
POST /contacts/{contactId}/mark-unread
Ripristina l’indicatore di non letto sulla conversazione: utile quando qualcuno del tuo team ha aperto una chat ma la sta passando a qualcun altro. Non è richiesto alcun corpo della richiesta.
Questo è un flag valido solo per la posta in arrivo: non modifica l’orario dell’ultima lettura della conversazione, quindi non viene inviata alcuna conferma di lettura al contatto sui canali che le supportano.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-unread" \
-H "X-API-Key: YOUR_API_KEY"
Risposta (200 OK):
{
"success": true,
"contact_id": "contact123"
}
Esporta una conversazione
Le esportazioni forniscono un’intera conversazione come trascrizione leggibile, invece di sfogliare i messaggi pagina per pagina. Ogni endpoint di esportazione accetta un filter di all (predefinito), text, media o tool_use, che corrisponde al filtro nell’elenco dei messaggi.
Esporta la chat di un contatto
GET /chat-exports/{contactId}
| Parametro di query | Obbligatorio | Descrizione |
|---|---|---|
format |
No | txt (predefinito) restituisce un link per il download di una trascrizione in testo semplice. json restituisce i messaggi come dati strutturati nella risposta. |
filter |
No | all (predefinito), text, media o tool_use. |
cURL
curl "https://api.youraiconnector.com/v1/chat-exports/contact123?format=json" \
-H "X-API-Key: YOUR_API_KEY"
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/chat-exports/contact123",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"format": "json"},
)
print(res.json()["data"]["messages"])
Risposta con format=json (200 OK):
{
"success": true,
"data": {
"contact": {
"id": "contact123",
"name": "Jane Doe",
"phone": "+31612345678",
"email": "jane@example.com"
},
"messages": [
{
"body": "Hi! I have a question about my order.",
"direction": "inbound",
"timestamp": "2026-06-01T09:55:00.000Z",
"type": "text",
"media_url": null,
"media_content_type": null,
"name": null,
"args": null
}
]
}
}
Con format=txt (il predefinito), data è invece un link per il download del file di trascrizione generato:
{
"success": true,
"data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}
Il link per il download ha una durata limitata. Recupera il file non appena ricevi il link invece di memorizzarlo: richiedi una nuova esportazione quando hai di nuovo bisogno della trascrizione.
Esporta ogni conversazione recente
GET /chat-exports/recent
Esporta le conversazioni di tutti i contatti che sono stati attivi nelle ultime X ore, in un’unica chiamata.
| Parametro di query | Obbligatorio | Descrizione |
|---|---|---|
hours |
Sì | Quante ore di attività considerare a ritroso. Deve essere un numero intero positivo. |
format |
No | json (predefinito) restituisce una voce per contatto. txt restituisce un singolo file di testo scaricabile contenente ogni conversazione. |
limit |
No | Numero massimo di contatti da esportare. Predefinito 50, massimo 100. |
filter |
No | all (predefinito), text, media o tool_use. |
cURL
curl "https://api.youraiconnector.com/v1/chat-exports/recent?hours=24&limit=25" \
-H "X-API-Key: YOUR_API_KEY"
Risposta (200 OK):
{
"success": true,
"data": {
"hours_ago": 24,
"total_contacts": 2,
"exports": [
{
"contactId": "contact123",
"contactName": "Jane Doe",
"phoneNumber": "+31612345678",
"email": "jane@example.com",
"messageCount": 12,
"chatExport": "Acme Export - Jane Doe\nPhone: +31612345678\n..."
}
]
}
}
Con format=txt la risposta è il file di testo stesso, inviato come download anziché come JSON.
Questa singola chiamata estrae l’intera cronologia di ogni contatto corrispondente, quindi mantieni
hourselimitmoderati su account molto attivi.
Invia una trascrizione via email al contatto
POST /chat-exports/{contactId}/email
Invia al contatto la propria trascrizione della conversazione via email: il flusso “inviami questa chat via email”, gestito dal tuo sistema.
| Campo | Obbligatorio | Descrizione |
|---|---|---|
recipient_email |
No | Dove inviarla. Per impostazione predefinita utilizza l’indirizzo email salvato del contatto. |
via |
No | auto (predefinito) sceglie il percorso migliore, transactional la invia come email di sistema, email_channel la invia dal tuo canale email collegato. |
note |
No | Una breve riga da parte tua mostrata sopra la trascrizione. Fino a 1000 caratteri. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/chat-exports/contact123/email" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "note": "Here is a copy of our chat, as promised." }'
Risposta (200 OK):
{
"success": true,
"data": {
"via": "transactional",
"recipientEmail": "jane@example.com",
"messageCount": 42,
"omittedCount": 0
}
}
omittedCount ti indica quanti dei messaggi più vecchi sono stati esclusi per mantenere l’email di una lunghezza ragionevole. Un 200 significa che la trascrizione è stata creata e messa in coda per l’invio, non che sia già arrivata nella casella di posta.
Sospendere o riprendere l’IA per un singolo contatto
PUT /contacts/{contactId}
Imposta is_bot_active su false per impedire all’IA di rispondere a un contatto, e riportalo su true per restituire la conversazione. Questo è l’interruttore di controllo che ti serve quando un essere umano interviene in una conversazione: i messaggi in uscita inviati tramite API vengono comunque consegnati mentre il bot è in pausa.
cURL
curl -X PUT "https://api.youraiconnector.com/v1/contacts/contact123" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_bot_active": false }'
JavaScript
await fetch("https://api.youraiconnector.com/v1/contacts/contact123", {
method: "PUT",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ is_bot_active: false }),
});
Python
import requests
requests.put(
"https://api.youraiconnector.com/v1/contacts/contact123",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"is_bot_active": False},
)
Risposta
{
"success": true,
"contact_id": "contact123"
}
Sospensione durante la risposta
Se un umano sta prendendo il controllo inviando una risposta, puoi mettere in pausa il bot nella stessa richiesta invece di effettuare una seconda chiamata. POST /contacts/{contactId}/send-message accetta questi flag opzionali:
| Campo | Descrizione |
|---|---|
pauseBot |
true mette in pausa l’IA per questo contatto mentre il messaggio viene inviato. |
clearIncompleteReply |
true scarta una risposta del bot a metà, in modo che non riprenda successivamente. |
human_reply |
true contrassegna il messaggio come risposta di un collega e annulla una risposta che l’IA aveva messo in coda. Per la pausa è comunque necessario pauseBot. |
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Hi, Sarah here - taking over from the assistant.",
"pauseBot": true,
"clearIncompleteReply": true,
"human_reply": true
}'
La risposta include "botPaused": true quando la pausa è stata applicata.
Contrassegnare un contatto come privato con
POST /contacts/bulk-flagsospende anche il bot per quel contatto. Vedi Contatti per l’elenco completo dei campi.
Creare la propria casella di posta
Tutto ciò di cui una casella di posta ha bisogno si trova in questa pagina e in Contatti:
| Cosa ti serve | Endpoint |
|---|---|
| Elenca conversazioni | GET /contacts |
| Leggi una conversazione | GET /contacts/{contactId}/messages |
| Elenca le sessioni di chat di un contatto | GET /chat-sessions/{contactId} |
| Vedi cosa è arrivato di recente | GET /chat-sessions/recent |
| Leggi una sessione di chat | GET /contacts/{contactId}/chat-sessions/{sessionId}/messages |
| Invia una risposta manuale | POST /contacts/{contactId}/send-message |
| Correggi una risposta appena inviata | POST /contacts/{contactId}/messages/{messageId}/edit |
| Rimuovi un messaggio | DELETE /contacts/{contactId}/messages/{messageId} |
| Elimina diversi messaggi | POST /contacts/{contactId}/messages/bulk-delete |
| Reagisci con un’emoji | POST /contacts/{contactId}/messages/{messageId}/react |
| Valuta o aggiungi una stella a un messaggio | PATCH /contacts/{contactId}/messages/{messageId} |
| Segna come letto | POST /contacts/{contactId}/mark-read |
| Restituisci una chat al team | POST /contacts/{contactId}/mark-unread |
| Esporta una trascrizione | GET /chat-exports/{contactId} |
| Metti in pausa o riprendi l’IA | PUT /contacts/{contactId} con is_bot_active |
Per aggiornamenti in tempo reale, iscriviti agli eventi New Message, Replies, Human Alerted e Chat Concluded con i Webhook invece di interrogare questa API a intervalli regolari.
Errori dell’API Messaggi
Gli endpoint dei messaggi restituiscono il pacchetto di errore standard:
{
"success": false,
"error": "Contact not found"
}
| Stato | Quando si verifica su un endpoint di messaggio |
|---|---|
400 |
Manca un campo obbligatorio o un parametro non è valido (limit, hours, filter, direction, status errati, un array message_ids vuoto o superiore a 500, un cursor non valido, una modifica body vuota o troppo lunga, un score al di fuori di -1/0/1, o un’emoji con spazi o superiore a 16 caratteri). Restituito anche quando un messaggio non può essere modificato affatto: è stato eliminato, il suo canale non supporta le modifiche o è oltre la finestra di modifica di quel canale. |
404 |
Il contatto, la sessione di chat o uno degli ID messaggio forniti non è stato trovato. |
409 |
Il canale non accetta la modifica in questo momento. Non è stato scritto nulla: in caso di modifica, edit_reason spiega il perché; in caso di reazione, il canale era momentaneamente irraggiungibile e un nuovo tentativo potrebbe funzionare. |
422 |
Il contatto non può ricevere messaggi in uscita (non disturbare, privato o un canale non supportato), oppure una reazione non può mai essere consegnata in questa conversazione (reaction_reason indica quale). |
I codici condivisi che ogni endpoint può restituire — 401, 403 (il tuo piano non include l’accesso all’API), 429 (limite di frequenza) e 500 — sono elencati con indicazioni sui tentativi in Errori e Paginazione.
Passaggi successivi
- Webhooks — ricevi aggiornamenti sullo stato di consegna invece di eseguire il polling.
- Contatti — crea e cerca i contatti a cui invii messaggi.
- Appuntamenti — prenota e gestisci gli appuntamenti per i tuoi contatti.