SMS
Envíe SMS por todo el mundo a través de la puerta SMPP de Orbit. Orbit se conecta a operadores de nivel 1 y agregadores en más de 190 países, y maneja concatenación, codificación y seguimiento de entrega automáticamente. Esta página lleva a través del canal de principio a fin: qué remitente adjuntar, dónde se necesita registro antes de que se acepte el tráfico, cómo la codificación decide qué cuesta cada envío, qué le dice el ciclo de vida del estado, y cómo leer fallos cuando vuelven.Envíe un SMS
to como from se validan como E.164 — formato internacional completo con el prefijo del país, como +14155552671. Cómo Orbit valida y normaliza números en Ciclo de vida de números.
Use una clave sandbox (dv_test_sk_… sobre curl, ORBIT_API_KEY en el código) mientras prototipa — los envíos sandbox son simulados, gratuitos y nunca llegan a un operador. Cambie a la clave en vivo cuando vaya a producción; nada del código arriba cambia.
La pestaña Node arriba usa el ayudante genérico orbit.messages.send({ channel: 'sms', ... }); el método tipado por canal orbit.messages.sendSms({ to, body, from }) hace el mismo POST — elija una forma y úsela consistentemente.
Respuesta
El punto responde HTTP 202 Accepted — el mensaje está persisted y en cola para entrega (aún no entregado al operador). Elid es un id de mensaje de plataforma de la forma msg_ seguido de 32 caracteres hex en minúsculas (sin infijo de canal); siga su ciclo de vida a través de webhooks de entrega.
data.id para consultar o conciliar después, y bifurque en data.status (comienza en queued):
- Node.js / fetch (TypeScript) — el SDK o el valor de retorno de
res.json()lleva el sobre:message.data.id,message.data.status. - Python —
send_smsdevuelve el cuerpo JSON crudo como dict:message["data"]["id"],message["data"]["status"]. - Go —
SendSMSdesmarca el sobre en un struct tipado:msg.Data.ID,msg.Data.Status. - Ruby / PHP (vía de escape) —
client.requestdevuelve el cuerpo JSON crudo:send.dig("data", "id")/$send['data']['id'].
segments y encoding en cada envío — son lo que recobtaba la facturación, y la sección Codificación y concatenación abajo muestra cómo predecir ambos antes de enviar.
Patrones comunes
Dos patrones cubren casi toda integración SMS de producción: reintentos seguros al enviar y paginar el historial de mensajes.Envío idempotente con Idempotency-Key
Puntos POST que crean recursos aceptan un encabezadoIdempotency-Key. Un reintento que presenta la misma clave devuelve el sobre original — sin envío duplicado, sin segundo cargo. Los SDKs mintan un UUID por llamada automáticamente; sobre HTTP crudo lo pone explícitamente. De cualquier forma, pase una clave estable a los intentos de un envío lógico en vez de dejar que cada reintento minta la suya.
Node
Python
Paginar GET /messages a través de llamadas de lista SDK
El historial de mensajes está paginado por cursor: cada página llevameta.pagination.cursor y meta.pagination.has_more; pase el cursor de vuelta hasta que has_more sea false. El SDK Node envía un bucle de cursor y un iterador que se pagin solo; los otros SDKs paginan a través de sus métodos de lista o la vía de escape:
Node
Python
Ejemplo trabajado: envíe, consulte y maneje fallos
La secuencia abajo es la misma de principio a fin: POST el envío, consulteGET /messages/{id} (o tome el webhook — consulta es el respaldo), y bifurque deterministicamente cuando algo falla. El cuerpo es intencionalmente un envío UCS-2 para que vea el veredicto de codificación volver en vez de asumir precio GSM-7.
1. Envíe el mensaje
from, sender_pool_id, messaging_service_id o from_extension — de otra forma el punto devuelve HTTP 422 con SENDER_REQUIRED (p.ej. cuando un paste como "from": null entra a su solicitud). Para lo que significa cada selector, vea Elija un tipo de remitente.
2. Lea la respuesta de envío
status: queued es el estado inicial — todavía nada entregado, y ningún external_id (referencia del operador) ha vuelto. Los campos segments y encoding son exactamente contra lo que multiplica el precio por segmento; trátelos como la factura, no una sugerencia.
3. Consulte la fila
Cuando no puede (o no quiere) suscribirse a webhooks, consulteGET /messages/{id} en el id que devolvió el envío. La fila avanza por sending → sent → delivered / un fallo terminal. Cada respuesta muestra también metadata.classified_error_code para fallos terminales y metadata.no_dlr_channel para filas Meta-DM, entonces bifurque en el status legible por máquina, nunca en strings de etiqueta.
sending (el proveedor la ganó) o sent (el proveedor la aceptó) antes de delivered. Añada ?include=webhook_deliveries cuando quiere la historia de fan-out en el mismo viaje.
4. Bifurque en fallos
Bifurque en elstatus de la consulta, el data.status del webhook, o metadata.classified_error_code — todos cuentan la misma historia. Las familias de fallo abajo son las que tiene que manejar realísticamente:
En cualquier webhook
message.failed, data.status es el campo a bifurcar — submitted_no_receipt y expired montan el mismo evento, y un webhook posterior message.delivered puede aterrizar incluso después de uno de esos.
Fundamentos de entrega SMS
La entrega SMS depende de tres cosas, en este orden: de quién envía, de dónde, y qué rápido. Tengálas bien, y la codificación se convierte en la única variable de costo que queda.Elija un tipo de remitente
Los remitentes existen por un razón cada uno: entrega. Necesita un ID de remitente aprobado para las reglas del país destino, o el operador filtra el tráfico antes de que le cueste un segmento — vea Requisitos de cumplimiento de países.
Onboarding a través del dashboard
La recorrido del dashboard dura menos de cinco minutos y capta los dos modos de fallo abajo antes de que escriba una línea de código.- Abra Channels → SMS en el dashboard.
- Haga clic en Attach Sender y elija un tipo de remitente arriba. Orbit valida el formato (número E.164, ID alfanumérico de 3–11, o referencia de grupo) y verifica si el destino que define como default necesita registro.
- Envíe un mensaje de prueba a un número que posea. El compositor muestra
segmentsyencodinginline, así que ve el costo por segmento estimado antes de enviar. - Si su puerta de destino rechaza el adjuntar (US sin campaña 10DLC, un país gated sin aprobación de remitente ID), el asistente lo dirige al flujo de registro — vea las próximas dos secciones.
GET /api/v1/messaging/senders sobre API.
Registro de 10DLC & tipos de campañas (US)
Si envía a destinos US sobre códigos largos numéricos, los operadores necesitan registro; el tráfico no registrado es filtrado, sobrecargado, o ambos. Orbit someter registro a través de The Campaign Registry en su nombre — la recorrido completa (marca → campaña → aprobación → niveles de volumen) está en la Guía de registro de 10DLC. El punto US-específico a tener en cuenta: el volumen después del registro se conquenta como un techo de segmento de por-día, por-número basado en su puntuación de vetting de marca — no una tasa por-segundo. Si necesita más capacidad diaria, alza su puntuación de vetting (datos de marca completos, EIN, website) o asigne más números a la campaña. Para destinos no-US que gerten IDs de remitente alfanuméricos (mayoría de Europa, Brasil, Bangladesh, partes de APAC), el flujo paralelo de registro es Registro de ID de remitente, que registra su aprobación por país y adjunta los documentos KYC soportantes. La puerta en tiempo de envío rechaza tráfico a países gated hasta que la entrada del país coincidente seaapproved — sin filtración silenciosa, el fallo regresa como un rejected visible.
India es la excepción: sus IDs de remitente (“Headers”) registran a través de DLT/TRAI en vez del flujo genérico — vea Onboarding de DLT-India.
Codificación y concatenación
La codificación es la única variable de costo que sobrevive un remitente debidamente registrado. SMS recaba por segmentos, y el contador de segmentos depende totalmente de en qué alfabeto caba el cuerpo.GSM-7 vs. UCS-2
- GSM-7 — alfabeto GSM de 7-bit (ASCII más unos pocos extras:
@,£,€, algo de griego). Un cuerpo que caba obtiene hasta 160 caracteres por segmento, o 153 caracteres en envío de múltiples partes (7 por segmento van al encabezado UDH de concatenación). - UCS-2 — cualquier carácter fuera de GSM-7 (emoji, CJK, comillas inteligentes, la mayoría de scripts no-Latin) flipa todo el mensaje a codificación 16-bit. Un cuerpo obtiene hasta 70 caracteres por segmento, o 67 en múltiples partes.
Ejemplo trabajado
Su pedido se envió — responda YES — 30 caracteres, todos GSM-7 → 1 segmento, GSM-7.
Adjuntar un solo emoji flipa el alfabeto: 54 caracteres en UCS-2 → todavía 1 segmento, pero un boletín ASCII de 160 caracteres se vuelve 2 segmentos UCS-2 tan pronto como entra un emoji. A escala, ese es el número que conduce costo.
La plataforma cuenta los segmentos antes de despachar; la respuesta de envío lleva el veredicto:
wasTruncated: true para que lo ve, en vez de preguntarse dónde fue el rabo. Eso es lo que la lista de features llama “mensajes concatenados hasta 10 segmentos”. Lea segments en cada envío y bifurque sus estimaciones de facturación en él — es exactamente contra lo que multiplica el precio por segmento.
Límites de velocidad, volumen y grupos de remitentes
Dos límites independientes sobre el volumen SMS, y tiene que despejar ambos:- Límite de solicitud del lado API. 100 solicitudes/minuto por inquilino por default en
POST /messages/sms, keyed por organización. Encima obtiene429 RATE_LIMITED; vea la Guía de límites de velocidad para encabezados y manejo de reintentos. La tabla completa por canal abajo. - Volumen del lado remitente. US 10DLC: un techo de segmento por-día, por-número fijado por su nivel de vetting. En otros lugares: lo que la ruta del destino admite por remitente.
sticky, round_robin, random o geomatch, y el volumen por remitente multiplica por tamaño del grupo. Los grupos también dejan que un remitente degradado rote fuera sin que su código de envío cambie — el punto de salud del grupo le dice qué miembro está degradando antes de que se convierta en un problema de entrega.
Ciclo de vida del estado de mensajes
Cada SMS saliente lleva unstatus que avanza cuando el mensaje se mueve de su llamada API hacia el handset — o hacia un fallo terminal:
queued → sending → sent → delivered (o failed / undelivered / rejected / expired)
Suscríbase a transiciones de estado vía webhooks usando los eventos message.sent, message.delivered y message.failed — un webhook por transición, cada uno llevando el id del mensaje y el nuevo valor status.
Las nuancias que captan operadores:
submitted_no_receipt— el proveedor aceptó el envío, ninguna DLR volvió dentro de la ventana de 30 minutos SMPP. Etiquetado intermedio (is_terminal: false) porque unadeliveredtardía o fallo DLR puede todavía aterrizar y sobreescribir. Trátelo como resultado desconocido, no una entrega y no un fallo.expired— una DLR llegó después de que se cerró la ventana de llegada tardía. Fila cerrada, resultado no conocible; fan-out enmessage.failed.cancelled— solo alcanzable por usted; ningún webhook nunca dispara por él.
is_terminal vive en Ciclo de vida de entrega; las semánticas por estado y la tabla de transición completa están en la referencia del ciclo de vida del estado de mensajes.
Solución de problemas
Cuando llegamessage.failed, bifurque en el status del payload, no el tipo de evento — submitted_no_receipt y expired fan-out en ese evento también. Lea metadata.classified_error_code para manejo por máquina, y error_code / error_message para la palabras del operador cuando abre un ticket.
El paquete de escalación que consigue que un ticket de soporte sea contestado en la primera pasada: su ID de inquilino, un ID de mensaje, y la
classified_error_code de la fila — además Referencia del proveedor del Registro de entrega para filas de síntoma DLR. La guía del registro de entrega muestra cómo filtrar el estado; Busca de números es cómo distingue un número muerto de uno vivo antes de repetir.
Precios
El precio SMS es por segmento y varía por país de destino. Consulte la página de precios o consulte el puntoGET /api/v1/pricing/messaging?country=<ISO> para tarifas en tiempo real (el array devuelto channels incluye sms).
El número de planificación viene de las secciones anteriores: multiplique la tarifa por segmento que devuelve el punto de precios por el valor segments que lleva la respuesta de envío. Dos envíos de lo contrario idénticos se recaban de forma diferente el momento en que uno cambia a UCS-2 — vea Codificación y concatenación para cuándo sucede eso y cómo normalizarlo de nuevo.
Features
- Mensajes A2P y P2P — soporte aplicación-a-persona y persona-a-persona
- Alcance global — 190+ países a través de la red de agregadores de Devotel
- Informes de entrega — webhooks de estado en tiempo real para cada mensaje
- Mensajes concatenados — SMS multi-parte manejado transparentemente (hasta 10 segmentos)
- Validación E.164 — validación automática del formato del número de teléfono
- Soporte Unicode — codificación GSM-7 y UCS-2 completa con detección automática y normalización de comillas inteligentes
- ID de remitente — IDs de remitente alfanuméricos donde soportan las regulaciones locales, gateados por registro donde se necesita
Límites de Velocidad
Envíos SMS están limitados a 100 solicitudes/minuto por inquilino por default en el punto/messages/sms. El límite es keyed por inquilino (por organización), no por IP ni por plan, así que llamadores concurrentes dentro del mismo inquilino comparten una piscina mientras inquilinos separados nunca se afectan entre sí.
¿Necesita un techo más alto? El techo por inquilino es sobrecrucible a través de la configuración de mensajería de su organización (channel_rate_overrides.sms) — contacte a soporte o póngalo desde el dashboard. Exceder el límite devuelve 429 Too Many Requests con el código de error RATE_LIMITED; vea la Guía de límites de velocidad para encabezados y manejo de retry.
El mismo modelo por-canal, por-minuto, por-inquilino aplica a través de canales de mensajería (cada uno independientemente sobrecrucible):