RCS API
Cos'è RCS
RCS (Rich Communication Services) è l'evoluzione degli SMS tradizionali. Consente di inviare messaggi ricchi con immagini, video, bottoni interattivi, card e caroselli direttamente nell'app di messaggistica nativa del telefono, senza che il destinatario debba installare applicazioni aggiuntive.
A differenza degli SMS, i messaggi RCS supportano:
- Contenuti multimediali (immagini, video, GIF)
- Bottoni interattivi (rispondi, apri URL, chiama, posizione, calendario)
- Card con titolo, descrizione e media
- Caroselli di card scorrevoli
- Conferme di lettura e indicatori di digitazione
- Fallback automatico su WhatsApp e/o SMS se il destinatario non supporta RCS
:::info Fallback automatico Se il destinatario non supporta RCS, il messaggio viene inviato automaticamente tramite WhatsApp e/o SMS (se configurato). Questo garantisce che il messaggio raggiunga sempre il destinatario, indipendentemente dal suo dispositivo. :::
Endpoint
POST https://lora-api.agiletelecom.com/api/message-server/rcs/send
Content-Type: application/json
Autenticazione: API Key (X-Api-Key) oppure Basic Auth (Authorization: Basic)
Campi della richiesta
| Campo | Tipo | Obbligatorio | Default | Descrizione |
|---|---|---|---|---|
destination | string | Sì | – | Numero di telefono destinatario in formato internazionale (es. +393401234567) |
agentId | integer | Sì | – | ID dell'agente RCS mittente associato al tuo account |
body | object | Sì* | – | Contenuto del messaggio RCS. *Mutuamente esclusivo con templateId |
templateId | integer | Sì* | – | ID di un template RCS preconfigurato. *Mutuamente esclusivo con body |
campaignId | string | No | – | Identificativo della campagna per raggruppare più messaggi. Massimo 255 caratteri |
messageId | string | No | (auto) | Identificativo personalizzato del messaggio. Se non fornito, viene generato automaticamente (UUID) |
simulation | boolean | No | false | Se true, il messaggio viene elaborato ma non inviato fisicamente. Utile per test |
enableNotification | boolean | No | true | Se true, abilita le notifiche di consegna e lettura verso il tuo URL di callback |
maxSmsParts | integer | No | – | Numero massimo di parti SMS consentite per il messaggio di fallback. Se il testo di fallback supera questo limite, il messaggio non viene inviato via SMS |
placeholders | object | No | – | Mappa chiave-valore per sostituire i placeholder nel testo. Es: {"nome": "Mario"} sostituisce {nome} nel messaggio |
scheduledDate | string | No | – | Data e ora di invio programmato. Formato: yyyy-MM-dd HH:mm:ss.SSSZ (es. 2025-10-01 09:00:00.000+0000) |
Tipi di body
Il campo body deve contenere un campo type che specifica il formato del messaggio e i relativi sotto-campi.
TEXT
Messaggio di testo semplice, opzionalmente con suggerimenti interattivi.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | Deve essere "TEXT" |
text | string | Sì | Testo del messaggio |
suggestions | array | No | Lista di suggerimenti interattivi (vedi sezione Suggestions) |
CARD
:::tip Best practice per Rich Card
Includi sempre un mediaUrl con un'immagine di alta qualità e un title chiaro. Aggiungi almeno un suggerimento interattivo (bottone) per massimizzare il coinvolgimento dell'utente.
:::
Messaggio con un singolo elemento visivo contenente media, titolo, descrizione e suggerimenti.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | Deve essere "CARD" |
title | string | No | Titolo della card |
description | string | No | Descrizione della card |
mediaUrl | string | No | URL pubblico dell'immagine o del video da visualizzare nella card |
mediaHeight | string | No | Altezza del media: SHORT, MEDIUM, TALL. Default: MEDIUM |
suggestions | array | No | Lista di suggerimenti interattivi |
CAROUSEL
Messaggio con più card scorrevoli orizzontalmente. Ogni card può avere il proprio titolo, descrizione, media e suggerimenti.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | Deve essere "CAROUSEL" |
cards | array | Sì | Lista di card (minimo 2, massimo 10). Ogni card ha gli stessi campi del tipo CARD (title, description, mediaUrl, mediaHeight, suggestions) |
Suggestions (suggerimenti interattivi)
I suggerimenti sono bottoni interattivi che appaiono sotto il messaggio. Ogni suggerimento ha un type e campi specifici.
reply
Risposta rapida con testo predefinito. Quando l'utente clicca, il sistema riceve il postbackData.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | "reply" |
text | string | Sì | Testo visualizzato sul bottone |
postbackData | string | Sì | Dato inviato al tuo callback quando l'utente clicca |
url
Apre un URL nel browser del dispositivo.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | "url" |
text | string | Sì | Testo visualizzato sul bottone |
url | string | Sì | URL da aprire |
dial
Avvia una chiamata telefonica al numero indicato.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | "dial" |
text | string | Sì | Testo visualizzato sul bottone |
phoneNumber | string | Sì | Numero di telefono da chiamare (formato internazionale) |
locationCoordinates
Apre la mappa con un segnaposto alle coordinate specificate.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | "locationCoordinates" |
text | string | Sì | Testo visualizzato sul bottone |
latitude | string | Sì | Latitudine (es. "45.4642") |
longitude | string | Sì | Longitudine (es. "9.1900") |
label | string | No | Etichetta del segnaposto sulla mappa |
locationQuery
Apre la mappa con una ricerca testuale dell'indirizzo.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | "locationQuery" |
text | string | Sì | Testo visualizzato sul bottone |
query | string | Sì | Indirizzo o luogo da cercare (es. "Via Roma 1, Milano") |
calendar
Crea un evento nel calendario del dispositivo.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
type | string | Sì | "calendar" |
text | string | Sì | Testo visualizzato sul bottone |
title | string | Sì | Titolo dell'evento |
description | string | No | Descrizione dell'evento |
startTime | string | Sì | Data e ora di inizio in formato ISO 8601 (es. "2025-10-15T14:00:00Z") |
endTime | string | Sì | Data e ora di fine in formato ISO 8601 |
Fallback
RCS supporta il fallback automatico su altri canali quando il destinatario non supporta RCS o il messaggio non può essere consegnato.
fallbackWhatsApp
Se RCS fallisce, il sistema prova a inviare il messaggio tramite WhatsApp.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
phoneNumberId | integer | Sì | ID del numero WhatsApp Business mittente |
templateId | integer | Sì* | ID template WhatsApp. *Mutuamente esclusivo con body |
body | object | Sì* | Body WhatsApp inline. *Mutuamente esclusivo con templateId |
fallbackSms
Se RCS (e l'eventuale fallback WhatsApp) fallisce, il sistema invia un SMS.
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
sender | string | Sì | Mittente dell'SMS (alfanumerico o numerico) |
text | string | Sì | Testo dell'SMS di fallback |
Regola: Se
fallbackWhatsAppè presente,fallbackSmsè obbligatorio.
Risposta
{
"messageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"simulation": false,
"results": {
"rcs": {
"accepted": true,
"reasons": []
},
"sms": null
}
}
| Campo | Tipo | Descrizione |
|---|---|---|
messageId | string | ID univoco del messaggio |
simulation | boolean | true se il messaggio era in modalità simulazione |
results.rcs.accepted | boolean | true se il messaggio RCS è stato accettato |
results.rcs.reasons | array | Lista di motivi in caso di rifiuto |
results.sms | object/null | Risultato fallback SMS (se configurato, altrimenti null) |
Importante:
accepted: truesignifica che il messaggio è stato accettato per l'invio, non che è stato consegnato. La conferma di consegna arriva tramite callback.
Notifiche (Callback)
Delivery Notification
Notifica di consegna del messaggio:
{
"channel": "RCS",
"eventType": "DELIVERY",
"messageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"destination": "+393401234567",
"statusCode": 3,
"description": "delivered",
"eventDate": "2025-10-16T10:42:18Z"
}
| statusCode | Significato |
|---|---|
3 | Messaggio consegnato |
6 | Messaggio non consegnabile |
Read Notification
Notifica di lettura (il destinatario ha aperto il messaggio):
{
"channel": "RCS",
"eventType": "READ",
"messageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"destination": "+393401234567",
"eventDate": "2025-10-16T10:43:05Z"
}
Inbound Message
Notifica di messaggio in ingresso (il destinatario ha risposto o cliccato un suggerimento):
{
"channel": "RCS",
"eventType": "INBOUND",
"messageId": "rcs-inbound-id-12345",
"source": "+393401234567",
"destination": "+393209998877",
"receivedDate": "2025-10-16T10:45:00Z",
"messageType": "TEXT",
"text": "Messaggio di risposta dell'utente"
}
Per i messaggi con media, il campo mediaKey contiene la chiave per scaricare il file.
Download file media
Quando ricevi un messaggio in ingresso con media, puoi scaricare il file tramite:
GET https://lora-api.agiletelecom.com/api/files/{mediaKey}?expireMinutes=180
La risposta contiene un campo url con un URL temporaneo (pre-firmato) per il download diretto del file.
Esempi
1. Messaggio TEXT con suggerimenti
Invio di un messaggio di testo con bottoni di risposta rapida e apertura URL:
{
"destination": "+393401234567",
"agentId": 1,
"body": {
"type": "TEXT",
"text": "Ciao Mario! La tua prenotazione per il 15 ottobre è confermata. Vuoi modificarla?",
"suggestions": [
{
"type": "reply",
"text": "Conferma",
"postbackData": "CONFIRM_BOOKING_123"
},
{
"type": "reply",
"text": "Modifica",
"postbackData": "MODIFY_BOOKING_123"
},
{
"type": "url",
"text": "Vedi dettagli",
"url": "https://example.com/booking/123"
},
{
"type": "dial",
"text": "Chiamaci",
"phoneNumber": "+390212345678"
}
]
},
"enableNotification": true
}
2. Messaggio CARD con immagine
Invio di una card con immagine, titolo, descrizione e suggerimenti:
{
"destination": "+393401234567",
"agentId": 1,
"body": {
"type": "CARD",
"title": "Offerta Speciale",
"description": "Sconto del 30% su tutta la collezione primavera-estate. Valido fino al 31 marzo.",
"mediaUrl": "https://example.com/images/promo-spring.jpg",
"mediaHeight": "MEDIUM",
"suggestions": [
{
"type": "url",
"text": "Scopri l'offerta",
"url": "https://example.com/promo"
},
{
"type": "calendar",
"text": "Ricordamelo",
"title": "Fine promozione primavera",
"description": "Ultimo giorno per lo sconto del 30%",
"startTime": "2025-03-31T09:00:00Z",
"endTime": "2025-03-31T23:59:00Z"
}
]
},
"campaignId": "promo-primavera-2025"
}
3. Invio con templateId
Invio di un messaggio utilizzando un template RCS preconfigurato con placeholder:
{
"destination": "+393401234567",
"agentId": 1,
"templateId": 42,
"placeholders": {
"nome": "Mario",
"codiceOrdine": "ORD-2025-789",
"dataConsegna": "18 ottobre 2025"
},
"enableNotification": true
}
Codici di errore
| Codice HTTP | Significato | Cosa fare |
|---|---|---|
200 | Richiesta elaborata | Controlla results.rcs.accepted per verificare l'accettazione |
400 | Richiesta non valida | Verifica i campi obbligatori (destination, agentId, body o templateId) |
401 | Non autenticato | Verifica la tua API Key o le credenziali Basic Auth |
403 | Accesso negato | IP non in whitelist o risorsa non autorizzata |
404 | Non trovato | Template o agente non esistente |
422 | Entità non processabile | Dati sintatticamente corretti ma semanticamente non validi |
429 | Troppe richieste | Hai superato il rate limit. Riprova dopo il periodo indicato |
500 | Errore interno del server | Riprova più tardi. Se il problema persiste, contatta il supporto |