Passa al contenuto principale

SMS Universal API

Cos'è SMS Universal

SMS Universal è il formato moderno e consigliato per l'invio di messaggi SMS tramite la piattaforma Qlara. Ogni richiesta HTTP corrisponde a un singolo messaggio verso un singolo destinatario, rendendo l'integrazione semplice e immediata.

Rispetto al formato Legacy, SMS Universal offre supporto nativo per placeholder, notifiche di consegna, modalità simulazione e programmazione dell'invio.


Endpoint

POST https://lora-api.agiletelecom.com/api/message-server/sms/send

Content-Type: application/json

Autenticazione: API Key (X-Api-Key) oppure Basic Auth (Authorization: Basic)


Campi della richiesta

CampoTipoObbligatorioDefaultDescrizione
destinationstringNumero di telefono destinatario in formato internazionale (es. +393401234567)
senderstringMittente del messaggio. Può essere alfanumerico (max 11 caratteri, es. MyBrand) o numerico (es. +393401234567)
bodystringTesto del messaggio SMS. La lunghezza massima dipende dalla codifica (vedi sezione Codifica testo)
campaignIdstringNoIdentificativo della campagna per raggruppare più messaggi. Massimo 255 caratteri
messageIdstringNo(auto)Identificativo personalizzato del messaggio per tracciamento. Se non fornito, viene generato automaticamente (UUID)
udhDatastringNoUser Data Header in formato esadecimale. Usato per messaggi binari o concatenazione manuale. Nella maggior parte dei casi non è necessario
simulationbooleanNofalseSe true, il messaggio viene elaborato e validato ma non inviato fisicamente. Utile per test e debug
enableNotificationbooleanNotrueSe true, abilita le notifiche di consegna (delivery notification) verso il tuo URL di callback
placeholdersobjectNoMappa chiave-valore per sostituire i placeholder nel testo. Es: {"nome": "Mario"} sostituisce {nome} nel campo body
scheduledDatestringNoData e ora di invio programmato. Formato: yyyy-MM-dd HH:mm:ss.SSSZ (es. 2025-10-01 09:00:00.000+0000)
skipRcsOverridebooleanNofalseSe true, l'SMS viene inviato direttamente senza passare per un eventuale override RCS configurato a livello di account

Risposta

Tutte le chiamate di invio restituiscono una risposta con questa struttura:

Risposta
{
"messageId": "e76614d1-4ac1-4d94-89f0-d07f1b5a190c",
"simulation": false,
"results": {
"sms": {
"accepted": true,
"unicode": false,
"parts": 1,
"reasons": []
}
}
}
CampoTipoDescrizione
messageIdstringID univoco del messaggio. Usalo per correlare le notifiche di consegna
simulationbooleantrue se il messaggio era in modalità simulazione
results.sms.acceptedbooleantrue se il messaggio è stato accettato per l'invio
results.sms.unicodebooleantrue se il messaggio contiene caratteri Unicode (codifica UTF-16)
results.sms.partsintegerNumero di parti SMS in cui il messaggio è stato suddiviso
results.sms.reasonsarrayLista di motivi in caso di rifiuto (vuota se accettato)

Importante: accepted: true significa che il messaggio è stato accettato per l'invio, non che è stato consegnato. La conferma di consegna arriva tramite il callback Delivery Notification.


Codifica del testo

GSM-7 (standard)

:::tip Risparmio sui costi Usa la codifica GSM-7 quando possibile: supporta fino a 160 caratteri per messaggio singolo, contro i 70 dell'Unicode. Evita emoji e caratteri non latini per mantenere i costi al minimo. :::

La codifica predefinita per gli SMS. Supporta lettere latine, numeri, simboli comuni e alcuni caratteri speciali.

  • Messaggio singolo: fino a 160 caratteri
  • Messaggio concatenato: ogni parte contiene 153 caratteri (7 caratteri riservati all'header di concatenazione)

Unicode / UTF-16

Utilizzata automaticamente quando il testo contiene caratteri non supportati da GSM-7 (es. emoji, caratteri cinesi, arabi, cirillici).

  • Messaggio singolo: fino a 70 caratteri
  • Messaggio concatenato: ogni parte contiene 67 caratteri (3 caratteri riservati all'header di concatenazione)

Regole di concatenazione

:::warning Limiti di caratteri e costi Un singolo SMS supporta 160 caratteri GSM-7 o 70 caratteri Unicode. Il superamento di questi limiti causa la suddivisione del messaggio in più parti, e ogni parte viene tariffata separatamente. :::

Quando il testo supera la lunghezza massima di una singola parte, il messaggio viene automaticamente suddiviso in più parti (concatenazione). Il dispositivo del destinatario ricompone le parti in un unico messaggio.

Codifica1 parte2 parti3 partiN parti
GSM-7160 car.306 car.459 car.N x 153 car.
Unicode70 car.134 car.201 car.N x 67 car.

Nota: Ogni parte SMS viene tariffata singolarmente. Il campo results.sms.parts nella risposta indica il numero di parti.


Notifiche di consegna (Delivery Notification)

Se enableNotification è true, il sistema invia una callback HTTP POST al tuo URL quando lo stato del messaggio cambia.

Formato della callback

Callback Delivery Notification
{
"channel": "SMS",
"eventType": "DELIVERY",
"messageId": "e76614d1-4ac1-4d94-89f0-d07f1b5a190c",
"destination": "+393401234567",
"statusCode": 3,
"description": "delivered",
"price": 0.035,
"numPart": 1,
"totalParts": 1,
"eventDate": "2025-10-16T10:42:18Z"
}
CampoTipoDescrizione
channelstringSempre "SMS" per questo canale
eventTypestringSempre "DELIVERY"
messageIdstringID del messaggio (lo stesso restituito nella risposta di invio)
destinationstringNumero destinatario
statusCodeintegerCodice di stato: 3 = consegnato, 6 = non consegnabile
descriptionstringDescrizione testuale dello stato
pricenumberCosto della singola parte SMS
numPartintegerNumero della parte corrente (es. 1, 2, 3...)
totalPartsintegerNumero totale di parti del messaggio
eventDatestringData e ora dell'evento in formato ISO 8601

Codici di stato

statusCodeSignificato
3Messaggio consegnato al dispositivo del destinatario
6Messaggio non consegnabile (numero inesistente, telefono spento, ecc.)

Esempi

1. Invio semplice

Invio base di un messaggio SMS:

curl -X POST "https://lora-api.agiletelecom.com/api/message-server/sms/send" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination": "+393401234567",
"sender": "MyBrand",
"body": "Ciao! Il tuo ordine #12345 è stato spedito."
}'

Risposta:

{
"messageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"simulation": false,
"results": {
"sms": {
"accepted": true,
"unicode": false,
"parts": 1,
"reasons": []
}
}
}

2. Invio con placeholder

I placeholder nel campo body vengono sostituiti con i valori della mappa placeholders:

curl -X POST "https://lora-api.agiletelecom.com/api/message-server/sms/send" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination": "+393401234567",
"sender": "MyBrand",
"body": "Ciao {nome}, il tuo appuntamento è confermato per il {data} alle {ora}.",
"placeholders": {
"nome": "Mario",
"data": "15/03/2025",
"ora": "14:30"
},
"enableNotification": true
}'

Il destinatario riceverà: "Ciao Mario, il tuo appuntamento è confermato per il 15/03/2025 alle 14:30."

3. Invio programmato

Programma l'invio del messaggio a una data e ora futura:

curl -X POST "https://lora-api.agiletelecom.com/api/message-server/sms/send" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination": "+393401234567",
"sender": "MyBrand",
"body": "Promemoria: la tua prenotazione è domani alle 10:00.",
"scheduledDate": "2025-10-01 09:00:00.000+0000",
"campaignId": "reminder-ottobre-2025"
}'

4. Modalità simulazione

Il messaggio viene validato ma non inviato. Utile per verificare la correttezza della richiesta prima dell'invio reale:

curl -X POST "https://lora-api.agiletelecom.com/api/message-server/sms/send" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination": "+393401234567",
"sender": "MyBrand",
"body": "Questo è un messaggio di test con emoji 🎉",
"simulation": true
}'

Risposta:

{
"messageId": "f1e2d3c4-b5a6-7890-abcd-ef0987654321",
"simulation": true,
"results": {
"sms": {
"accepted": true,
"unicode": true,
"parts": 1,
"reasons": []
}
}
}

Nota: La risposta indica unicode: true perché il messaggio contiene un'emoji.


Codici di errore

Codice HTTPSignificatoCosa fare
200Richiesta elaborataControlla results.sms.accepted per verificare l'accettazione
400Richiesta non validaVerifica i campi obbligatori (destination, sender, body) e il formato dei dati
401Non autenticatoVerifica la tua API Key o le credenziali Basic Auth
403Accesso negatoIP non in whitelist o risorsa non autorizzata
404Non trovatoEndpoint non corretto
422Entità non processabileI dati sono sintatticamente corretti ma semanticamente non validi (es. numero destinatario non valido)
429Troppe richiesteHai superato il rate limit. Riprova dopo il periodo indicato nell'header Retry-After
500Errore interno del serverRiprova più tardi. Se il problema persiste, contatta il supporto