Gestión de canales
Una vez que conectaste un canal (WhatsApp Embedded Signup o Instagram Business
Login OAuth desde el dashboard), la superficie /platform/v1/channels/{id}/*
te deja operarlo programáticamente: revisar su salud, editar el perfil de
empresa, bloquear usuarios, registrar el PIN de 2FA y prender/apagar el
procesamiento de inbound.
Distinto de conectar/desconectar. La conexión y la desconexión de un canal viven en el dashboard (cookie-only, bajo
/platform/dashboard/channels/*). Esta sección cubre las operaciones sobre un canal que ya existe.
Todas las rutas /platform/v1/channels/{id}/* requieren manage:channels.
El scope es accesible desde una API key (server-to-server) o desde una sesión
cookie del dashboard.
WhatsApp-only (con una excepción)
Section titled “WhatsApp-only (con una excepción)”Todas las operaciones que llaman a Meta son solo para WhatsApp. Si llamás
con el id de un canal de Instagram, recibís un 400 limpio antes de
cualquier llamada a Meta (sin tocar Meta):
{ "error": "wa_only", "message": "Esta operación solo está disponible en canales de WhatsApp.", "type": "health"}La única excepción es PATCH /{id}/inbound (el kill-switch): es un cambio
de columna local, no llama a Meta, y funciona tanto en WhatsApp como en
Instagram.
Códigos de error comunes
Section titled “Códigos de error comunes”| Código | Trigger |
|---|---|
400 wa_only | Operación Meta sobre un canal de Instagram. |
404 | El canal no existe o no es tuyo (respuesta opaca, no se puede enumerar). |
501 display_name_submit_not_supported | POST /{id}/display-name (ver abajo). |
502 channel_token_unavailable | El canal no tiene un token válido. Reconectalo. |
502 meta_send_failed | Meta devolvió un error (envelope estructurado de 6 claves {error, meta_code, meta_subcode, meta_title, message, fbtrace_id}). |
GET /{id}/health: salud del canal
Section titled “GET /{id}/health: salud del canal”Devuelve un diagnóstico que combina la consulta en vivo a Meta del nodo
del número (health_status, quality_rating, messaging_limit_tier,
name_status, code_verification_status, verified_name,
display_phone_number) con el snapshot cacheado en DB (lo que escribió el
webhook de calidad), más dos booleanos derivados de operatividad:
{ "live": { "health_status": { "can_send_message": "AVAILABLE" }, "quality_rating": "GREEN", "...": "..." }, "cached": { "quality_rating": "GREEN", "messaging_limit_tier": "TIER_1K", "quality_updated_at": "..." }, "webhook_configured": true, "token_present": true, "status": "active", "inbound_enabled": true}El token nunca se devuelve.
token_presentes un booleano: la salud te dice si el token desencripta, no cuál es.
GET / POST /{id}/profile: perfil de empresa
Section titled “GET / POST /{id}/profile: perfil de empresa”Leé o actualizá el perfil de empresa de WhatsApp (about / address / description / email / websites / vertical / profile_picture).
POST solo envía los campos que mandás (los omitidos quedan sin cambios).
Los límites de Meta se validan en el servidor antes de llamar a Meta (422
si te pasás):
| Campo | Límite |
|---|---|
about | ≤ 139 |
address | ≤ 256 |
description | ≤ 256 |
email | ≤ 128 |
websites | ≤ 2 entradas |
vertical | enum de Meta |
profile_picture_handle | de un upload resumable |
curl -X POST https://api.kalipto.app/platform/v1/channels/34/profile \ -H "X-API-Key: $KALIPTO_KEY" -H "Content-Type: application/json" \ -d '{"about":"Pizzería del barrio","description":"Pedí tu pizza por WhatsApp"}'GET / POST /{id}/display-name: display name
Section titled “GET / POST /{id}/display-name: display name”-
GET /{id}/display-name: devuelvename_status+verified_name. Te sirve para pollear el estado de revisión de tu display name. Esta lectura funciona y tiene valor por sí sola. -
POST /{id}/display-name: devuelve 501display_name_submit_not_supported.{"error": "display_name_submit_not_supported","message": "Meta no expone un endpoint estable de Cloud API para solicitar un nuevo display name. La gestión del display name se realiza desde Business Manager; el estado se lee con GET /display-name."}Meta enruta la aprobación inicial del display name a través de Business Manager; no hay un endpoint estable de Cloud API para enviar un display name nuevo. Usá Business Manager para el submit inicial y
GET /display-namepara pollear el resultado. (Si Meta publica un endpoint estable más adelante, esta ruta lo implementará y dejará de devolver 501.)
POST / DELETE /{id}/block-users: bloquear / desbloquear
Section titled “POST / DELETE /{id}/block-users: bloquear / desbloquear”Bloqueá o desbloqueá hasta 64 usuarios de WhatsApp por llamada. El body es el mismo en ambos casos:
{ "users": ["59891234567", "59899876543"] }- Bloquear →
POST /{id}/block-users. - Desbloquear →
DELETE /{id}/block-users(HTTP DELETE con body JSON: Meta expone bloqueo y desbloqueo en el mismo endpoint/block_users; no esPOST /unblock_users).
# desbloquear (HTTP DELETE con body)curl -X DELETE https://api.kalipto.app/platform/v1/channels/34/block-users \ -H "X-API-Key: $KALIPTO_KEY" -H "Content-Type: application/json" \ -d '{"users":["59891234567"]}'POST /{id}/two-factor: registrar el PIN de 2FA
Section titled “POST /{id}/two-factor: registrar el PIN de 2FA”Registrá el PIN de verificación en dos pasos del canal con Meta. El PIN se
valida con el patrón ^[0-9]{6}$ (exactamente 6 dígitos; 422 si no cumple)
antes de la llamada.
curl -X POST https://api.kalipto.app/platform/v1/channels/34/two-factor \ -H "X-API-Key: $KALIPTO_KEY" -H "Content-Type: application/json" \ -d '{"pin":"123456"}'# → {"status":"set"}El PIN nunca se loguea ni se devuelve. La respuesta es un fijo
{"status":"set"}; el echo de Meta se descarta deliberadamente.
PATCH /{id}/inbound: kill-switch de inbound
Section titled “PATCH /{id}/inbound: kill-switch de inbound”Prendé o apagá el procesamiento de mensajes entrantes para el canal. Es la única ruta que funciona en WhatsApp y Instagram (no llama a Meta: es un toggle de una columna local).
curl -X PATCH https://api.kalipto.app/platform/v1/channels/34/inbound \ -H "X-API-Key: $KALIPTO_KEY" -H "Content-Type: application/json" \ -d '{"inbound_enabled":false}'# → {"channel_id":34,"inbound_enabled":false}| Valor | Efecto |
|---|---|
true (default) | Reenvío + persistencia del inbound (comportamiento normal). |
false | El inbound del canal se descarta silenciosamente: no se reenvía a tu webhook, no se persiste en el data plane, no cuenta para el metering. El canal sigue conectado y enviando; solo el inbound queda en pausa. |
El toggle se lee fresco en cada delivery, así que un cambio toma efecto en el próximo mensaje entrante. Útil para mantenimiento de tu receptor o para pausar un canal sin desconectarlo.
Próximo paso
Section titled “Próximo paso”- Webhook entrante (forward): cómo recibís el
inbound mientras
inbound_enabled = true. - Webhooks normalizados: eventos tipados,
incluyendo
channel.connected/channel.disconnected.