REST API

Referencia de la API REST

Envía mensajes de WhatsApp y SMS, gestiona templates y llamadas con claves API.

URL basehttps://api.integracionessh.lat
Obtener API key

Introducción

La API REST acepta y devuelve JSON. CORS está habilitado para integraciones desde el navegador. Todas las rutas documentadas requieren el header X-API-Key.

URL base

https://api.integracionessh.lat

Autenticación

Incluye tu clave API en cada solicitud. Las claves se asocian a un bot y heredan sus permisos (scopes).

Header requerido

X-API-Key: YOUR_API_KEY
Para crear una clave API, inicia sesión y ve a Developer API.Obtener API key

Scopes

Cada clave API incluye uno o más scopes. Si falta un scope, la API responde 403.

messages:sendScope
POST /v1/messages
sms:sendScope
POST /v1/sms
sms:readScope
GET /v1/sms/{traceId}
otp:sendScope
POST /v1/otp/send
otp:verifyScope
POST /v1/otp/verify
templates:readScope
GET /v1/templates
templates:writeScope
POST /v1/templatesPUT /v1/templates/{name}DELETE /v1/templates/{name}
calls:initiateScope
POST /v1/callsPOST /v1/calls/permission-requestGET /v1/calls/permission/{userWaId}
calls:manageScope
POST /v1/calls/{callId}GET /v1/calls/{callId}
calls:settingsScope
GET /v1/calls/settingsPUT /v1/calls/settings
voice:calls:initiateScope
POST /v1/voice/calls
voice:calls:readScope
GET /v1/voice/callsGET /v1/voice/calls/{callId}GET /v1/voice/calls/{callId}/eventsGET /v1/voice/calls/{callId}/transcriptGET /v1/voice/calls/{callId}/recording
voice:calls:manageScope
POST /v1/voice/calls/{callId}/end

Límites de tasa

Las respuestas incluyen headers de rate limit. Si superas el límite, recibirás 429 con Retry-After.

Headers de respuesta

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1718640060

Errores

Los errores devuelven un objeto JSON con el campo error.

CódigoSignificado
400Solicitud inválida (validación Zod)
401Clave API ausente o inválida
403Clave deshabilitada, expirada o sin scope
404Recurso no encontrado
429Límite de tasa excedido
502Error al comunicarse con WhatsApp o el proveedor SMS

Ejemplo

{ "error": "Invalid request body" }

Endpoints

Referencia de las rutas públicas /v1/*. El número to debe contener solo dígitos (código de país + número).

Mensajes

2
POST/v1/messagesmessages:send

Envía un mensaje de texto de WhatsApp al número indicado.

Usa type text o type template. Para templates, name y language deben coincidir con un template aprobado.

{"to":"521234567890","type":"text","text":"Hello!"}
POST/v1/messagesmessages:send

Envía un template de WhatsApp aprobado por Meta.

{
  "to": "521234567890",
  "type": "template",
  "template": {
    "name": "hello_world",
    "language": "en_US"
  }
}

SMS

2
POST/v1/smssms:send

Envía un SMS de texto libre y devuelve un traceId para consultar la trazabilidad.

Requiere que el bot tenga SMS habilitado y un remitente configurado. Si el envío falla, la respuesta incluye traceId para consultar el estado.

{"to":"573001234567","text":"Hello from SMS API"}
GET/v1/sms/{traceId}sms:read

Consulta la trazabilidad de un SMS enviado por traceId.

Devuelve estado de entrega, IDs del proveedor, errores y timestamps. Solo accesible para el tenant y bot de la API key.

{
  "traceId": "550e8400-e29b-41d4-a716-446655440000",
  "phone": "573001234567",
  "channel": "sms",
  "status": "delivered",
  "failureKind": null,
  "externalMessageId": "telcored-123",
  "telcoredMessageId": "telcored-123",
  "sendErrorMessage": null,
  "deliveryErrorCode": null,
  "deliveryErrorMessage": null,
  "deliveryStatus": "DELIVRD",
  "finalDeliveryCode": 1,
  "lastIntermediateCode": null,
  "sentAt": "2026-06-17T12:00:01.000Z",
  "deliveredAt": "2026-06-17T12:00:05.000Z",
  "failedAt": null,
  "dlrAt": "2026-06-17T12:00:05.000Z",
  "cost": "0.02",
  "part": "1",
  "sender": "msg",
  "requestDlr": true,
  "createdAt": "2026-06-17T12:00:00.000Z",
  "updatedAt": "2026-06-17T12:00:05.000Z"
}

OTP

2
POST/v1/otp/sendotp:send

Genera y envía un código OTP por SMS o WhatsApp.

Usa channel sms o whatsapp. Para WhatsApp puedes enviar template AUTHENTICATION con name y language. El código expira en 5 minutos.

{
  "channel": "sms",
  "to": "573001234567",
  "message": "Tu codigo de verificacion es {{code}}. Expira en 5 minutos."
}
POST/v1/otp/verifyotp:verify

Verifica un código OTP previamente enviado al número indicado.

Devuelve verified true/false y reason (verified, invalid_code, expired, max_attempts, not_found).

{"to":"573001234567","code":"123456"}

Templates

4
GET/v1/templatestemplates:read

Lista los templates de WhatsApp del bot asociado a la clave API.

Sincroniza templates desde Meta y devuelve name, language, category, status y components.

[
  {
    "name": "hello_world",
    "language": "en_US",
    "category": "UTILITY",
    "status": "APPROVED",
    "components": [
      {
        "type": "BODY",
        "text": "Hello World"
      }
    ],
    "metaTemplateId": "111",
    "syncedAt": "2026-06-17T12:00:00.000Z",
    "createdAt": "2026-06-17T12:00:00.000Z"
  }
]
POST/v1/templatestemplates:write

Crea un template de WhatsApp. Meta lo revisa antes de poder enviarlo.

name debe ser minúsculas, números y guiones bajos. Si BODY tiene variables ({{1}}), incluye example.body_text. Categoría: MARKETING, UTILITY o AUTHENTICATION.

{
  "name": "order_update",
  "language": "es",
  "category": "UTILITY",
  "components": [
    {
      "type": "BODY",
      "text": "Hola {{1}}, tu pedido {{2}} está listo.",
      "example": {
        "body_text": [
          [
            "Juan",
            "12345"
          ]
        ]
      }
    },
    {
      "type": "FOOTER",
      "text": "Gracias por tu compra"
    }
  ]
}
PUT/v1/templates/{name}templates:write

Edita un template rechazado de WhatsApp y lo reenvía a revisión de Meta.

Solo se pueden editar templates en estado REJECTED. Pasa language en el body o como query ?language= (default: es).

{
  "language": "es",
  "components": [
    {
      "type": "BODY",
      "text": "Hola {{1}}, tu pedido {{2}} fue actualizado.",
      "example": {
        "body_text": [
          [
            "Juan",
            "12345"
          ]
        ]
      }
    }
  ]
}
DELETE/v1/templates/{name}templates:write

Elimina un template de WhatsApp por nombre en Meta y en la caché local.

Elimina todas las variantes de idioma con el mismo name del bot.

204 No Content — cuerpo de respuesta vacío

Llamadas

7
POST/v1/callscalls:initiate

Inicia una llamada saliente de WhatsApp (WebRTC). session.sdp_type debe ser offer.

Requiere permiso de llamada del usuario. Usa permission-request y getCallPermission antes de llamar.

{
  "to": "521234567890",
  "session": {
    "sdp_type": "offer",
    "sdp": "v=0..."
  }
}
POST/v1/calls/{callId}calls:manage

Ejecuta una acción sobre una llamada activa: pre_accept, accept, reject o terminate.

Las acciones pre_accept y accept requieren session con sdp_type answer u offer según el flujo WebRTC.

{
  "action": "accept",
  "session": {
    "sdp_type": "answer",
    "sdp": "v=0..."
  }
}
GET/v1/calls/{callId}calls:manage

Obtiene el estado de una llamada por callId.

{
  "callId": "call_xxx",
  "tenantId": "tenant_xxx",
  "botId": "bot_xxx",
  "phoneNumber": "521234567890",
  "direction": "BUSINESS_INITIATED",
  "status": "initiated",
  "startedAt": "2026-06-17T12:00:00.000Z",
  "createdAt": "2026-06-17T12:00:00.000Z",
  "updatedAt": "2026-06-17T12:00:00.000Z"
}
GET/v1/calls/settingscalls:settings

Lee la configuración de llamadas del número de WhatsApp del bot.

{
  "calling": {
    "status": "ENABLED"
  }
}
PUT/v1/calls/settingscalls:settings

Actualiza la configuración de llamadas del número de WhatsApp del bot.

{
  "calling": {
    "status": "ENABLED"
  }
}
POST/v1/calls/permission-requestcalls:initiate

Envía un mensaje solicitando permiso de llamada al usuario.

{"to":"521234567890","bodyText":"Can we call you?"}
GET/v1/calls/permission/{userWaId}calls:initiate

Consulta si un usuario ha concedido permiso de llamada.

{
  "permission": {
    "status": "granted",
    "expiration_time": 1718640000
  }
}

Agentes de voz

9
POST/v1/voice/callsvoice:calls:initiate

Inicia una llamada PSTN saliente con el agente de voz del bot de la API key.

Requiere telefonía habilitada en el bot, Telnyx configurado y el scope voice:calls:initiate. Usa webhooks para eventos asíncronos.

{"to":"573001234567","contactName":"Jane Doe"}
GET/v1/voice/callsvoice:calls:read

Lista llamadas Telnyx del bot asociado a la API key.

Soporta limit (1-100) y paginación con cursor. Solo devuelve llamadas PSTN del agente de voz.

{
  "items": [
    {
      "callId": "550e8400-e29b-41d4-a716-446655440000",
      "botId": "bot_xxx",
      "phoneNumber": "573001234567",
      "businessPhoneNumber": "+12025550100",
      "direction": "outbound",
      "status": "accepted",
      "duration": 120,
      "startedAt": "2026-06-17T12:00:00.000Z",
      "recordingStatus": "ready",
      "structuredOutputs": {
        "name": "customer_order",
        "result": {
          "intent": "support"
        }
      },
      "costStatus": "final",
      "createdAt": "2026-06-17T12:00:00.000Z",
      "updatedAt": "2026-06-17T12:02:00.000Z"
    }
  ],
  "nextCursor": "eyJjYWxsSWQiOiIuLi4ifQ"
}
GET/v1/voice/calls/{callId}voice:calls:read

Obtiene una llamada por callId con estado, costos y structured outputs.

{
  "callId": "550e8400-e29b-41d4-a716-446655440000",
  "botId": "bot_xxx",
  "phoneNumber": "573001234567",
  "businessPhoneNumber": "+12025550100",
  "direction": "outbound",
  "status": "accepted",
  "duration": 120,
  "startedAt": "2026-06-17T12:00:00.000Z",
  "recordingStatus": "ready",
  "structuredOutputs": {
    "name": "customer_order",
    "result": {
      "intent": "support"
    }
  },
  "costStatus": "final",
  "createdAt": "2026-06-17T12:00:00.000Z",
  "updatedAt": "2026-06-17T12:02:00.000Z"
}
POST/v1/voice/calls/{callId}/endvoice:calls:manage

Finaliza una llamada PSTN activa.

Es idempotente si la llamada ya terminó.

{
  "callId": "call_xxx",
  "status": "ending"
}
GET/v1/voice/calls/{callId}/eventsvoice:calls:read

Lista eventos de la línea de tiempo de una llamada.

{
  "items": [
    {
      "eventId": "evt_1",
      "callId": "call_xxx",
      "type": "initiated",
      "message": "Outbound call started",
      "createdAt": "2026-06-17T12:00:00.000Z"
    }
  ]
}
GET/v1/voice/calls/{callId}/transcriptvoice:calls:read

Lee los mensajes de la transcripción de la llamada.

Soporta limit y cursor sobre mensajes en orden cronológico.

{
  "items": [
    {
      "messageId": "msg_1",
      "role": "assistant",
      "content": "Hello, how can I help?",
      "timestamp": "2026-06-17T12:00:05.000Z"
    }
  ]
}
GET/v1/voice/calls/{callId}/recordingvoice:calls:read

Obtiene una URL firmada para descargar la grabación.

La URL expira en 900 segundos. La grabación debe estar lista.

{
  "url": "https://s3.amazonaws.com/...",
  "expiresInSeconds": 900
}
GET/v1/voice/agents/{botId}/structured-outputvoice:calls:read

Lee la configuración de datos extraídos del agente de voz asociado a la API key.

El botId del path debe coincidir con el bot de la API key. Devuelve null si no hay esquema configurado.

{
  "botId": "bot_xxx",
  "structuredOutput": {
    "name": "customer_order",
    "type": "ai",
    "schema": {
      "type": "object",
      "properties": {
        "subtotal": {
          "type": "number",
          "description": "subtotal"
        },
        "nombre_cliente": {
          "type": "string",
          "description": "nombre cliente"
        },
        "tipo_servicio": {
          "type": "string",
          "description": "tipo servicio"
        }
      },
      "additionalProperties": false
    }
  }
}
PUT/v1/voice/agents/{botId}/structured-outputvoice:calls:manage

Crea o actualiza la configuración de datos extraídos del agente de voz.

Acepta schema JSON Schema o un ejemplo con name + result. Envía null para eliminar la configuración.

{
  "name": "customer_order",
  "type": "ai",
  "result": {
    "subtotal": 34.98,
    "nombre_cliente": "Daniel Salcedo",
    "tipo_servicio": "delivery"
  }
}