Vai al contenuto
OmniChannels.ai

Inviare SMS via API: esempi in Python, Node.js, PHP e cURL

Inviare SMS con una API in Python, Node.js, PHP e cURL: invii singoli e massivi, Unicode e arabo, conteggio dei segmenti, webhook di stato ed errori.

Aggiornato 10 min di lettura

Di OmniChannels.ai Editorial Team · Revisione di BroadNet Messaging Solutions Team

Integrazione

Risposta breve

Per inviare un SMS con l'API di OmniChannels.ai, eseguite una POST autenticata a https://api.broadnet.me/sms/sendSms con un corpo JSON contenente senderId, destinationNumber, message e messageType. Usate TEXT per il testo GSM-7 e UNICODE per arabo o emoji. Una risposta 200 restituisce l'ID del messaggio come testo semplice e lo stato finale di consegna arriva in seguito al vostro webhook.

In questa pagina
  1. Come si invia un SMS con l'API?
  2. Come formattare i numeri di telefono?
  3. Come inviare arabo, emoji o altro testo Unicode?
  4. Come contare i segmenti prima dell'invio?
  5. Come inviare a molti numeri?
  6. Come ricevere lo stato di consegna?
  7. Come gestire gli errori ed evitare i duplicati?
  8. Esempio pratico: codici di accesso per un'app regionale
  9. Quali sono gli errori comuni?
  10. Come vi aiuta OmniChannels.ai

Punti chiave

  • POST /sms/sendSms richiede quattro campi: senderId, destinationNumber, message e messageType; il corpo della risposta è l'ID del messaggio come testo semplice, non JSON.
  • Impostate messageType su UNICODE per arabo, emoji o qualsiasi carattere fuori dal GSM-7; un solo carattere di questo tipo rende Unicode l'intero messaggio e accorcia ogni segmento.
  • POST /sms/identify conta caratteri e segmenti prima dell'invio, così potete prevedere quanti segmenti usa un messaggio.
  • La consegna è asincrona: un 200 significa accettato e DELIVERED, FAILED o REJECTED arriva in seguito al vostro webhook.
  • L'API non ha una chiave di idempotenza, quindi registrate ogni invio prima di effettuarlo e dopo un timeout controllate lo stato invece di reinviare.

Questa guida è per gli sviluppatori che devono inviare SMS da un'applicazione e vogliono codice funzionante in Python, Node.js, PHP o cURL. Tratta l'invio singolo, Unicode e arabo, il conteggio dei segmenti, il caricamento massivo, i webhook di stato di consegna e la gestione degli errori, usando solo endpoint e campi del nostro riferimento dell'API SMS e della specifica OpenAPI.

Come si invia un SMS con l'API?

Eseguite una POST autenticata a /sms/sendSms con un corpo JSON. La risposta è 200 OK con l'ID del messaggio come testo semplice.

Elemento Valore
URL di base https://api.broadnet.me (senza prefisso /v1)
Endpoint POST /sms/sendSms
Autenticazione Authorization: Bearer $BROADNET_TOKEN
Content type application/json
Campi obbligatori senderId, destinationNumber, message, messageType

Le credenziali di test vengono rilasciate dopo una breve richiesta di accesso e gli invii di prova vanno ai vostri numeri verificati. Non esiste una registrazione self-service immediata. Vedi il quickstart.

curl -X POST https://api.broadnet.me/sms/sendSms \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "senderId": "OmniDemo",
    "destinationNumber": "447700900123",
    "message": "Your OmniDemo code is 482913",
    "messageType": "TEXT"
  }'
// Node.js 18+ (fetch integrato)
const res = await fetch("https://api.broadnet.me/sms/sendSms", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BROADNET_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    senderId: "OmniDemo",
    destinationNumber: "447700900123",
    message: "Your OmniDemo code is 482913",
    messageType: "TEXT",
  }),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const messageId = await res.text(); // ID del messaggio come testo semplice
import os
import requests

r = requests.post(
    "https://api.broadnet.me/sms/sendSms",
    headers={"Authorization": f"Bearer {os.environ['BROADNET_TOKEN']}"},
    json={
        "senderId": "OmniDemo",
        "destinationNumber": "447700900123",
        "message": "Your OmniDemo code is 482913",
        "messageType": "TEXT",
    },
    timeout=15,
)
r.raise_for_status()
message_id = r.text  # ID del messaggio come testo semplice, non JSON
<?php
$payload = json_encode([
    "senderId" => "OmniDemo",
    "destinationNumber" => "447700900123",
    "message" => "Your OmniDemo code is 482913",
    "messageType" => "TEXT",
]);

$ch = curl_init("https://api.broadnet.me/sms/sendSms");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 15,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("BROADNET_TOKEN"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => $payload,
]);
$messageId = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
echo $status . " " . $messageId . PHP_EOL;

Il corpo di una risposta riuscita si presenta così:

2603121407537573731

Salvate quell'ID insieme al vostro record, ad esempio un ordine o un tentativo di accesso. È ciò che vi permette di associare in seguito gli stati di consegna.

Come formattare i numeri di telefono?

Usate prefisso internazionale più numero nazionale, solo cifre. Il formato segue il piano di numerazione internazionale ITU-T E.164, senza il segno più.

Input Valido? Motivo
447700900123 Sì Prefisso 44 più numero nazionale
+44 7700 900123 No Togliete il segno più e gli spazi
07700900123 No Sostituite lo 0 iniziale con il prefisso internazionale

Memorizzate i numeri in formato E.164 (+447700900123) nel database e togliete il + quando costruite la richiesta. Il nostro formattatore gratuito di numeri di telefono aiuta per un controllo rapido.

Come inviare arabo, emoji o altro testo Unicode?

Impostate messageType su UNICODE. Qualsiasi carattere fuori dall'alfabeto GSM-7, come una lettera araba, un'emoji, virgolette tipografiche o un trattino lungo, porta l'intero messaggio in Unicode.

r = requests.post(
    "https://api.broadnet.me/sms/sendSms",
    headers={"Authorization": f"Bearer {os.environ['BROADNET_TOKEN']}"},
    json={
        "senderId": "OmniDemo",
        "destinationNumber": "971500000000",
        "message": "رمز التحقق الخاص بك هو 482913",
        "messageType": "UNICODE",
        "campaignName": "login-otp",
    },
    timeout=15,
)

In PHP usate JSON_UNESCAPED_UNICODE quando chiamate json_encode. La codifica determina la dimensione del segmento, come definito per gli SMS dal 3GPP TS 23.040:

messageType SMS singolo Per segmento se diviso Da usare per
TEXT 160 caratteri 153 caratteri Testo che usa solo l'alfabeto GSM-7
UNICODE 70 caratteri 67 caratteri Arabo, cirillico, cinese, emoji

La maggior parte degli operatori fattura per segmento, quindi un lungo messaggio in arabo costa più dello stesso messaggio in scrittura latina. Leggete la nostra guida agli SMS Unicode e in arabo e provate il contatore di caratteri SMS.

Come contare i segmenti prima dell'invio?

Chiamate POST /sms/identify con il messaggio. Restituisce la codifica rilevata, il numero di caratteri, il numero di segmenti e il limite per segmento.

curl -X POST https://api.broadnet.me/sms/identify \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Your OmniDemo code is 482913" }'
{
  "message": "Your OmniDemo code is 482913",
  "messageType": "TEXT",
  "smscount": 1,
  "charCount": 28,
  "charLimit": 160
}

Potete passare smsParts (da smscount), charCount e charLimit in una richiesta di invio. Il testo GSM-7 può essere indicato come GSM-7 nella risposta; inviatelo come TEXT.

Come inviare a molti numeri?

Usate POST /sms/sendbulk, una richiesta multipart/form-data con un file di destinatari e una stringa JSON di impostazioni.

curl -X POST https://api.broadnet.me/sms/sendbulk \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -F destinationNumberFile=@recipients.csv \
  -F 'bulkRequest={"senderId":"OmniDemo","message":"Your statement is ready in the app.","messageType":"TEXT","campaignName":"oct-statements","allowDuplicate":false}'
import json
import os
import requests

bulk_request = {
    "senderId": "OmniDemo",
    "message": "Your statement is ready in the app.",
    "messageType": "TEXT",
    "campaignName": "oct-statements",
    "allowDuplicate": False,
}

with open("recipients.csv", "rb") as f:
    r = requests.post(
        "https://api.broadnet.me/sms/sendbulk",
        headers={"Authorization": f"Bearer {os.environ['BROADNET_TOKEN']}"},
        files={"destinationNumberFile": ("recipients.csv", f, "text/csv")},
        data={"bulkRequest": json.dumps(bulk_request)},
        timeout=60,
    )
print(r.json())

La risposta include bulkSessionId e un oggetto bulkListInfo con total, validCount, invalidCount e duplicate. Memorizzate bulkSessionId con la campagna. I job possono essere elencati, messi in pausa, ripresi e interrotti con gli endpoint del riferimento. Potete anche controllare i numeri prima di un grande invio con POST /sms/lookup; vedi la nostra guida alla HLR lookup.

Come ricevere lo stato di consegna?

Gli stati di consegna vengono inviati all'URL del webhook configurato sul vostro account. Un messaggio passa da SUBMITTED e SENT a DELIVERED, oppure termina come FAILED o REJECTED. Fornite al nostro team l'URL HTTPS pubblico; i reseller possono avere un webhook per ogni sotto-account.

I campi del payload variano per canale e la specifica dell'API non definisce un unico schema di webhook, quindi registrate prima il corpo grezzo e mappate i campi da un evento reale sul vostro account. Un ricevitore minimo salva l'evento e conferma rapidamente:

import express from "express";

const app = express();

app.post("/webhooks/omnichannels", express.json(), async (req, res) => {
  await saveStatusEvent(req.body); // il vostro storage; elaborate in modo asincrono
  res.sendStatus(200);             // confermate subito
});

app.listen(3000);

Rendete l'elaborazione idempotente, perché lo stesso stato può arrivare due volte, e non lasciate mai che un SENT in ritardo sovrascriva un DELIVERED già memorizzato. Se il vostro endpoint era fuori servizio, POST /sms/resendDlr reinvia i rapporti per un intervallo di date:

curl -X POST https://api.broadnet.me/sms/resendDlr \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startDate": "2026-10-09",
    "endDate": "2026-10-10",
    "senderId": "OmniDemo",
    "messageStatus": "DELIVERED"
  }'

Approfondite nella guida ai webhook e negli stati di consegna dei messaggi spiegati.

Come gestire gli errori ed evitare i duplicati?

Gestite prima lo stato HTTP, poi il corpo dell'errore. Riprovate solo in caso di errori di rete, 429 e 5xx.

Codice Significato Azione
200 Accettato Memorizzate l'ID
400 Errore di validazione o campo mancante Correggete la richiesta
401 / 403 Token errato o operazione non consentita Correggete; non riprovate
429 Limite di richieste superato Attendete Retry-After
500, 503, 504 Problemi del server o a monte Riprovate con backoff e jitter

Gli errori generati dall'API usano un corpo JSON a cinque campi con status, error, message, errorCode e requestUri. Il limite REST documentato per impostazione predefinita è di 200 richieste al secondo sostenute; i limiti del vostro account vengono confermati insieme alle credenziali.

L'API non accetta una chiave di idempotenza. Una richiesta può riuscire mentre la risposta va persa, e un nuovo tentativo alla cieca invia due volte. Scrivete una riga in sospeso, con chiave un vostro ID di operazione, prima della chiamata, memorizzate l'ID del messaggio restituito e dopo un timeout controllate se c'è uno stato dal webhook prima di inviare di nuovo. Per gli invii massivi impostate allowDuplicate su false. I dettagli sono in Errori e limiti.

Esempio pratico: codici di accesso per un'app regionale

«Souq Rafiq» (nome di fantasia), un rivenditore degli Emirati, invia codici di accesso via SMS.

  1. Il servizio di autenticazione genera un codice di sei cifre, memorizza un hash con scadenza di cinque minuti e scrive una riga di invio pending.
  2. Chiama /sms/sendSms con messageType=UNICODE per gli utenti arabi e TEXT per quelli inglesi.
  3. Con 200 memorizza l'ID del messaggio.
  4. Il gestore del webhook segna la riga come DELIVERED, FAILED o REJECTED.
  5. Se dopo una breve attesa lo stato non è DELIVERED, l'app propone un nuovo invio e, se configurato, un altro canale. Vedi il fallback tra canali.
  6. Limiti sulle richieste di codice per numero e per IP proteggono dagli abusi; vedi la prevenzione dell'SMS pumping.

Quali sono gli errori comuni?

  • Chiamare r.json() sulla risposta di invio. È testo semplice.
  • Nomi di campo sbagliati. Usate senderId, destinationNumber e message; campi come to, from o text non fanno parte di questo endpoint.
  • Segni più e zeri iniziali nei numeri.
  • Dimenticare UNICODE per l'arabo, che altera il testo.
  • Sender ID non registrati. Alcuni paesi li bloccano o li sostituiscono; verificate le regole sui Sender ID della destinazione e chiedeteci di occuparci della registrazione.
  • Considerare 200 come consegnato.
  • Token in un'app mobile o nel browser, dove chiunque può estrarlo.
  • Limiti: questa guida mostra la richiesta più comune. Campi facoltativi come i formati di programmazione dell'invio vanno confermati con il nostro team.

Come vi aiuta OmniChannels.ai

OmniChannels.ai invia SMS A2P tramite la connettività diretta agli operatori di BroadNet, con SMS bidirezionali, Sender ID, Unicode e arabo, HLR lookup e SMPP 3.4 per i volumi elevati. L'API REST su https://api.broadnet.me usa un Bearer token e copre anche WhatsApp, RCS e altri canali, con gli stati di consegna normalizzati in un unico formato di webhook. Il nostro team prepara con voi le registrazioni dei Sender ID. Consultate il riferimento dell'API SMS o il canale SMS.

Domande frequenti

Come si invia un SMS con Python?

Usate la libreria requests per eseguire una POST JSON a https://api.broadnet.me/sms/sendSms con un header Authorization: Bearer e i campi senderId, destinationNumber, message e messageType. Leggete il token da una variabile d'ambiente. Il corpo della risposta 200 è l'ID del messaggio come testo semplice, quindi usate r.text anziché r.json().

Quale formato di numero di telefono si aspetta l'API SMS?

Prefisso internazionale più numero nazionale, solo cifre, senza segno più, prefisso 00, spazi o zero iniziale. Ad esempio 447700900123 è valido, mentre +44 7700 900123 e 07700900123 no. Memorizzate i numeri in formato E.164 nel vostro database e togliete il segno più quando costruite la richiesta.

Come si inviano SMS in arabo tramite l'API?

Impostate messageType su UNICODE e inviate il testo arabo nel campo message in UTF-8. I messaggi Unicode contengono 70 caratteri in un singolo segmento e 67 per segmento se divisi, contro 160 e 153 del GSM-7. Testate su telefoni reali e chiamate prima /sms/identify per vedere il numero di segmenti.

Come si ottengono i rapporti di consegna?

Gli stati vengono inviati all'URL del webhook configurato sul vostro account. I messaggi passano da SUBMITTED e SENT a DELIVERED, FAILED o REJECTED. Il vostro endpoint dovrebbe salvare l'evento grezzo, rispondere rapidamente con 2xx ed elaborare in modo asincrono. Se alcuni eventi sono andati persi, POST /sms/resendDlr può reinviare i rapporti di consegna per un intervallo di date.

Come si inviano SMS a molti numeri in una volta?

Usate POST /sms/sendbulk, una richiesta multipart con un destinationNumberFile (CSV o TXT) e una stringa JSON bulkRequest con senderId, message e messageType. La risposta indica quanti numeri sono validi, non validi o duplicati e restituisce un bulkSessionId che potete memorizzare con la campagna.

Devo registrare un Sender ID?

In molti paesi sì. Alcuni richiedono un Sender ID alfanumerico approvato, altri identificativi dell'ente regolatore o dei template, che l'API accetta in campi facoltativi come peId e templateId. I requisiti dipendono dal paese, quindi consultate la pagina sul Sender ID della vostra destinazione; il nostro team può occuparsi della registrazione con voi.

Fonti

  1. 3GPP TS 23.040: Technical realization of the Short Message Service (SMS)
  2. ITU-T E.164: The international public telecommunication numbering plan
  3. RFC 9110: HTTP Semantics