Autenticación
La Kalipto Devs Platform usa API keys con scopes atadas a tu cuenta de desarrollador. Las keys se generan desde el dashboard en Cuenta → API keys (no se exponen por la API).
Header
Section titled “Header”Todas las peticiones autenticadas usan:
X-API-Key: <plaintext_key>Flujo del resolver
Section titled “Flujo del resolver”- SHA-256 del texto plano:
key_hash = hashlib.sha256(x_api_key.encode()).hexdigest(). - Búsqueda en
platform_api_keysconkey_hash = ? AND is_active = TRUE. - Si
expires_atestá seteado y ya pasó, devuelve 401. - Rate limit Redis sliding-window por key (por defecto 60 por minuto,
configurable vía
rate_limit_per_minute). El budget es separado del rate limit de v1/v2. Tu key no comparte cupo con keys de otros namespaces. - Se actualiza
last_used_atdespués del check de rate limit (las peticiones bloqueadas por rate limit NO cuentan para el uso).
DeveloperContextno llevabusiness_id: la plataforma es un sistema independiente del backend managed.
Códigos de error de la capa de autenticación
Section titled “Códigos de error de la capa de autenticación”| Código | Trigger |
|---|---|
401 Unauthorized | Key ausente / inválida / inactiva / expirada |
403 Forbidden | Key válida pero le falta el scope que el endpoint requiere |
429 Too Many Requests | Rate limit excedido para esta key |
Scopes (v1)
Section titled “Scopes (v1)”Once scopes forman el vocabulario, todos LIVE: send:messages,
manage:templates, upload:media, read:messages, read:conversations,
read:contacts, manage:data, manage:webhooks, manage:channels (WF8),
send:broadcasts (WF9) y read:channels (v399). El resto del
control-plane (cuenta, billing, gestión de keys, y la conexión/onboarding de
canales) vive bajo /platform/dashboard/* y es cookie-only (lo consume
el dashboard web) — ojo que manage:channels (WF8) habilita las
operaciones sobre un canal ya conectado (health, perfil, bloqueo, 2FA,
kill-switch de inbound), distinto de la conexión/desconexión que es
cookie-only.
read:channelsno es lo mismo quemanage:channels. Una key conmanage:channelspero sinread:channelsrecibe 403 enGET /platform/v1/channels. Son scopes independientes: uno lista, el otro opera.Si tu key fue creada antes de esta versión, NO tiene
read:channelsautomáticamente — el scope no se otorga retroactivamente a keys existentes. Si tu integración necesita listar canales por API, creá una key nueva marcandoread:channels. El texto plano se muestra una sola vez, igual que con cualquier key.
| Scope | ¿Accesible desde API key? | Endpoint | Descripción |
|---|---|---|---|
send:messages | Sí | POST /platform/v1/messages + POST /platform/v1/messages/mark-read | Enviar mensajes (13 tipos) por un canal de tu cuenta y emitir read receipts. |
manage:templates | Sí | /platform/v1/templates/* (7 rutas post-WF6) | CRUD de templates de WhatsApp + submit a Meta + edición + sync desde Meta + subida resumable de header media. Cubre la superficie completa de componentes Meta (HEADER text/media/location, BODY positional/NAMED, FOOTER, BUTTONS incl. OTP, CAROUSEL, categoría authentication). Ver Templates. |
upload:media | Sí | POST /platform/v1/media + GET /platform/v1/media/{id}/url + DELETE /platform/v1/media/{id} | Subir, consultar URL temporal y borrar binarios en Meta. |
read:messages | Sí (solo lectura) | GET /platform/v1/messages + GET /platform/v1/messages/{id} | Consultar el historial de mensajes persistidos. Solo lectura — no permite mutar nada. Ver Data plane. |
read:conversations | Sí (solo lectura) | GET /platform/v1/conversations + GET /platform/v1/conversations/{id} | Consultar conversaciones. Solo lectura — para cerrar una conversación necesitás manage:data. |
read:contacts | Sí (solo lectura) | GET /platform/v1/contacts + GET /platform/v1/contacts/{id} | Consultar la lista de contactos por canal. Solo lectura — para editar o borrar un contacto necesitás manage:data. |
manage:data | Sí (mutación) | PATCH /platform/v1/conversations/{id} + PATCH /platform/v1/contacts/{id} + DELETE /platform/v1/contacts/{id} | Mutar filas del data plane: cerrar conversaciones, editar metadata de contactos, borrar contactos con cascada asíncrona. Independiente de los read:* — una key con read:contacts puede consultar pero NUNCA borrar. |
manage:webhooks (WF7 — LIVE) | Sí (key o cookie) | /platform/v1/webhooks/subscriptions/* (CRUD + rotate-secret + resume + test) + /platform/v1/webhooks/deliveries/* (observabilidad — mode=kalipto|meta) | Gestionar suscripciones a eventos normalizados de Kalipto. Crear / listar / editar / borrar suscripciones, rotar el HMAC secret, reanudar una suscripción auto-pausada, lanzar un evento de prueba firmado, y observar entregas en ambos modos (kalipto = eventos normalizados, meta = forward crudo). Ver Webhooks normalizados. |
manage:channels (WF8 — LIVE) | Sí (key o cookie) | /platform/v1/channels/{id}/{health,profile,display-name,block-users,two-factor,inbound} (9 rutas) | Operar un canal ya conectado: probar la salud (health), leer/actualizar el perfil de empresa, leer el estado del display name (el submit devuelve 501 — Meta lo gestiona desde Business Manager), bloquear/desbloquear usuarios, registrar el PIN de 2FA, y prender/apagar el procesamiento de inbound (kill-switch). Todas WhatsApp-only salvo PATCH /inbound (sirve para WA e IG). Distinto de la conexión/desconexión del canal, que es cookie-only bajo /platform/dashboard/channels/*. Ver Gestión de canales. |
send:broadcasts (WF9 — LIVE) | Sí (key o cookie) | /platform/v1/broadcasts/* (8 rutas) | Campañas masivas basadas en templates (WhatsApp-only): crear borrador, cargar hasta 1000 destinatarios por llamada, agendar / cancelar / enviar, y leer métricas por destinatario. Caps por plan (broadcast_recipients_limit / broadcasts_per_month) — el plan free está deshabilitado (403). Ver Broadcasts. |
read:channels (v399 — LIVE) | Sí (SOLO key, sin cookie) | GET /platform/v1/channels | Listar los canales de tu cuenta — el channel_id que toda otra ruta de /platform/v1/* requiere. Newest-first, [] si no tenés canales, nunca devuelve material de token. No otorgado retroactivamente a keys existentes. |
Separación lectura ↔ mutación: las rutas
PATCHyDELETEdel data plane NO se habilitan con un scoperead:*. Necesitás explícitamentemanage:data. Esto preserva el modelo de seguridad: una key de solo-lectura filtrada NO puede borrar contactos ni cerrar conversaciones. Si tu integración solo necesita leer, dejala conread:*y dormís tranquilo.
Los scopes se eligen al crear la key. Por defecto el formulario viene con TODOS los scopes disponibles tildados (decisión de producto WF v321-A) — destildás los que tu integración NO necesite, en lugar de sumar opt-in desde cero.
API key vs cookie JWT
Section titled “API key vs cookie JWT”X-API-Key: para integraciones backend (server-to-server, scripts, cron jobs). Es el modo recomendado para producción. Las rutas accesibles por key sonPOST /platform/v1/messages,POST /platform/v1/messages/mark-read,/platform/v1/media/*,/platform/v1/templates/*, el Data plane (GET /platform/v1/messages*,GET/PATCH /platform/v1/conversations*,GET/PATCH/DELETE /platform/v1/contacts*),/platform/v1/webhooks/*(WF7),/platform/v1/channels/{id}/*de gestión de canal (WF8),/platform/v1/broadcasts/*(WF9), yGET /platform/v1/channelspara descubrimiento de canales (v399, SOLO key, sin cookie).- Cookie JWT (
access_token_dev): para el dashboard web. Cubre el resto del control-plane (cuenta, canales, billing, gestión de keys) bajo/platform/dashboard/*. Si estás usando solo el dashboard, no necesitás API keys.
Ambos mecanismos coexisten en /platform/v1/templates/* (esa es la única
ruta cross-method de control-plane). El resto del control-plane
(cuenta, canales, billing, gestión de keys) es cookie-only.
Próximo paso
Section titled “Próximo paso”- Quickstart: registrar cuenta, conectar un canal, generar key y enviar el primer mensaje.