Skip to content
Agent Orchestration
Skill

/kapso-whatsapp

How to interact with Kapso WhatsApp from the swarm — read inbound webhook payloads (text AND media), fetch message history, send free-form messages within the 24h session window (and template messages outside it), mark-as-read, show the typing indicator, send reactions, download

BOOST
From plugin
agent-swarm
88016 skills5 agents11 commands
Install
$ npx -y skills add desplega-ai/agent-swarm --skill kapso-whatsapp --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/kapso-whatsapp

Context preview

The summary Claude sees to decide when to auto-load this skill.

How to interact with Kapso WhatsApp from the swarm — read inbound webhook payloads (text AND media), fetch message history, send free-form messages within the 24h session window (and template messages outside it), mark-as-read, show the typing indicator, send reactions, download

SKILL.md

kapso-whatsapp.SKILL.md
name: kapso-whatsapp
description: How to interact with Kapso WhatsApp from the swarm — read inbound webhook payloads (text AND media), fetch message history, send free-form messages within the 24h session window (and template messages outside it), mark-as-read, show the typing indicator, send reactions, download media, verify webhook signatures, and resolve contacts to swarm users. Canonical reference for ANY Kapso interaction beyond the thin `send-whatsapp-message` / `reply-whatsapp-message` MCP tools — for templates, media, reactions, typing, mark-as-read, signature verify, contact resolution, conversation history, drop to the REST recipes here. Use whenever a task references a WhatsApp message routed through Kapso, or when a workflow needs to reply on WhatsApp.
user-invocable: false

Kapso WhatsApp

Kapso (https://kapso.ai) is a WhatsApp platform vendor that fronts the Meta Cloud API. A swarm provisions one or more WhatsApp phone numbers and wires each one to either the native inbound handler or a workflow that dispatches a task per inbound message.

When to use MCP tools vs this skill's REST recipes

The integration ships **thin MCP-tool wrappers for the common case only**:

| Tool | Use for | |---|---| | `send-whatsapp-message` | Free-form text within the 24h session window. | | `reply-whatsapp-message` | Same as above but quote-threads to an inbound WAMID. | | `register-kapso-number` / `unregister-kapso-number` | Provisioning a phone number's webhook + KV mapping. |

**For ANYTHING else, drop to the REST recipes in this skill** — these are the canonical reference, and the MCP tools deliberately do NOT duplicate them:

  • **Template messages** (outside 24h window) → §"Send a template" below.
  • **Media** (image / document / audio / video, including wide-image padding and PTT voice notes) → §"Sending media".
  • **Reactions** (👀 / ✅ / clear) → §"Send a reaction".
  • **Typing indicator + mark-as-read** → §"Mark as read + typing indicator".
  • **Signature verify (manual)** → §"Webhook signature verification".
  • **Contact resolution → swarm user** → §"Resolve a contact to a swarm user".
  • **Conversation history / message detail / templates list** → §"Read conversation context".

If the MCP-tool send returns a 24h-window error (`sessionWindowExpired: true`), fall through to the template path in §"Send a template" — this is exactly what the tool's structured-error points at.

Setup

Swarm config keys (resolve with `get-config key:<NAME> includeSecrets:true` — Lead-only for secrets; workers should ask Lead if they need a value injected):

| Key | Value | |---|---| | `KAPSO_API_BASE_URL` | `https://api.kapso.ai` (host only, no `/platform/v1`) | | `KAPSO_API_KEY` | API key (`X-API-Key` header) | | `KAPSO_PHONE_NUMBER_ID` | The swarm's provisioned number's Meta phone-number ID | | `KAPSO_WEBHOOK_HMAC_SECRET` | Shared HMAC secret. Kapso signs every webhook request with `X-Webhook-Signature: <hex>` |

The curl recipes below assume `$API_BASE`, `$API_KEY`, and `$PHONE_NUMBER_ID` are set in your shell. `get-config` is an MCP tool, not a shell command — call it as a tool first, then export the values it returns:

# Values from the `get-config` MCP tool (key:<NAME> includeSecrets:true):
API_BASE=https://api.kapso.ai        # KAPSO_API_BASE_URL
API_KEY=<value of KAPSO_API_KEY>
PHONE_NUMBER_ID=<value of KAPSO_PHONE_NUMBER_ID>

The Kapso CLI is NOT installed in worker containers. Use direct HTTP or clone the `gokapso/agent-skills` repo for fallback scripts.

git clone --depth=1 https://github.com/gokapso/agent-skills /tmp/kapso-skills
cd /tmp/kapso-skills/skills/integrate-whatsapp && npm i  # or observe-whatsapp / automate-whatsapp

The Meta Cloud API is proxied at `$API_BASE/meta/whatsapp/v24.0/...` (auth: `X-API-Key`). Kapso's own platform endpoints live at `$API_BASE/platform/v1/...`.

Inbound webhook payload (v2)

When inbound events are routed through a workflow, the workflow's webhook trigger receives `whatsapp.message.*` and `whatsapp.conversation.*` events at `POST https://<your-swarm-host>/api/webhooks/<workflow-id>`.

Shape (top-level keys):

{
  "message": {
    "id": "wamid.HBgL...",            // Meta message id (WAMID)
    "from": "15551234567",            // E.164 without + (sender)
    "from_user_id": "XX.00000...",    // Meta-internal user id
    "timestamp": "1700000000",        // unix seconds (string)
    "type": "text",                   // text | image | audio | video | document | sticker | location | contacts | reaction | ...
    "text": { "body": "hi" },         // only for type=text
    "context": null,                  // present when the user quote-replied another message
    "kapso": {
      "direction": "inbound|outbound",
      "status": "received|delivered|read|sent|failed",
      "processing_status": "pending|completed",
      "origin": "cloud_api",
      "has_media": false,
      "content": "hi"                 // text representation (caption / filename / body)
    }
  },
  "conversation": {
    "id": "<conversation-uuid>",
    "phone_number": "15551234567",
    "phone_number_id": "<PHONE_NUMBER_ID>",
    "contact_name": "Jane Doe",
    "status": "active",
    "last_active_at": "...",
    "created_at": "...",
    "kapso": {
      "messages_count": 10,
      "last_message_id": "wamid...",
      "last_message_text": "hi",
      "last_inbound_at": "...",
      "last_outbound_at": "..."
    }
  },
  "is_new_conversation": false,
  "phone_number_id": "<PHONE_NUMBER_ID>"
}

**ALWAYS filter on `message.kapso.direction == "inbound"`** — Kapso fires the webhook for the swarm's own outbound sends, deliveries, reads, and failures too. Only inbound events from real humans warrant a task.

Test payloads include `"test": true` and `wamid.TEST_...` ids — handle gracefully (treat as a real inbound but mark it test in your reply; do not send a real WhatsApp reply to test payloads).

Non-text message types

`message.type` can be `text

Read more
Ships withagent-swarm

Your Company Agentic Operating System

Get the whole plugin

Other skills on agent-swarm.