> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zelto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Kapso (WhatsApp)

> Connect a Kapso project and bring the WhatsApp conversations your agents handle into Zelto — no audio, no upload code.

[Kapso](https://kapso.ai) is WhatsApp for developers: your agent gets a WhatsApp
number, and Kapso delivers each message to it (through a Kapso Workflow or your
own webhook) and stores the conversation. Zelto connects to the same project and
turns those conversations into [conversations](/docs/conversations) you can
review, run [monitors](/docs/monitors) over, and surface [findings](/docs/findings)
from — exactly like a voice call, minus the recording.

## Connect

1. Open **Settings → Integrations → Kapso** and click **Connect Kapso**.
2. Paste your Kapso **project API key**. Create one in your Kapso project's
   settings under **API Keys**. Zelto uses it to list your WhatsApp numbers,
   read conversations, and register its webhook.

You can connect multiple Kapso projects to one organization.

## Import your numbers

In Kapso, an agent speaks as a **WhatsApp phone number**, so in Zelto each
imported number is an [agent](/docs/agents). Import from **Agents → Add Agent →
Kapso**, or from the **Get started** connect step, which lists every number in
the project with its recent conversation volume.

Importing a number does three things:

* **Registers Zelto's webhook on the number** in Kapso, subscribed to the
  `whatsapp.conversation.inactive` and `whatsapp.conversation.ended` events with a
  60-minute inactivity window. Nothing to paste.
* **Backfills** the conversations active in the last 30 days (or the last 2000,
  whichever is smaller) from the onboarding picker, 14 days from the Agents page.
* **Reads the agent's prompt** when the number is answered by a Kapso Workflow:
  Zelto follows the workflow bound to the number and stores its `agent` node's
  system prompt on the Zelto agent. Numbers answered by an external agent (your
  own server behind a Kapso webhook) import without a prompt — Kapso has none to
  give.

## How a WhatsApp thread becomes conversations

A Kapso conversation is one contact's whole thread with your number. It lives
until someone closes it by hand, so it is not the right unit to analyze: a repeat
customer would be one endless transcript.

Zelto instead splits each thread into **sessions** — bursts of messages with no
gap of 60 minutes or more inside them — and stores **one Zelto conversation per
session**. A session is ingested once it has been quiet for the gap (that is
exactly when Kapso fires `whatsapp.conversation.inactive`) or when the thread is
ended. Inbound messages are the customer's turns; outbound messages are the
agent's. Images, documents, locations, interactive replies and audio (using
Kapso's transcript) render as bracketed turns.

<Note>
  Kapso does not record whether an outbound message came from the AI, a human in
  the Kapso inbox, or your API. Zelto attributes every outbound turn to the agent.
  If a human took the conversation over, their replies read as agent turns.
</Note>

Sessions shorter than four turns are stored but not analyzed, the same rule
voice calls follow.

## Delivery paths

* **Webhook (primary)** — the session-closed events above. Kapso signs each
  delivery with the shared secret shown under **Manage**; Zelto verifies it and
  only accepts events for numbers you imported.
* **Hourly sync (safety net)** — every imported number is re-read on the hour for
  threads active since the last sync, so a paused or missed webhook is caught
  within the hour. The two paths dedupe on the session, so nothing lands twice.

### Registering the webhook by hand

If Zelto could not register the webhook (for example a key without webhook
permissions), open **Settings → Integrations → Kapso → Manage** and create the
webhook in Kapso yourself:

* **URL** — the webhook URL shown on the card.
* **Secret** — the webhook secret shown on the card, pasted as `secret_key`.
* **Events** — `whatsapp.conversation.inactive` and `whatsapp.conversation.ended`.
* **Inactivity window** — 60 minutes, so Kapso's idea of "quiet" matches Zelto's
  session boundary.

## Verify the first conversation

Message your WhatsApp number, exchange a few turns, then wait for the quiet
period to pass. The session appears in [Conversations](/docs/conversations) with
the Kapso badge on its agent. Until then, the agent's **Connections** card shows
the last webhook Kapso delivered and flags a rejected one — a `401` almost
always means the secret on the Kapso webhook doesn't match the one on the card.

## Connection status & disconnecting

The card lists the connected projects, the webhook URL and the shared secret.
**Disconnect** removes the stored API key and, best-effort, the webhooks Zelto
registered on your numbers with that key; already-ingested conversations are kept.

## Related

* [Chatbot & text conversations](/docs/integrations/chatbot-text-conversations) — the generic upload path for text agents on other platforms.
* [Conversations](/docs/conversations) — where WhatsApp sessions land.
* [Agents](/docs/agents) — how Zelto models each number.
* [Findings](/docs/findings) — what analysis surfaces from each session.
