Envío de SMS
Envío de SMS
Sección titulada «Envío de SMS»El servicio de SMS permite enviar mensajes de texto a números chilenos desde tu sistema. Los mensajes se procesan de forma asíncrona con routing inteligente, reintentos automáticos y tracking de estado de entrega.
Requisitos Previos
Sección titulada «Requisitos Previos»Antes de usar el endpoint necesitas:
- Una API Key con uno de estos roles:
ADMIN,SUPER-ADMIN,SMS_OPERADOR, oFULL-API - El tenant debe tener el servicio SMS habilitado
Flujo del Mensaje
Sección titulada «Flujo del Mensaje»POST /{tenantSlug}/sms/send │ ▼ Validar teléfono y body │ ▼ Calcular segmentos (GSM-7 / Unicode) │ ▼ Crear registro en BD (status: queued) │ ▼ Encolar en BullMQ (prioridad según routeType) │ ▼ Respuesta inmediata: { messageId, status: "queued" } │ ▼ [Async] Worker procesa con circuit breaker │ ▼ [Async] Proveedor entrega SMS → status: delivered/failedLa respuesta es inmediata — el mensaje se encola y se procesa en background. Usa el messageId para consultar el estado posteriormente.
Request
Sección titulada «Request»Endpoint
Sección titulada «Endpoint»POST /{tenantSlug}/sms/sendHeaders
Sección titulada «Headers»Authorization: Bearer {api_key}Content-Type: application/json{ "to": "+56912345678", "body": "Tu código de verificación es 123456", "routeType": "transactional", "metadata": { "orderId": "ORD-001", "source": "mi-sistema" }}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
to | string | Sí | Teléfono chileno destino |
body | string | Sí | Texto del mensaje (máx. 1600 caracteres) |
routeType | string | Sí | Tipo de ruta para priorización |
metadata | object | No | Objeto JSON libre para trazabilidad |
Formatos de Teléfono Aceptados
Sección titulada «Formatos de Teléfono Aceptados»| Formato | Ejemplo | Descripción |
|---|---|---|
+56XXXXXXXXX | +56912345678 | Con prefijo internacional |
56XXXXXXXXX | 56912345678 | Sin signo + |
9XXXXXXXX | 912345678 | Solo número móvil |
Todos se normalizan internamente a +56XXXXXXXXX.
Tipos de Ruta (routeType)
Sección titulada «Tipos de Ruta (routeType)»El routeType determina la prioridad de procesamiento y el proveedor de envío:
| Tipo | Descripción | Prioridad |
|---|---|---|
otp | Códigos de verificación y autenticación | Máxima |
premium | Mensajes prioritarios de negocio | Alta |
transactional | Notificaciones de transacciones y eventos | Media |
marketing | Campañas promocionales (requiere opt-in del destinatario) | Baja |
wholesale | Envíos masivos de alto volumen | Mínima |
Ejemplo con curl
Sección titulada «Ejemplo con curl»curl -X POST "https://api.redcumbre.cl/{tenantSlug}/sms/send" \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "to": "+56912345678", "body": "Hola, tu pedido #1234 fue despachado.", "routeType": "transactional" }'Response
Sección titulada «Response»Respuesta Exitosa (201)
Sección titulada «Respuesta Exitosa (201)»{ "messageId": "cmovnx2op0001sezxd0srby0g", "status": "queued", "segmentCount": 1, "encoding": "gsm7"}| Campo | Tipo | Descripción |
|---|---|---|
messageId | string | Identificador único del mensaje (CUID) |
status | string | Siempre "queued" en respuesta inicial |
segmentCount | number | Cantidad de segmentos SMS |
encoding | string | "gsm7" o "ucs2" según caracteres usados |
Segmentos y Encoding
Sección titulada «Segmentos y Encoding»Los SMS se dividen en segmentos según la codificación del contenido:
| Encoding | Caracteres por segmento | Cuándo se usa |
|---|---|---|
GSM-7 (gsm7) | 160 | Texto ASCII estándar (letras, números, puntuación básica) |
UCS-2 (ucs2) | 70 | Texto con caracteres especiales, emojis, acentos no-GSM |
Códigos de Error
Sección titulada «Códigos de Error»| Código | Descripción | Causa |
|---|---|---|
| 400 | Validación fallida | Teléfono mal formado, body vacío, routeType inválido |
| 401 | No autorizado | API key inválida, expirada o revocada |
| 403 | Prohibido | Servicio SMS no habilitado o rol insuficiente |
| 429 | Rate limited | OTP rate limit (1 por número cada 5 min) |
Ejemplo de Error 400
Sección titulada «Ejemplo de Error 400»{ "statusCode": 400, "message": [ "to must be a valid Chilean phone number (+56XXXXXXXXX, 56XXXXXXXXX, or 9XXXXXXXX)" ], "error": "Bad Request"}Ejemplo de Error 403
Sección titulada «Ejemplo de Error 403»{ "statusCode": 403, "message": "El servicio 'SMS' no está habilitado para este tenant. Contacte al administrador de la plataforma.", "error": "Forbidden"}Consultar Estado del Mensaje
Sección titulada «Consultar Estado del Mensaje»Después de enviar un SMS, puedes consultar su estado de entrega:
Listar Mensajes
Sección titulada «Listar Mensajes»GET /{tenantSlug}/sms/messagescurl "https://api.redcumbre.cl/{tenantSlug}/sms/messages?status=delivered" \ -H "Authorization: Bearer {api_key}"Detalle de un Mensaje
Sección titulada «Detalle de un Mensaje»GET /{tenantSlug}/sms/messages/{messageId}curl "https://api.redcumbre.cl/{tenantSlug}/sms/messages/cmovnx2op0001sezxd0srby0g" \ -H "Authorization: Bearer {api_key}"Estados del Mensaje
Sección titulada «Estados del Mensaje»| Estado | Terminal | Descripción |
|---|---|---|
queued | No | En cola, pendiente de procesamiento |
submitted | No | Enviado al proveedor SMS |
sent | No | Confirmado enviado por el proveedor |
delivered | Sí | Entregado al destinatario |
undelivered | Sí | No se pudo entregar (número inválido, apagado, etc.) |
failed | Sí | Error en el envío (proveedor falló) |
expired | Sí | Sin confirmación de entrega después de 1 hora |
rejected | Sí | Rechazado por política de contenido |
Estadísticas
Sección titulada «Estadísticas»Consulta estadísticas de envío para un rango de fechas:
GET /{tenantSlug}/sms/stats?dateFrom=2026-01-01&dateTo=2026-01-31curl "https://api.redcumbre.cl/{tenantSlug}/sms/stats?dateFrom=2026-01-01&dateTo=2026-01-31" \ -H "Authorization: Bearer {api_key}"Casos de Uso
Sección titulada «Casos de Uso»Notificación de Despacho
Sección titulada «Notificación de Despacho»curl -X POST "https://api.redcumbre.cl/{tenantSlug}/sms/send" \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "to": "+56987654321", "body": "Tu pedido #5678 fue despachado. Seguimiento: https://track.example.com/5678", "routeType": "transactional", "metadata": { "orderId": "5678", "type": "dispatch" } }'Código de Verificación (OTP)
Sección titulada «Código de Verificación (OTP)»curl -X POST "https://api.redcumbre.cl/{tenantSlug}/sms/send" \ -H "Authorization: Bearer {api_key}" \ -H "Content-Type: application/json" \ -d '{ "to": "+56912345678", "body": "Tu código de verificación es 482913. Expira en 5 minutos.", "routeType": "otp" }'Integración JavaScript
Sección titulada «Integración JavaScript»const response = await fetch( `https://api.redcumbre.cl/${tenantSlug}/sms/send`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ to: '+56912345678', body: 'Recordatorio: tu cita es mañana a las 10:00.', routeType: 'transactional', metadata: { appointmentId: 'APT-100' }, }), });
const { messageId, segmentCount } = await response.json();console.log(`SMS encolado: ${messageId} (${segmentCount} segmento/s)`);