Connect WhatsApp to your product with Kapso: onboard customers with setup links, detect connections, receive events via webhooks, and send messages/templates/media. Also manage WhatsApp Flows (create/update/publish, data endpoints, encryption). Use when integrating WhatsApp end-to-end.
npx skills add https://github.com/gokapso/agent-skills --skill integrate-whatsapp
Preferred path:
kapso login)kapso status to confirm project access before onboarding or messagingFallback path:
Env vars:
KAPSO_API_BASE_URL (host only, no /platform/v1)KAPSO_API_KEYMETA_GRAPH_VERSION (optional, default v24.0)Auth header (direct API calls):
X-API-Key: <api_key>
Install deps (once):
npm i
Preferred onboarding path (CLI):
kapso setupkapso projects listkapso projects use <project-id>kapso customers listkapso customers new --name "<customer-name>" --external-id <external-id>kapso setup --customer <customer-id>kapso whatsapp numbers list --output jsonkapso whatsapp numbers resolve --phone-number "<display-number>" --output jsonFallback onboarding flow (direct API):
POST /platform/v1/customersPOST /platform/v1/customers/:id/setup_linksphone_number_id to send messages and configure webhooksDetect connection:
whatsapp.phone_number.created (recommended)Recommended Kapso setup-link defaults:
{
"setup_link": {
"allowed_connection_types": ["dedicated"],
"provision_phone_number": true,
"phone_number_country_isos": ["US"]
}
}
Notes:
kapso setup and kapso whatsapp numbers new use dedicated plus provisioning by default.phone_number_country_isos, phone_number_area_code, language, and redirect URLs as optional overrides./platform/v1/meta/whatsapp/v24.0 (messaging, templates, media)phone_number_id as the primary WhatsApp identifierUse webhooks to receive:
Scope rules:
phone_number_idwhatsapp.message.*, whatsapp.conversation.*) are phone-number onlyCreate a webhook:
node scripts/create.js --scope project --url <https://...> --events <csv>node scripts/create.js --phone-number-id <id> --url <https://...> --events <csv>Common flags for create/update:
--url <https://...> - webhook destination--events <csv|json-array> - event types (Kapso webhooks)--kind <kapso|meta> - Kapso (event-based) vs raw Meta forwarding--payload-version <v1|v2> - payload format (v2 recommended)--buffer-enabled <true|false> - enable buffering for whatsapp.message.received--buffer-window-seconds <n> - 1-60 seconds--max-buffer-size <n> - 1-100--active <true|false> - enable/disableTest delivery:
node scripts/test.js --webhook-id <id>
Always verify signatures. See:
references/webhooks-overview.mdreferences/webhooks-reference.mdTwo Meta IDs are needed for different operations:
| ID | Used for | How to discover |
|----|----------|-----------------|
| business_account_id (WABA) | Template CRUD | kapso whatsapp numbers resolve --phone-number "<display-number>" --output json or node scripts/list-platform-phone-numbers.mjs |
| phone_number_id | Sending messages, media upload | kapso whatsapp numbers resolve --phone-number "<display-number>" --output json or node scripts/list-platform-phone-numbers.mjs |
Common commands:
kapso whatsapp numbers list --output json
kapso whatsapp numbers resolve --phone-number "<display-number>" --output json
kapso whatsapp messages send --phone-number-id <PHONE_NUMBER_ID> --to <wa-id> --text "Hello from Kapso"
kapso whatsapp messages list --phone-number-id <PHONE_NUMBER_ID> --limit 50 --output json
kapso whatsapp messages get <MESSAGE_ID> --phone-number-id <PHONE_NUMBER_ID> --output json
kapso whatsapp conversations list --phone-number-id <PHONE_NUMBER_ID> --output json
kapso whatsapp templates list --phone-number-id <PHONE_NUMBER_ID> --output json
kapso whatsapp templates get <TEMPLATE_ID> --phone-number-id <PHONE_NUMBER_ID> --output json
Install:
npm install @kapso/whatsapp-cloud-api
Create client:
import { WhatsAppClient } from "@kapso/whatsapp-cloud-api";
const client = new WhatsAppClient({
baseUrl: "https://api.kapso.ai/meta/whatsapp",
kapsoApiKey: process.env.KAPSO_API_KEY!
});
Via SDK:
await client.messages.sendText({
phoneNumberId: "<PHONE_NUMBER_ID>",
to: "+15551234567",
body: "Hello from Kapso"
});
node scripts/list-platform-phone-numbers.mjsassets/template-utility-order-status-update.jsonnode scripts/create-template.mjs --business-account-id <WABA_ID> --file <payload.json>node scripts/template-status.mjs --business-account-id <WABA_ID> --name <name>node scripts/send-template.mjs --phone-number-id <ID> --file <send-payload.json>Interactive messages require an active 24-hour session window. For outbound notifications outside the window, use templates.
phone_number_idassets/send-interactive-*.jsonnode scripts/send-interactive.mjs --phone-number-id <ID> --file <payload.json>For a contact information request, use interactive.type: "request_contact_info" with action.name: "request_contact_info". Include body, but omit header and footer.
Preferred path:
kapso whatsapp messages ..., kapso whatsapp conversations ..., kapso whatsapp templates ...Fallback path:
GET /{phone_number_id}/messages, GET /{phone_number_id}/conversationsclient.messages.query(), client.messages.get(), client.conversations.list(), client.conversations.get(), client.templates.get()Use Platform API inbox embeds when the user wants to place Kapso's inbox inside their own app.
Create:
POST /platform/v1/inbox_embedsinbox_embedproject, customer, phone_numberscope_id is blank for project, a customer UUID for customer, and WhatsApp phone_number_id for phone_numberlanguage controls the embedded inbox UI language; supported values are en and estoken and embed_url once. Store embed_url; list/get/update omit secrets.Example:
{
"inbox_embed": {
"name": "Support inbox",
"scope_type": "phone_number",
"scope_id": "1234567890",
"allowed_origins": ["https://app.example.com"],
"default_mode": "system",
"language": "es"
}
}
Manage:
GET /platform/v1/inbox_embedsGET /platform/v1/inbox_embeds/:idPATCH /platform/v1/inbox_embeds/:idDELETE /platform/v1/inbox_embeds/:id (revokes)Creation:
parameter_format: "NAMED" with {{param_name}} (preferred over positional)language (not language_code){{1}}REQUEST_CONTACT_INFO button, omit text; WhatsApp supplies the labelSend-time:
parameter_name in header/body paramsbutton component with sub_type: "url" and indexid or link (never both)Use Flows to build native WhatsApp forms. Read references/whatsapp-flows-spec.md before editing Flow JSON.
node scripts/create-flow.js --phone-number-id <id> --name <name>node scripts/update-flow-json.js --flow-id <id> --json-file <path>node scripts/publish-flow.js --flow-id <id>node scripts/send-test-flow.js --phone-number-id <id> --flow-id <id> --to <phone>node scripts/setup-encryption.js --flow-id <id>node scripts/set-data-endpoint.js --flow-id <id> --code-file <path>node scripts/deploy-data-endpoint.js --flow-id <id>node scripts/register-data-endpoint.js --flow-id <id>Static flows (no data endpoint):
version: "7.3"routing_model and data_api_version are optionalassets/sample-flow.jsonDynamic flows (with data endpoint):
version: "7.3" with data_api_version: "3.0"routing_model is required (defines valid screen transitions)assets/dynamic-flow.jsonHandler signature:
async function handler(request, env) {
const body = await request.json();
// body.data_exchange.action: INIT | data_exchange | BACK
// body.data_exchange.screen: current screen id
// body.data_exchange.data: user inputs
return Response.json({
version: "3.0",
screen: "NEXT_SCREEN_ID",
data: { }
});
}
export or module.exportsscreen: "SUCCESS" with extension_message_response.paramsendpoint_uri or data_channel_uri (Kapso injects these)kapso logs search --query "<wamid-flow-id-request-id-or-endpoint>" --period 7d --source all --limit 20 --output json"flow_token is missing": flow is dynamic without a data endpoint. Attach one and refresh.| Script | Purpose |
|--------|---------|
| list.js | List webhooks |
| get.js | Get webhook details |
| create.js | Create a webhook |
| update.js | Update a webhook |
| delete.js | Delete a webhook |
| test.js | Send a test event |
| Script | Purpose | Required ID |
|--------|---------|-------------|
| list-platform-phone-numbers.mjs | Discover business_account_id + phone_number_id | — |
| list-connected-numbers.mjs | List WABA phone numbers | business_account_id |
| list-templates.mjs | List templates (with filters) | business_account_id |
| template-status.mjs | Check single template status | business_account_id |
| create-template.mjs | Create a template | business_account_id |
| update-template.mjs | Update existing template | business_account_id |
| send-template.mjs | Send template message | phone_number_id |
| send-interactive.mjs | Send interactive message | phone_number_id |
| upload-media.mjs | Upload media for send-time headers | phone_number_id |
| Script | Purpose |
|--------|---------|
| list-flows.js | List all flows |
| create-flow.js | Create a new flow |
| get-flow.js | Get flow details |
| read-flow-json.js | Read flow JSON |
| update-flow-json.js | Update flow JSON (creates new version) |
| publish-flow.js | Publish a flow |
| get-data-endpoint.js | Get data endpoint config |
| set-data-endpoint.js | Create/update data endpoint code |
| deploy-data-endpoint.js | Deploy data endpoint |
| register-data-endpoint.js | Register data endpoint with Meta |
| get-encryption-status.js | Check encryption status |
| setup-encryption.js | Set up flow encryption |
| send-test-flow.js | Send a test flow message |
| delete-flow.js | Delete a flow |
| list-flow-responses.js | List stored flow responses |
| list-function-logs.js | List function logs |
| list-function-invocations.js | List function invocations |
| Script | Purpose |
|--------|---------|
| openapi-explore.mjs | Explore OpenAPI (search/op/schema/where) |
Examples:
node scripts/openapi-explore.mjs --spec whatsapp search "template"
node scripts/openapi-explore.mjs --spec whatsapp op sendMessage
node scripts/openapi-explore.mjs --spec whatsapp schema TemplateMessage
node scripts/openapi-explore.mjs --spec platform ops --tag "WhatsApp Flows"
node scripts/openapi-explore.mjs --spec platform op setupWhatsappFlowEncryption
node scripts/openapi-explore.mjs --spec platform search "setup link"
| File | Description |
|------|-------------|
| template-utility-order-status-update.json | UTILITY template with named params + URL button |
| send-template-order-status-update.json | Send-time payload for order_status_update |
| template-utility-named.json | UTILITY template showing button ordering rules |
| template-marketing-media-header.json | MARKETING template with IMAGE header |
| template-authentication-otp.json | AUTHENTICATION OTP template (COPY_CODE) |
| send-interactive-buttons.json | Interactive button message |
| send-interactive-list.json | Interactive list message |
| send-interactive-cta-url.json | Interactive CTA URL message |
| send-interactive-location-request.json | Location request message |
| send-interactive-catalog-message.json | Catalog message |
| sample-flow.json | Static flow example (no endpoint) |
| dynamic-flow.json | Dynamic flow example (with endpoint) |
| webhooks-example.json | Webhook create/update payload example |
automate-whatsapp - Workflows, agents, and automationsobserve-whatsapp - Debugging, logs, health checks<!-- FILEMAP:BEGIN -->
[integrate-whatsapp file map]|root: .
|.:{package.json,SKILL.md}
|assets:{dynamic-flow.json,sample-flow.json,send-interactive-buttons.json,send-interactive-catalog-message.json,send-interactive-cta-url.json,send-interactive-list.json,send-interactive-location-request.json,send-template-order-status-update.json,template-authentication-otp.json,template-marketing-media-header.json,template-utility-named.json,template-utility-order-status-update.json,webhooks-example.json}
|references:{detecting-whatsapp-connection.md,getting-started.md,platform-api-reference.md,setup-links.md,templates-reference.md,webhooks-event-types.md,webhooks-overview.md,webhooks-reference.md,whatsapp-api-reference.md,whatsapp-cloud-api-js.md,whatsapp-flows-spec.md}
|scripts:{create-flow.js,create-function.js,create-template.mjs,create.js,delete-flow.js,delete.js,deploy-data-endpoint.js,deploy-function.js,get-data-endpoint.js,get-encryption-status.js,get-flow.js,get-function.js,get.js,list-connected-numbers.mjs,list-flow-responses.js,list-flows.js,list-function-invocations.js,list-function-logs.js,list-platform-phone-numbers.mjs,list-templates.mjs,list.js,openapi-explore.mjs,publish-flow.js,read-flow-json.js,register-data-endpoint.js,send-interactive.mjs,send-template.mjs,send-test-flow.js,set-data-endpoint.js,setup-encryption.js,submit-template.mjs,template-status.mjs,test.js,update-flow-json.js,update-function.js,update-template.mjs,update.js,upload-media.mjs,upload-template-header-handle.mjs}
|scripts/lib:{args.mjs,cli.js,env.js,env.mjs,http.js,output.js,output.mjs,request.mjs,run.js,whatsapp-flow.js}
|scripts/lib/webhooks:{args.js,kapso-api.js,webhook.js}
<!-- FILEMAP:END -->
Expert in secure backend coding practices specializing in input validation, authentication, and API security. Use PROACTIVELY for backend security implementations or security code reviews.
This skill should be used when the user asks to "perform cloud penetration testing", "assess Azure or AWS or GCP security", "enumerate cloud resources", "exploit cloud misconfigurations", "test O365 security", "extract secrets from cloud environments", or "audit cloud infrastructure". It provides comprehensive techniques for security assessment across major cloud platforms.
You are a dependency security expert specializing in vulnerability scanning, license compliance, and supply chain security. Analyze project dependencies for known vulnerabilities, licensing issues, outdated packages, and provide actionable remediation strategies.
Comprehensive Flow Nexus platform management - authentication, sandboxes, app deployment, payments, and challenges
This skill should be used when the user asks to "escalate privileges on Linux", "find privesc vectors on Linux systems", "exploit sudo misconfigurations", "abuse SUID binaries", "exploit cron jobs for root access", "enumerate Linux systems for privilege escalation", or "gain root access from low-privilege shell". It provides comprehensive techniques for identifying and exploiting privilege escalation paths on Linux systems.
Expert malware analyst specializing in defensive malware research, threat intelligence, and incident response. Masters sandbox analysis, behavioral analysis, and malware family identification. Handles static/dynamic analysis, unpacking, and IOC extraction. Use PROACTIVELY for malware triage, threat hunting, incident response, or security research.
This skill should be used when the user asks to "use Metasploit for penetration testing", "exploit vulnerabilities with msfconsole", "create payloads with msfvenom", "perform post-exploitation", "use auxiliary modules for scanning", or "develop custom exploits". It provides comprehensive guidance for leveraging the Metasploit Framework in security assessments.
Expert in secure mobile coding practices specializing in input validation, WebView security, and mobile-specific security patterns. Use PROACTIVELY for mobile security implementations or mobile security code reviews.
Take gokapso/integrate-whatsapp from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm.
Without those the skill loads but fails at the first command.