---
title: "Inviare SMS via API: esempi in Python, Node.js, PHP e cURL"
description: "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."
canonical: "https://omnichannels.ai/it/blog/send-sms-api-examples/"
language: "it"
updated: "2026-10-16"
publisher: "BroadNet Technologies"
brand: "OmniChannels.ai"
category: "integration"
primaryQuery: "send sms api python"
keywords: ["inviare sms python", "api sms node.js esempio", "api sms php", "api sms curl", "api sms unicode arabo", "webhook rapporto di consegna sms", "esempio api sms massivi"]
published: "2026-10-16"
author: "OmniChannels.ai Editorial Team"
reviewer: "BroadNet Messaging Solutions Team"
readingMinutes: 10
answer: "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."
takeaways: ["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."]
faq: 
  - q: "Come si invia un SMS con Python?"
    a: "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()."
  - q: "Quale formato di numero di telefono si aspetta l'API SMS?"
    a: "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."
  - q: "Come si inviano SMS in arabo tramite l'API?"
    a: "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."
  - q: "Come si ottengono i rapporti di consegna?"
    a: "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."
  - q: "Come si inviano SMS a molti numeri in una volta?"
    a: "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."
  - q: "Devo registrare un Sender ID?"
    a: "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."
sources: 
  - title: "3GPP TS 23.040: Technical realization of the Short Message Service (SMS)"
    url: "https://www.3gpp.org/dynareport?code=23040"
  - title: "ITU-T E.164: The international public telecommunication numbering plan"
    url: "https://www.itu.int/rec/T-REC-E.164"
  - title: "RFC 9110: HTTP Semantics"
    url: "https://www.rfc-editor.org/rfc/rfc9110"
---

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

Canonical: https://omnichannels.ai/it/blog/send-sms-api-examples/
Language: it
Publisher: OmniChannels.ai by BroadNet Technologies

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](/developers/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](/developers/quickstart/).

```bash
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"
  }'
```

```js
// 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
```

```python
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
<?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ì:

```text
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.

```python
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](/it/blog/sms-character-limits-unicode-arabic/) 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.

```bash
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" }'
```

```json
{
  "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.

```bash
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}'
```

```python
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](/it/blog/hlr-lookup-number-validation/).

## 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:

```js
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:

```bash
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](/developers/webhooks/) 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](/developers/errors-and-limits/).

## 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](/it/blog/sms-pumping-fraud-prevention/).

## 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](/developers/sms/) o il canale SMS.
