Todo lo que hace la app, también por API.
213 endpoints REST sobre HTTPS, autenticados con una llave que tú generas y revocas. Webhooks firmados para enterarte de lo que pasa sin estar preguntando. Esta página es la guía completa: sirve para integrar desde PHP, C#, TypeScript, Python o lo que uses, porque no hay nada que no sea una petición HTTP con una cabecera.
Antes de empezar
Necesitas dos cosas: una cuenta de Kontesta y una API key. La llave se crea desde la app, en Ajustes → API keys, y hace falta permiso de administrador. No se puede crear una llave usando otra llave — es a propósito: evita que una llave filtrada se multiplique sola.
Al crearla eliges qué permisos lleva (ver Permisos y scopes). El secreto completo se muestra una sola vez: en nuestra base solo queda su hash, así que si lo pierdes no hay forma de recuperarlo, solo de rotarlo.
| Concepto | Valor |
|---|---|
URL base | https://api.kontesta.app |
Pruebas | https://staging.kontesta.mx |
| Versión | Va en la ruta: todas las rutas empiezan con /v1 |
| Formato | JSON en petición y respuesta, UTF-8 |
| Llave | ktk_ + 8 caracteres de prefijo + . + el secreto |
Empieza por el entorno de pruebas
https://staging.kontesta.mx la app y la API viven en el mismo origen, con datos de demo que puedes romper sin consecuencias. Nada de lo que envíes desde ahí sale a WhatsApp de verdad, así que es el lugar para equivocarte. Los ejemplos de esta guía funcionan igual en pruebas: cambia la URL base y ya.Autenticación
Manda la llave en la cabecera X-Api-Key. Si tu cliente HTTP te complica las cabeceras personalizadas, también se acepta como Authorization: Bearer — el prefijo ktk_ nos deja distinguirla de un token de sesión.
X-Api-Key: ktk_a1b2c3d4.tu-secreto-aqui
# o bien
Authorization: Bearer ktk_a1b2c3d4.tu-secreto-aquiTrata la llave como una contraseña
Para cambiar una llave sin cortar el servicio existe la rotación: te devuelve una llave nueva y deja la vieja funcionando durante una ventana de gracia (24 horas por omisión, hasta 7 días, o 0 para cortar de inmediato). Despliegas la nueva, verificas y la vieja muere sola.
Tu primera llamada
Lista las conversaciones abiertas. Si esto responde 200, ya estás integrado: todo lo demás es cambiar la ruta y el cuerpo.
curl -s "https://api.kontesta.app/v1/conversations?status=open&limit=30" \
-H "X-Api-Key: $KONTESTA_API_KEY"Un 401 significa que la llave no llegó o no es válida. Un 403 significa que llegó bien pero le falta el permiso — no es lo mismo, y la diferencia te ahorra media hora de depuración.
Permisos y scopes
Cada llave lleva una lista de permisos con la forma recurso:verbo — conversations:read, messages:send, leads:write. Cada endpoint exige el suyo, y la llave debe traerlo o la respuesta es 403.
Todo lo que no se concede, se niega
La consecuencia práctica: dale a cada llave el mínimo que necesita. Una integración que solo publica leads desde tu sitio no necesita conversations:read, y si algún día se filtra, no leerá las conversaciones de nadie. Es más trabajo el primer día y menos daño el peor día.
Paginación, errores y límites
Paginación
Todo listado responde con la misma forma: items (el arreglo) y nextCursor. Se pagina por cursor, no por número de página: pides limit (1 a 100, 30 por omisión) y devuelves el nextCursor en el parámetro cursor para la siguiente página; cuando viene nulo se acabó. Es un poco más incómodo que page=2, pero no se salta ni repite registros cuando entran datos nuevos mientras paginas — que en un inbox pasa todo el tiempo.
<?php
$cursor = null;
do {
$params = ['status' => 'open', 'limit' => 100];
if ($cursor !== null) {
$params['cursor'] = $cursor;
}
$url = 'https://api.kontesta.app/v1/conversations?' . http_build_query($params);
$pagina = json_decode(pedir($url), true);
foreach ($pagina['items'] as $conversacion) {
procesar($conversacion);
}
$cursor = $pagina['nextCursor'] ?? null;
} while ($cursor !== null);Errores
Todos los errores traen la misma forma. El campo requestId es el que nos sirve para rastrear qué pasó: si nos escribes por un error, mándalo.
{
"statusCode": 403,
"error": "Forbidden",
"message": "Scope insuficiente: la llave no concede [messages:send]",
"requestId": "a4898ca6-b9ba-496b-a0bf-814ee17ad7f1",
"timestamp": "2026-08-05T19:56:10.378Z",
"path": "/v1/conversations/cmrh3l84d001yxqdd992h7uwa/messages"
}| Código | Qué pasó | Qué hacer |
|---|---|---|
| 400 | El cuerpo o los parámetros no pasaron validación | Lee message: dice el campo |
| 401 | Falta la llave o no es válida | Revisa la cabecera y que la llave no esté revocada |
| 403 | La llave es válida pero le falta el permiso | Agrega el scope y rota la llave |
| 404 | El recurso no existe o no es de tu cuenta | Verifica el id |
| 409 | Choca con el estado actual | Relee el recurso antes de reintentar |
| 422 | Válido en forma, imposible en negocio | Lee message: explica la regla |
| 429 | Pasaste el límite de peticiones | Espera y reintenta con espera creciente |
| 5xx | Falla nuestra | Reintenta con espera creciente; si insiste, escríbenos con el requestId |
Límites de peticiones
Ventana de un minuto, contada por cuenta, y con cubetas separadas para lectura (GET) y escritura (el resto). Al pasarte recibes 429.
| Plan | Lecturas / min | Escrituras / min |
|---|---|---|
| Prueba | 60 | 30 |
| Emprende / Esencial | 120 | 60 |
| Crece / Pro | 240 | 120 |
| Escala / Max | 480 | 240 |
| Enterprise | 600 | 300 |
Enviar un mensaje
El caso más común. Se envía dentro de una conversación existente: el número de destino y la línea de salida se derivan de ella, así que no los mandas tú y no hay forma de equivocar el mapeo.
curl -s -X POST \
"https://api.kontesta.app/v1/conversations/cvs_abc123/messages" \
-H "X-Api-Key: $KONTESTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"kind":"text","text":"Tu pedido va en camino."}'La ventana de 24 horas es de Meta, no nuestra
kind: "template"). No es una restricción que podamos levantar: la pone Meta y la aplica su API.Webhooks
En vez de preguntar cada minuto si hay algo nuevo, das de alta una URL tuya y te avisamos. Cada entrega es un POST con el evento en el cuerpo.
curl -s -X POST "https://api.kontesta.app/v1/webhooks" \
-H "X-Api-Key: $KONTESTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://tu-sistema.com/hooks/kontesta",
"events": ["message.received", "lead.created"]
}'
# La respuesta trae el secreto de firma. Se muestra una sola vez:
# { "id": "whk_...", "secret": "whsec_...", ... }Al crear la suscripción te devolvemos un secreto que empieza con whsec_. Con él firmamos cada entrega, y ese es el único modo de saber que la petición viene de nosotros: la URL es pública, cualquiera puede llamarla.
Cabeceras de cada entrega
| Cabecera | Contenido |
|---|---|
X-Kontesta-Signature | t=<unix>,v1=<hex> |
X-Kontesta-Event-Id | Identificador del evento — úsalo para no procesar dos veces |
X-Kontesta-Event-Type | El tipo, por ejemplo message.received |
X-Kontesta-Delivery-Id | Identificador de este intento de entrega |
Verificar la firma
La firma es HMAC-SHA256 del texto {timestamp}.{cuerpo crudo} con tu secreto. Tres reglas que importan: usa el cuerpo tal como llegó (si lo parseas a objeto y lo vuelves a serializar, la firma ya no coincide), compara en tiempo constante, y rechaza lo que tenga más de 5 minutos para que nadie pueda reenviar una petición vieja.
<?php
function verificarFirma(
string $cuerpoCrudo,
?string $cabecera,
string $secreto,
int $toleranciaSeg = 300
): bool {
if ($cabecera === null) {
return false;
}
// La cabecera viene como "t=1754413462,v1=9f86d0..."
$t = null;
$v1 = null;
foreach (explode(',', $cabecera) as $parte) {
$pos = strpos($parte, '=');
if ($pos === false) {
continue;
}
$clave = trim(substr($parte, 0, $pos));
$valor = trim(substr($parte, $pos + 1));
if ($clave === 't') {
$t = $valor;
} elseif ($clave === 'v1') {
$v1 = $valor;
}
}
if ($t === null || $v1 === null) {
return false;
}
// Anti-reenvio: nada mas viejo que la tolerancia.
if (abs(time() - (int) $t) > $toleranciaSeg) {
return false;
}
$esperado = hash_hmac('sha256', $t . '.' . $cuerpoCrudo, $secreto);
// hash_equals compara en tiempo constante. NUNCA usar ===.
return hash_equals($esperado, $v1);
}
// El cuerpo CRUDO, sin parsear: si lo decodificas y lo vuelves a
// codificar, cambia un espacio y la firma ya no coincide.
$cuerpoCrudo = file_get_contents('php://input');
$cabecera = $_SERVER['HTTP_X_KONTESTA_SIGNATURE'] ?? null;
if (!verificarFirma($cuerpoCrudo, $cabecera, getenv('KONTESTA_WEBHOOK_SECRET'))) {
http_response_code(401);
exit;
}
$evento = json_decode($cuerpoCrudo, true);
// Responde 2xx rapido; el trabajo pesado va en cola.
http_response_code(200);
encolar($evento['id'], $evento['type'], $evento['data']);Responde rápido y sé idempotente
2xx en cuanto recibas y haz el trabajo pesado aparte. Si tardas o fallas, reintentamos — y eso significa que el mismo evento puede llegarte dos veces. Guarda los X-Kontesta-Event-Id que ya procesaste y descarta los repetidos.Catálogo de eventos
Al suscribirte eliges cuáles te interesan. Todos llegan con el mismo sobre: id, type, apiVersion, tenantId, occurredAt y data.
| Evento | Cuándo se dispara |
|---|---|
message.received | Entra un mensaje de un cliente |
message.status_changed | Un mensaje que enviaste cambia a entregado, leído o fallido |
conversation.assigned | La conversación se asigna a un agente |
conversation.closed | Se cierra la conversación |
handoff.requested | El bot pide pasar la conversación a una persona |
lead.created | Se crea una oportunidad |
lead.stage_changed | Una oportunidad cambia de etapa en el embudo |
appointment.created | Se agenda una cita |
appointment.updated | Se reprograma o cancela una cita |
payment.updated | Cambia el estado de una liga de pago |
review.obtained | Se obtiene una reseña |
Referencia de endpoints
Los 213 endpoints que puedes llamar con una API key, con el permiso que exige cada uno. Esta lista se genera del código, no se escribe a mano.
Conversaciones y mensajes
El inbox: listar hilos, leer y enviar mensajes, asignar.
| GET | /v1/conversations | conversations:read |
| GET | /v1/conversations/:id | conversations:read |
| PATCH | /v1/conversations/:id | conversations:write |
| GET | /v1/conversations/:id/messages | messages:read |
| POST | /v1/conversations/:id/messages | messages:send |
| POST | /v1/conversations/:id/read | conversations:write |
| POST | /v1/conversations/:id/thread/pass | conversations:write |
| POST | /v1/conversations/:id/thread/take | conversations:write |
| GET | /v1/metrics/speed-to-lead | metrics:read |
Ficha de cliente
Datos del contacto, notas, datos fiscales y fotos.
| GET | /v1/contacts/:id/photos | contacts:read |
| GET | /v1/conversations/:id/customer | contacts:read |
| GET | /v1/conversations/:id/customer/appointments | contacts:read |
| POST | /v1/conversations/:id/customer/erasure-request | contacts:write |
| GET | /v1/conversations/:id/customer/fiscal | contacts:read |
| PUT | /v1/conversations/:id/customer/fiscal | contacts:write |
| GET | /v1/conversations/:id/customer/notes | contacts:read |
| POST | /v1/conversations/:id/customer/notes | contacts:write |
| DELETE | /v1/conversations/:id/customer/notes/:noteId | contacts:write |
Leads y embudos
Tablero de oportunidades, etapas y pipelines.
| GET | /v1/leads | leads:read |
| POST | /v1/leads | leads:write |
| PATCH | /v1/leads/:id | leads:write |
| GET | /v1/leads/board | leads:read |
| GET | /v1/pipelines | pipelines:read |
| POST | /v1/pipelines/:id/stages | pipelines:write |
| DELETE | /v1/stages/:id | pipelines:write |
| PATCH | /v1/stages/:id | pipelines:write |
Tareas de seguimiento
Pendientes por contacto y “mis pendientes”.
| GET | /v1/conversations/:id/tasks | tasks:read |
| POST | /v1/conversations/:id/tasks | tasks:write |
| GET | /v1/tasks | tasks:read |
| PATCH | /v1/tasks/:id | tasks:write |
Plantillas de WhatsApp
Plantillas aprobadas por Meta para iniciar conversación.
| GET | /v1/templates | templates:read |
| POST | /v1/templates | templates:manage |
| DELETE | /v1/templates/:id | templates:manage |
| GET | /v1/templates/:id | templates:read |
Automatizaciones
Reglas, horario de atención y corridas.
| GET | /v1/automations | automations:read |
| POST | /v1/automations | automations:write |
| DELETE | /v1/automations/:id | automations:write |
| GET | /v1/automations/:id | automations:read |
| PATCH | /v1/automations/:id | automations:write |
| GET | /v1/automations/:id/runs | automations:read |
| POST | /v1/automations/:id/test | automations:write |
| GET | /v1/automations/business-hours | automations:read |
| PUT | /v1/automations/business-hours | automations:write |
| POST | /v1/conversations/:id/tags | tags:write |
| DELETE | /v1/conversations/:id/tags/:tagId | tags:write |
| GET | /v1/tags | tags:read |
| POST | /v1/tags | tags:write |
| DELETE | /v1/tags/:id | tags:write |
Respuestas guardadas
Macros del equipo para el compositor.
| GET | /v1/macros | macros:read |
| POST | /v1/macros | macros:write |
| DELETE | /v1/macros/:id | macros:write |
| GET | /v1/macros/:id | macros:read |
| PATCH | /v1/macros/:id | macros:write |
| GET | /v1/macros/variables | macros:read |
Citas y agenda
Tipos de servicio, disponibilidad, agendar y reprogramar.
| GET | /v1/appointments | appointments:read |
| POST | /v1/appointments | appointments:write |
| DELETE | /v1/appointments/:id | appointments:write |
| GET | /v1/appointments/:id | appointments:read |
| PATCH | /v1/appointments/:id | appointments:write |
| POST | /v1/appointments/:id/charge | appointments:write |
| POST | /v1/appointments/:id/complete | appointments:write |
| POST | /v1/appointments/:id/confirm | appointments:write |
| POST | /v1/appointments/:id/no-show | appointments:write |
| DELETE | /v1/appointments/:id/use-package | appointments:write |
| POST | /v1/appointments/:id/use-package | appointments:write |
| GET | /v1/appointments/availability | appointments:read |
| GET | /v1/appointments/calendar | appointments:read |
| GET | /v1/appointments/types | appointments:read |
| GET | /v1/commission-rules | commissions:read |
| POST | /v1/commission-rules | commissions:write |
| DELETE | /v1/commission-rules/:id | commissions:write |
| GET | /v1/commission-rules/:id | commissions:read |
| PATCH | /v1/commission-rules/:id | commissions:write |
| GET | /v1/commissions/overview | commissions:read |
| POST | /v1/conversations/:id/appointments | appointments:write |
| GET | /v1/reports/appointments | appointments:read |
| GET | /v1/reports/commissions | commissions:read |
Cobros
Ligas de pago dentro de la conversación.
| GET | /v1/conversations/:id/payment-links | payments:read |
| POST | /v1/conversations/:id/payment-links | payments:write |
| GET | /v1/payment-accounts | payments:read |
| POST | /v1/payment-accounts | payments:write |
| DELETE | /v1/payment-accounts/:id | payments:write |
| PATCH | /v1/payment-accounts/:id | payments:write |
| POST | /v1/payment-accounts/:id/test | payments:write |
| GET | /v1/payment-accounts/:id/webhook-url | payments:write |
| GET | /v1/payment-links | payments:read |
| GET | /v1/payment-links/:id | payments:read |
| POST | /v1/payment-links/:id/cancel | payments:write |
| GET | /v1/payments/overview | payments:read |
| GET | /v1/payments/settings | payments:read |
| PATCH | /v1/payments/settings | payments:write |
Facturación CFDI
Conexión con el PAC, series, timbrado y cancelación.
| GET | /v1/conversations/:id/invoices | invoices:read |
| POST | /v1/conversations/:id/invoices | invoices:write |
| GET | /v1/invoices | invoices:read |
| GET | /v1/invoices/:id | invoices:read |
| POST | /v1/invoices/:id/cancel | invoices:write |
| GET | /v1/invoices/:id/pdf | invoices:read |
| GET | /v1/invoices/:id/xml | invoices:read |
| GET | /v1/invoicing/connections | invoices:read |
| POST | /v1/invoicing/connections | invoices:write |
| DELETE | /v1/invoicing/connections/:id | invoices:write |
| GET | /v1/invoicing/connections/:id | invoices:read |
| PATCH | /v1/invoicing/connections/:id | invoices:write |
| POST | /v1/invoicing/connections/:id/test | invoices:write |
| GET | /v1/invoicing/emisor | invoices:read |
| POST | /v1/invoicing/emisor/csd | invoices:write |
| PUT | /v1/invoicing/emisor/fiscal | invoices:write |
| POST | /v1/invoicing/emisor/logo | invoices:write |
| GET | /v1/invoicing/series | invoices:read |
| POST | /v1/invoicing/series | invoices:write |
Catálogo y productos
Productos, inventario y envío de producto al chat.
| GET | /v1/catalog/products | catalog:read |
| POST | /v1/catalog/products | catalog:write |
| DELETE | /v1/catalog/products/:id | catalog:write |
| GET | /v1/catalog/products/:id | catalog:read |
| PATCH | /v1/catalog/products/:id | catalog:write |
| POST | /v1/catalog/products/:id/images | catalog:write |
| GET | /v1/catalog/products/:id/inventory | catalog:read |
| POST | /v1/catalog/products/:id/inventory/adjust | catalog:write |
| POST | /v1/conversations/:id/catalog/send-product | catalog:write |
Lealtad
Programas de puntos y sellos, saldo y canjes.
| GET | /v1/conversations/:id/loyalty | loyalty:read |
| POST | /v1/conversations/:id/loyalty/adjust | loyalty:write |
| POST | /v1/conversations/:id/loyalty/earn | loyalty:write |
| POST | /v1/conversations/:id/loyalty/enroll | loyalty:write |
| POST | /v1/conversations/:id/loyalty/packages | loyalty:write |
| POST | /v1/conversations/:id/loyalty/packages/sell | loyalty:write |
| POST | /v1/conversations/:id/loyalty/redeem | loyalty:write |
| POST | /v1/conversations/:id/loyalty/send-balance | loyalty:write |
| POST | /v1/conversations/:id/loyalty/send-wallet-pass | loyalty:write |
| GET | /v1/loyalty/members | loyalty:read |
| GET | /v1/loyalty/members/:id | loyalty:read |
| GET | /v1/loyalty/overview | loyalty:read |
| GET | /v1/loyalty/package-types | loyalty:read |
| POST | /v1/loyalty/package-types | loyalty:write |
| PATCH | /v1/loyalty/package-types/:id | loyalty:write |
| GET | /v1/loyalty/programs | loyalty:read |
| POST | /v1/loyalty/programs | loyalty:write |
| GET | /v1/loyalty/programs/:id | loyalty:read |
| PATCH | /v1/loyalty/programs/:id | loyalty:write |
| POST | /v1/loyalty/wallet-passes | loyalty:write |
| GET | /v1/loyalty/wallet-passes/:id | loyalty:read |
| GET | /v1/packages/overview | loyalty:read |
Reputación
Reseñas, conexiones y solicitudes de reseña.
| POST | /v1/conversations/:id/review-request | messages:send + reputation:write |
| POST | /v1/reputation/callback/:kind | reputation:write |
| GET | /v1/reputation/connect/:kind | reputation:write |
| GET | /v1/reputation/connections | reputation:read |
| DELETE | /v1/reputation/connections/:id | reputation:write |
| GET | /v1/reputation/overview | reputation:read |
| GET | /v1/reputation/reviews | reputation:read |
| PATCH | /v1/reputation/reviews/:id | reputation:write |
| POST | /v1/reputation/reviews/:id/reply | reputation:write |
| POST | /v1/reputation/sync | reputation:write |
Puntos de entrada
WALINK, QR y widget con su llave pública.
| GET | /v1/entry-points | entrypoints:read |
| POST | /v1/entry-points | entrypoints:write |
| DELETE | /v1/entry-points/:id | entrypoints:write |
| GET | /v1/entry-points/:id | entrypoints:read |
| PATCH | /v1/entry-points/:id | entrypoints:write |
| GET | /v1/entry-points/channels | entrypoints:read |
WhatsApp Flows
Formularios de captura y reserva dentro del chat.
| POST | /v1/conversations/:id/flows | flows:write |
Integraciones
Conectores salientes configurados por el tenant.
| GET | /v1/integrations | integrations:read |
| POST | /v1/integrations | integrations:write |
| DELETE | /v1/integrations/:id | integrations:write |
| GET | /v1/integrations/:id | integrations:read |
| PATCH | /v1/integrations/:id | integrations:write |
| POST | /v1/integrations/:id/test | integrations:write |
Webhooks
Suscripciones, entregas, reintentos y rotación del secreto.
| GET | /v1/webhooks | webhooks:read |
| POST | /v1/webhooks | webhooks:write |
| DELETE | /v1/webhooks/:id | webhooks:write |
| GET | /v1/webhooks/:id | webhooks:read |
| PATCH | /v1/webhooks/:id | webhooks:write |
| GET | /v1/webhooks/:id/deliveries | webhooks:read |
| POST | /v1/webhooks/:id/ping | webhooks:write |
| POST | /v1/webhooks/:id/rotate-secret | webhooks:write |
| POST | /v1/webhooks/deliveries/:id/redeliver | webhooks:write |
IA (BYOK)
Credenciales propias, ruteo, presupuesto y uso.
| GET | /v1/ai/bot-config/:channelAccountId | ai:read |
| PUT | /v1/ai/bot-config/:channelAccountId | ai:write |
| GET | /v1/ai/credentials | ai:read |
| POST | /v1/ai/credentials | ai:write |
| DELETE | /v1/ai/credentials/:id | ai:write |
| POST | /v1/ai/credentials/:id/test | ai:write |
| POST | /v1/ai/messages/:id/transcribe | ai:write |
| GET | /v1/ai/settings | ai:read |
| PUT | /v1/ai/settings | ai:write |
| GET | /v1/ai/suggest | ai:read |
| GET | /v1/ai/usage | ai:read |
| GET | /v1/conversations/:id/insight | ai:read |
| POST | /v1/conversations/:id/insight/reanalyze | ai:write |
Base de conocimiento
Fuentes del KB, ingesta y búsqueda.
| POST | /v1/rag/search | rag:read |
| GET | /v1/rag/sources | rag:read |
| POST | /v1/rag/sources | rag:write |
| DELETE | /v1/rag/sources/:id | rag:write |
| GET | /v1/rag/sources/:id | rag:read |
| POST | /v1/rag/sources/:id/reingest | rag:write |
Configuración
Ajustes del tenant expuestos a la API.
| GET | /v1/appointment-resources | appointments:read |
| POST | /v1/appointment-resources | appointments:write |
| DELETE | /v1/appointment-resources/:id | appointments:write |
| GET | /v1/appointment-resources/:id | appointments:read |
| PATCH | /v1/appointment-resources/:id | appointments:write |
| GET | /v1/appointment-types | appointments:read |
| POST | /v1/appointment-types | appointments:write |
| DELETE | /v1/appointment-types/:id | appointments:write |
| GET | /v1/appointment-types/:id | appointments:read |
| PATCH | /v1/appointment-types/:id | appointments:write |
| GET | /v1/availability-exceptions | appointments:read |
| POST | /v1/availability-exceptions | appointments:write |
| DELETE | /v1/availability-exceptions/:id | appointments:write |
| PATCH | /v1/availability-exceptions/:id | appointments:write |
| GET | /v1/availability-rules | appointments:read |
| POST | /v1/availability-rules | appointments:write |
| DELETE | /v1/availability-rules/:id | appointments:write |
| PATCH | /v1/availability-rules/:id | appointments:write |
Archivos
Descarga de adjuntos.
| GET | /v1/media/:mediaBlobId | contacts:read |
Fotos de servicio
Evidencia antes/después.
| POST | /v1/conversations/:id/photos | contacts:write |
Tiempo real
Flujo de eventos por Server-Sent Events.
| GET | /v1/inbox/stream | conversations:read |
SDK de TypeScript
Si trabajas en Node o TypeScript hay un cliente tipado que te ahorra armar las peticiones a mano y trae la verificación de webhooks ya resuelta. Cubre conversaciones, leads, pipelines, automatizaciones, etiquetas, plantillas, métricas, webhooks e integraciones.
Todavía no está en npm
npm i @kontesta/sdk todavía no funciona. Mientras tanto, integra con peticiones HTTP directas como en los ejemplos de arriba — el contrato es el mismo y no vas a tener que reescribir nada cuando salga. Si lo quieres antes, escríbenos.import { Kontesta } from '@kontesta/sdk';
const k = new Kontesta({ apiKey: process.env.KONTESTA_API_KEY! });
// Una página
const { items, nextCursor } = await k.conversations.list({
status: 'open',
limit: 30,
});
// …o todas, sin escribir el bucle del cursor
for await (const c of k.conversations.iterate({ status: 'open' })) {
console.log(c.id);
}Para cualquier otro lenguaje no hace falta SDK: son peticiones HTTP con una cabecera, como los ejemplos de PHP, C# y Python de esta página. Si prefieres generar un cliente tipado en tu lenguaje, publicamos el archivo OpenAPI del que sale el nuestro — pídelo al abrir tu cuenta.