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.
Invia tramite ID contatto
POST /contacts/{contactId}/send-message
| Campo | Obbligatorio | Descrizione |
|---|---|---|
body |
Sì | Il testo del messaggio da inviare. |
mediaUrl |
No | URL di un file multimediale (immagine, documento, ecc.) da allegare. |
mediaContentType |
No | Tipo MIME del file multimediale allegato, ad es. image/jpeg. |
pauseBot |
No | true sospende l’IA per questo contatto mentre il messaggio viene inviato — per un intervento umano. Vedi Sospendere o riprendere l’IA. |
clearIncompleteReply |
No | true scarta una risposta del bot a metà, in modo che non riprenda dopo il tuo messaggio. |
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. |
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 è fornito. 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.
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. |
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 corrente, 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 |
Data e ora ISO 8601 di creazione del messaggio. |
media_url |
URL di un file multimediale allegato, se presente. |
media_content_type |
Tipo MIME del file multimediale allegato, se presente. |
bot_reply |
true quando il messaggio è stato generato dall’assistente AI. |
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 i loro campi 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. |
Elenca sessioni di chat
Una sessione di chat è una finestra di conversazione con un contatto: si apre quando inizia a parlare e si chiude quando la conversazione è conclusa. Le sessioni sono il modo in cui puoi suddividere una lunga cronologia in conversazioni leggibili invece di un 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 di un messaggio inviato | Chat widget, WhatsApp Web, Telegram, LinkedIn | Nessuno sul chat widget, 15 minuti su WhatsApp Web, 48 ore su Telegram, 60 minuti su LinkedIn |
| Elimina per tutti | Chat widget, 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 può contenere al massimo 4096 caratteri. |
A differenza dell’eliminazione, questa operazione fallisce in modo esplicito quando il canale rifiuta: ricevi un 409 e la tua copia viene lasciata esattamente come quella del contatto, perché mostrare una modifica che non hanno mai ricevuto metterebbe le due parti fuori sincronia. Il campo edit_reason ti dice il perché — la finestra di modifica del canale è chiusa, il canale è disconnesso o qualcos’altro è andato storto.
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 essere umano sta intervenendo inviando una risposta, puoi sospendere il bot nella stessa richiesta invece di effettuare una seconda chiamata. POST /contacts/{contactId}/send-message accetta due flag opzionali:
| Campo | Descrizione |
|---|---|
pauseBot |
true sospende l’IA per questo contatto mentre il messaggio viene inviato. |
clearIncompleteReply |
true scarta una risposta del bot a metà, in modo che non riprenda in seguito. |
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
}'
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.