Skip to main content

Enviar y recibir mensajes

Esta guía te lleva desde una clave de API hasta un flujo de mensajes bidireccional que funciona: envía un mensaje saliente, sigue su entrega y recibe la respuesta en tu propio servidor. El ejemplo usa SMS — el mismo patrón de tres pasos (enviar → seguir → recibir) se aplica a WhatsApp, RCS, Viber y correo electrónico, cada uno en su propio endpoint. Harás lo siguiente:
  1. Enviar un mensaje
  2. Seguir la entrega
  3. Recibir mensajes entrantes
  4. Responder a un mensaje entrante

Requisitos previos

  • Una clave de API desde Ajustes → Claves de API. Utiliza una clave sandbox (dv_test_sk_…) mientras construyes — los envíos sandbox son gratuitos y simulados, y devuelven comprobantes de entrega deterministas para que puedas ejercer tanto los caminos de éxito como los de error. Cambia a una clave live (dv_live_sk_…) para producción.
  • Un número remitente que pueda enviar en el canal que uses. Para SMS es un número compatible con SMS que posees (búscalo y cómpralo vía la API de Numbers o desde Dashboard → Números). Si omites from, Orbit elige un remitente elegible para el destino.
  • Una URL HTTPS pública para el paso de recepción. Cualquier herramienta de túnel funciona mientras desarrollas.
Todas las solicitudes van a una única URL base — el sandbox es el mismo host, seleccionado por tu clave, no por otro dominio:
Cada solicitud lleva tu clave en el encabezado X-API-Key.

1. Enviar un mensaje

Envía un SMS con POST /messages/sms. Solo to y body son obligatorios; from es opcional.
La respuesta es 202 Accepted — el mensaje se persiste y se pone en cola para entrega, aún no entregado al operador. Los campos viven bajo data; meta lleva el request_id que debes registrar para soporte.
El id (msg_ seguido de 32 caracteres hexadecimales) es el handle para todas las llamadas posteriores — las consultas de estado, los webhooks de entrega y la traza del mensaje lo usan. Las respuestas sandbox añaden "test_mode": true a meta.
Envía siempre una Idempotency-Key en los envíos. Reproducir la misma clave y el mismo cuerpo dentro de las 24 horas devuelve la respuesta original en lugar de enviar un duplicado; reproducirla con un cuerpo distinto devuelve 409 IDEMPOTENCY_KEY_REUSED.

Otros canales

Cada canal tiene su propio endpoint bajo el prefijo /messages, con una forma de cuerpo adaptada a ese canal. No hay una única ruta polimórfica por canal — elige el endpoint que coincida con tu canal:

2. Seguir la entrega

Un mensaje en cola recorre un ciclo de estados antes de llegar al destinatario:
Tienes dos formas de seguirlo: Consulta (poll) el mensaje por id:
Suscríbete a webhooks (recomendado — sin polling). Por cada transición de estado se dispara un evento, cada uno llevando el id del mensaje y el nuevo status:
  • message.sent — aceptado por el operador
  • message.delivered — entrega confirmada al terminal
  • message.failed — fallo terminal (el status del payload distingue failed, undelivered, expired y submitted_no_receipt; error_code / error_message llevan el motivo del proveedor cuando está presente)
Registra un endpoint webhook una sola vez y deja que los eventos fluyan:
Un evento de entrega se ve así:
Verifica el encabezado X-Orbit-Signature antes de confiar en cualquier payload, y deduplica por el id del evento — la entrega es al menos una vez (at-least-once). Consulta Seguridad de webhooks para el fragmento de verificación.

3. Recibir mensajes entrantes

Cuando alguien responde a tu número (o te escribe primero), Orbit registra un mensaje entrante y — si estás suscrito a message.received en el paso anterior — lo envía por POST a tu URL de webhook:
El mensaje entrante también es consultable — lista todo lo recibido con el filtro direction=inbound:
El enrutamiento entrante es automático para los números que posees en Orbit — una respuesta a cualquiera de tus números remitentes se captura y, con una suscripción message.received, se entrega a tu webhook. No hace falta cablear URLs entrantes por número.

4. Responder a un mensaje entrante

Responder es solo otro envío, dirigido de vuelta al from entrante. Intercambia to y from y llama a POST /messages/sms de nuevo:
Ambos mensajes comparten una conversación, así que una vez que existe el hilo puedes extraer el intercambio completo con el filtro conversation_id en GET /messages.

Errores comunes

Todo error usa la misma forma — coincide en error.code (una constante en MAYÚSCULAS) y registra meta.request_id: Lista completa: Códigos de error.

Próximos pasos