Referencia de la API REST
Envía mensajes de WhatsApp y SMS, gestiona templates y llamadas con claves API.
https://api.integracionessh.latIntroducció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
Scopes
Cada clave API incluye uno o más scopes. Si falta un scope, la API responde 403.
messages:sendScopePOST /v1/messagessms:sendScopePOST /v1/smssms:readScopeGET /v1/sms/{traceId}otp:sendScopePOST /v1/otp/sendotp:verifyScopePOST /v1/otp/verifytemplates:readScopeGET /v1/templatestemplates:writeScopePOST /v1/templatesPUT /v1/templates/{name}DELETE /v1/templates/{name}calls:initiateScopePOST /v1/callsPOST /v1/calls/permission-requestGET /v1/calls/permission/{userWaId}calls:manageScopePOST /v1/calls/{callId}GET /v1/calls/{callId}calls:settingsScopeGET /v1/calls/settingsPUT /v1/calls/settingsvoice:calls:initiateScopePOST /v1/voice/callsvoice:calls:readScopeGET /v1/voice/callsGET /v1/voice/calls/{callId}GET /v1/voice/calls/{callId}/eventsGET /v1/voice/calls/{callId}/transcriptGET /v1/voice/calls/{callId}/recordingvoice:calls:manageScopePOST /v1/voice/calls/{callId}/endLí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ódigo | Significado |
|---|---|
| 400 | Solicitud inválida (validación Zod) |
| 401 | Clave API ausente o inválida |
| 403 | Clave deshabilitada, expirada o sin scope |
| 404 | Recurso no encontrado |
| 429 | Límite de tasa excedido |
| 502 | Error 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/v1/messagesmessages:sendEnví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!"}/v1/messagesmessages:sendEnvía un template de WhatsApp aprobado por Meta.
{
"to": "521234567890",
"type": "template",
"template": {
"name": "hello_world",
"language": "en_US"
}
}SMS
2/v1/smssms:sendEnví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"}/v1/sms/{traceId}sms:readConsulta 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/v1/otp/sendotp:sendGenera 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."
}/v1/otp/verifyotp:verifyVerifica 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/v1/templatestemplates:readLista 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"
}
]/v1/templatestemplates:writeCrea 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"
}
]
}/v1/templates/{name}templates:writeEdita 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"
]
]
}
}
]
}/v1/templates/{name}templates:writeElimina 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/v1/callscalls:initiateInicia 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..."
}
}/v1/calls/{callId}calls:manageEjecuta 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..."
}
}/v1/calls/{callId}calls:manageObtiene 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"
}/v1/calls/settingscalls:settingsLee la configuración de llamadas del número de WhatsApp del bot.
{
"calling": {
"status": "ENABLED"
}
}/v1/calls/settingscalls:settingsActualiza la configuración de llamadas del número de WhatsApp del bot.
{
"calling": {
"status": "ENABLED"
}
}/v1/calls/permission-requestcalls:initiateEnvía un mensaje solicitando permiso de llamada al usuario.
{"to":"521234567890","bodyText":"Can we call you?"}/v1/calls/permission/{userWaId}calls:initiateConsulta si un usuario ha concedido permiso de llamada.
{
"permission": {
"status": "granted",
"expiration_time": 1718640000
}
}Agentes de voz
9/v1/voice/callsvoice:calls:initiateInicia 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"}/v1/voice/callsvoice:calls:readLista 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"
}/v1/voice/calls/{callId}voice:calls:readObtiene 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"
}/v1/voice/calls/{callId}/endvoice:calls:manageFinaliza una llamada PSTN activa.
Es idempotente si la llamada ya terminó.
{
"callId": "call_xxx",
"status": "ending"
}/v1/voice/calls/{callId}/eventsvoice:calls:readLista 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"
}
]
}/v1/voice/calls/{callId}/transcriptvoice:calls:readLee 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"
}
]
}/v1/voice/calls/{callId}/recordingvoice:calls:readObtiene 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
}/v1/voice/agents/{botId}/structured-outputvoice:calls:readLee 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
}
}
}/v1/voice/agents/{botId}/structured-outputvoice:calls:manageCrea 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"
}
}