Ir para o conteúdo
OmniChannels.ai

Enviar SMS por API: exemplos em Python, Node.js, PHP e cURL

Envie SMS por API em Python, Node.js, PHP e cURL: envio único e em massa, Unicode e árabe, contagem de segmentos, webhooks de entrega e tratamento de erros.

Atualizado em 10 min de leitura

Por OmniChannels.ai Editorial Team · Revisado por BroadNet Messaging Solutions Team

Integração

Resposta curta

Para enviar um SMS com a API da OmniChannels.ai, faça um POST autenticado para https://api.broadnet.me/sms/sendSms com um corpo JSON contendo senderId, destinationNumber, message e messageType. Use TEXT para texto GSM-7 e UNICODE para árabe ou emoji. Uma resposta 200 devolve o ID da mensagem como texto simples, e o status final de entrega chega depois ao seu webhook.

Nesta página
  1. Como envio um SMS com a API?
  2. Como formatar os números de telefone?
  3. Como envio árabe, emoji ou outro texto Unicode?
  4. Como contar segmentos antes de enviar?
  5. Como envio para muitos números?
  6. Como recebo o status de entrega?
  7. Como tratar erros e evitar duplicatas?
  8. Exemplo prático: códigos de login para um app regional
  9. Quais são os erros comuns?
  10. Como a OmniChannels.ai ajuda

Pontos principais

  • POST /sms/sendSms exige quatro campos: senderId, destinationNumber, message e messageType; o corpo da resposta é o ID da mensagem como texto simples, não JSON.
  • Defina messageType como UNICODE para árabe, emoji ou qualquer caractere fora do GSM-7; um único caractere assim torna a mensagem inteira Unicode e encurta cada segmento.
  • POST /sms/identify conta caracteres e segmentos antes do envio, para você prever quantos segmentos uma mensagem usa.
  • A entrega é assíncrona: um 200 significa aceita, e DELIVERED, FAILED ou REJECTED chega depois ao seu webhook.
  • A API não tem chave de idempotência, então registre cada envio antes de fazê-lo e verifique o status após um timeout em vez de reenviar.

Este guia é para desenvolvedores que precisam enviar SMS a partir de uma aplicação e querem código funcional em Python, Node.js, PHP ou cURL. Ele cobre um envio único, Unicode e árabe, contagem de segmentos, upload em massa, webhooks de status de entrega e tratamento de erros, usando apenas endpoints e campos da nossa referência da API de SMS e da especificação OpenAPI.

Como envio um SMS com a API?

Faça um POST autenticado para /sms/sendSms com um corpo JSON. A resposta é 200 OK com o ID da mensagem como texto simples.

Item Valor
URL base https://api.broadnet.me (sem prefixo /v1)
Endpoint POST /sms/sendSms
Autenticação Authorization: Bearer $BROADNET_TOKEN
Tipo de conteúdo application/json
Campos obrigatórios senderId, destinationNumber, message, messageType

As credenciais de teste são emitidas após uma breve solicitação de acesso, e os envios de teste vão para os seus próprios números verificados. Não há cadastro self-service instantâneo. Veja o 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 nativo)
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 da mensagem em texto simples
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 da mensagem em texto simples, não 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;

O corpo de uma resposta bem-sucedida tem este aspecto:

2603121407537573731

Salve esse ID junto ao seu próprio registro, como um pedido ou uma tentativa de login. É com ele que você associa os status de entrega depois.

Como formatar os números de telefone?

Use código do país mais número nacional, apenas dígitos. O formato segue o plano internacional de numeração da ITU-T E.164, sem o sinal de mais.

Entrada Válido? Por quê
447700900123 Sim Código do país 44 mais número nacional
+44 7700 900123 Não Remova o sinal de mais e os espaços
07700900123 Não Troque o 0 inicial pelo código do país

Guarde os números em E.164 (+447700900123) no banco de dados e remova o + ao montar a requisição. Nosso formatador de números de telefone gratuito ajuda em uma conferência rápida.

Como envio árabe, emoji ou outro texto Unicode?

Defina messageType como UNICODE. Qualquer caractere fora do alfabeto GSM-7, como uma letra árabe, um emoji, aspas curvas ou um travessão longo, muda a mensagem inteira para 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,
)

Em PHP, use JSON_UNESCAPED_UNICODE ao chamar json_encode. A codificação define o tamanho do segmento, conforme definido para SMS na 3GPP TS 23.040:

messageType SMS único Por segmento quando dividido Use para
TEXT 160 caracteres 153 caracteres Texto que use apenas o alfabeto GSM-7
UNICODE 70 caracteres 67 caracteres Árabe, cirílico, chinês, emoji

A maioria das operadoras cobra por segmento, então uma mensagem longa em árabe custa mais do que uma do mesmo tamanho em alfabeto latino. Leia nosso guia de SMS em Unicode e árabe e experimente o contador de caracteres de SMS.

Como contar segmentos antes de enviar?

Chame POST /sms/identify com a mensagem. Ele devolve a codificação detectada, a contagem de caracteres, a contagem de segmentos e o limite por 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
}

Você pode passar smsParts (de smscount), charCount e charLimit em uma requisição de envio. O texto GSM-7 pode aparecer rotulado como GSM-7 na resposta; envie-o como TEXT.

Como envio para muitos números?

Use POST /sms/sendbulk, uma requisição multipart/form-data com um arquivo de destinatários e uma string JSON de configurações.

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())

A resposta inclui bulkSessionId e um objeto bulkListInfo com total, validCount, invalidCount e duplicate. Guarde o bulkSessionId com a campanha. Os jobs podem ser listados, pausados, retomados e abortados com os endpoints da referência. Você também pode verificar números antes de um envio grande com POST /sms/lookup; veja nosso guia de consulta HLR.

Como recebo o status de entrega?

Os status de entrega são enviados por push para a URL de webhook configurada na sua conta. Uma mensagem passa por SUBMITTED e SENT até DELIVERED ou termina como FAILED ou REJECTED. Você informa à nossa equipe a URL HTTPS pública, e os revendedores podem ter um webhook por subconta.

Os campos do payload variam por canal, e a especificação da API não define um único esquema de webhook, então registre primeiro o corpo bruto e mapeie os campos a partir de um evento real da sua conta. Um receptor mínimo armazena o evento e confirma rapidamente:

import express from "express";

const app = express();

app.post("/webhooks/omnichannels", express.json(), async (req, res) => {
  await saveStatusEvent(req.body); // seu armazenamento; processe de forma assíncrona
  res.sendStatus(200);             // confirme rápido
});

app.listen(3000);

Torne o processamento idempotente, porque o mesmo status pode chegar duas vezes, e nunca deixe um SENT tardio sobrescrever um DELIVERED já armazenado. Se o seu endpoint estava fora do ar, POST /sms/resendDlr reenvia os relatórios de um intervalo de datas:

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

Leia mais no guia de webhooks e em status de entrega de mensagens explicados.

Como tratar erros e evitar duplicatas?

Trate primeiro o status HTTP e depois o corpo do erro. Tente de novo apenas em erros de rede, 429 e 5xx.

Código Significado Ação
200 Aceita Guarde o ID
400 Erro de validação ou campo ausente Corrija a requisição
401 / 403 Token inválido ou operação não permitida Corrija; não tente de novo
429 Limite de taxa excedido Aguarde o Retry-After
500, 503, 504 Problema no servidor ou a montante Tente de novo com backoff e jitter

Os erros gerados pela API usam um corpo JSON de cinco campos, com status, error, message, errorCode e requestUri. O limite REST padrão documentado é de 200 requisições por segundo de forma sustentada; os limites da sua conta são confirmados junto com as suas credenciais.

A API não aceita chave de idempotência. Uma requisição pode ter sucesso enquanto a resposta se perde, e uma nova tentativa às cegas então envia duas vezes. Grave uma linha pendente, com a sua própria chave de operação, antes de chamar, guarde o ID da mensagem devolvido e, após um timeout, verifique se há um status por webhook antes de enviar de novo. Em envios em massa, defina allowDuplicate como false. Os detalhes estão em Erros e limites.

Exemplo prático: códigos de login para um app regional

A "Souq Rafiq" (sintética), uma varejista dos Emirados Árabes Unidos, envia códigos de login por SMS.

  1. O serviço de autenticação gera um código de seis dígitos, guarda um hash com expiração de cinco minutos e grava uma linha de envio pending.
  2. Ele chama /sms/sendSms com messageType=UNICODE para usuários de árabe e TEXT para usuários de inglês.
  3. Em um 200, guarda o ID da mensagem.
  4. O handler do webhook marca a linha como DELIVERED, FAILED ou REJECTED.
  5. Se o status não for DELIVERED após uma curta espera, o app oferece um reenvio e, se configurado, outro canal. Veja fallback entre canais.
  6. Limites de taxa para solicitações de código por número e por IP protegem contra abusos; veja prevenção de SMS pumping.

Quais são os erros comuns?

  • Chamar r.json() na resposta do envio. Ela é texto simples.
  • Nomes de campos errados. Use senderId, destinationNumber e message; campos como to, from ou text não fazem parte deste endpoint.
  • Sinais de mais e zeros à esquerda nos números.
  • Esquecer o UNICODE no árabe, o que corrompe o texto.
  • Sender IDs não registrados. Alguns países os bloqueiam ou substituem; confira as regras de sender ID do seu destino e peça que cuidemos do registro.
  • Tratar o 200 como entregue.
  • Token em um app móvel ou no navegador, onde qualquer pessoa pode extraí-lo.
  • Limites: este guia mostra a requisição comum. Campos opcionais, como os formatos de agendamento, devem ser confirmados com a nossa equipe.

Como a OmniChannels.ai ajuda

A OmniChannels.ai envia SMS A2P pela conectividade direta com operadoras da BroadNet, com SMS bidirecional, sender IDs, Unicode e árabe, consulta HLR e SMPP 3.4 para alto volume. A API REST em https://api.broadnet.me usa um token Bearer e também cobre WhatsApp, RCS e outros canais, com status de entrega normalizados em um único formato de webhook. Nossa equipe prepara com você os registros de sender ID. Veja a referência da API de SMS ou o canal de SMS.

Perguntas frequentes

Como envio um SMS com Python?

Use a biblioteca requests para fazer um POST de JSON para https://api.broadnet.me/sms/sendSms com um cabeçalho Authorization: Bearer e os campos senderId, destinationNumber, message e messageType. Leia o token de uma variável de ambiente. O corpo de uma resposta 200 é o ID da mensagem como texto simples, então use r.text em vez de r.json().

Que formato de número de telefone a API de SMS espera?

Código do país mais número nacional, apenas dígitos, sem sinal de mais, prefixo 00, espaços nem zero à esquerda. Por exemplo, 447700900123 é válido, enquanto +44 7700 900123 e 07700900123 não são. Guarde os números em E.164 no seu banco de dados e remova o sinal de mais ao montar a requisição.

Como envio SMS em árabe pela API?

Defina messageType como UNICODE e envie o texto em árabe no campo message em UTF-8. Mensagens Unicode comportam 70 caracteres em um segmento único e 67 por segmento quando divididas, contra 160 e 153 do GSM-7. Teste em aparelhos reais e chame /sms/identify para ver antes a contagem de segmentos.

Como obtenho os relatórios de entrega?

Os status são enviados por push para a URL de webhook configurada na sua conta. As mensagens passam por SUBMITTED e SENT até DELIVERED, FAILED ou REJECTED. Seu endpoint deve armazenar o evento bruto, responder 2xx rapidamente e processar de forma assíncrona. Se eventos foram perdidos, POST /sms/resendDlr pode reenviar relatórios de entrega de um intervalo de datas.

Como envio SMS para muitos números de uma vez?

Use POST /sms/sendbulk, uma requisição multipart com um destinationNumberFile (CSV ou TXT) e uma string JSON bulkRequest contendo senderId, message e messageType. A resposta informa quantos números eram válidos, inválidos ou duplicados e devolve um bulkSessionId que você pode guardar com a sua campanha.

Preciso registrar um sender ID?

Em muitos países, sim. Alguns exigem um sender ID alfanumérico aprovado, e outros precisam de identificadores do regulador ou de templates, que a API aceita em campos opcionais como peId e templateId. Os requisitos variam por país, então consulte a página de sender ID do seu destino, e nossa equipe pode cuidar do registro com você.

Fontes

  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