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

# Webhooks

> WhatsApp webhook integration for Agent-TS

# WhatsApp Webhooks

Agent-TS is Kapso-first for WhatsApp messaging. It keeps a compatibility webhook for external client testing, but production traffic should use Kapso / Meta webhooks.

## Endpoints

### Compatibility Webhook

`POST /api/v1/external/whatsapp`

For local testing or temporary bridge scenarios.

### Meta Business API Webhook

`GET /api/v1/webhooks/whatsapp` - Verification
`POST /api/v1/webhooks/whatsapp` - Message handling

For Meta's official WhatsApp Business API.

## External Client Integration

### Text Message Payload

```json theme={null}
{
  "event": "message",
  "message": "What is my balance?",
  "from": "23279648205@c.us",
  "phoneE164": "+23279648205"
}
```

### Image Message Payload

```json theme={null}
{
  "event": "message",
  "messageType": "image",
  "hasMedia": true,
  "phoneE164": "+23279372497",
  "message": "Here is my ID",
  "media": {
    "data": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
    "mimetype": "image/jpeg",
    "filename": "id_card_front.jpg",
    "size": 52643
  }
}
```

<Warning>
  The `media.data` field **must** include the data URI prefix (`data:image/jpeg;base64,`).
</Warning>

### Response Format

```json theme={null}
{
  "answer": "Your balance is 5,000 SLE",
  "status": "success"
}
```

## Kapso-first messaging

Kapso is the supported WhatsApp transport for:

* free-text conversations
* interactive list menus
* reply buttons for confirmations and navigation
* WhatsApp Flows for structured data capture and PIN/auth steps
* template messages from internal services when approved by WhatsApp

## Meta WhatsApp Business API

### Webhook Verification

Meta sends a GET request to verify your webhook:

```
GET /api/v1/webhooks/whatsapp?hub.mode=subscribe&hub.verify_token=YOUR_TOKEN&hub.challenge=CHALLENGE
```

The agent responds with the challenge if the verify token matches `WHATSAPP_VERIFY_TOKEN`.

### Incoming Message Payload

```json theme={null}
{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "WHATSAPP_BUSINESS_ACCOUNT_ID",
    "changes": [{
      "value": {
        "messaging_product": "whatsapp",
        "metadata": {
          "display_phone_number": "15551234567",
          "phone_number_id": "PHONE_NUMBER_ID"
        },
        "contacts": [{
          "profile": { "name": "John Doe" },
          "wa_id": "23279648205"
        }],
        "messages": [{
          "from": "23279648205",
          "id": "wamid.xxx",
          "timestamp": "1234567890",
          "type": "text",
          "text": { "body": "What is my balance?" }
        }]
      }
    }]
  }]
}
```

### Meta Developer Console Setup

1. Go to [Meta for Developers](https://developers.facebook.com/)
2. Create or select your app
3. Add WhatsApp product
4. Configure webhook URL: `https://your-domain.com/api/v1/webhooks/whatsapp`
5. Set verify token: Same as `WHATSAPP_VERIFY_TOKEN`
6. Subscribe to `messages` webhook field

## Payload Fields Reference

| Field            | Type    | Required | Description                      |
| ---------------- | ------- | -------- | -------------------------------- |
| `event`          | string  | Yes      | Event type (always "message")    |
| `from`           | string  | Yes      | Sender identifier                |
| `phoneE164`      | string  | Yes      | Phone in E.164 format            |
| `message`        | string  | No       | Text message content             |
| `messageType`    | string  | No       | Message type (text, image, etc.) |
| `hasMedia`       | boolean | No       | Whether message has media        |
| `media`          | object  | No       | Media data (if hasMedia)         |
| `media.data`     | string  | No       | Base64 with data URI prefix      |
| `media.mimetype` | string  | No       | MIME type                        |
| `media.filename` | string  | No       | Original filename                |
| `media.size`     | number  | No       | File size in bytes               |

## Error Responses

### Validation Error

```json theme={null}
{
  "error": "Missing required field: phoneE164",
  "status": "error"
}
```

### Agent Error

```json theme={null}
{
  "error": "Internal agent error",
  "status": "error"
}
```

### Rate Limited

```json theme={null}
{
  "error": "Too many requests",
  "status": "error",
  "retryAfter": 60
}
```

## Health Check

Verify the agent is running:

```bash theme={null}
curl http://localhost:8000/health
```

Response:

```json theme={null}
{
  "status": "healthy",
  "service": "olive-agent",
  "version": "1.0.0",
  "activeConversations": 5
}
```

## Testing

### Test Compatibility Text Message

```bash theme={null}
curl -X POST http://localhost:8000/api/v1/external/whatsapp \
  -H "Content-Type: application/json" \
  -d '{
    "event": "message",
    "message": "what is my balance?",
    "from": "23279648205@c.us",
    "phoneE164": "+23279648205"
  }'
```

### Test Compatibility Transfer

```bash theme={null}
curl -X POST http://localhost:8000/api/v1/external/whatsapp \
  -H "Content-Type: application/json" \
  -d '{
    "event": "message",
    "message": "send 5000 to CARD0001",
    "from": "23279648205@c.us",
    "phoneE164": "+23279648205"
  }'
```

## Security Considerations

<AccordionGroup>
  <Accordion title="Input Sanitization">
    All incoming messages are sanitized to prevent injection attacks.
  </Accordion>

  <Accordion title="Rate Limiting">
    30 requests per minute per phone number by default.
  </Accordion>

  <Accordion title="Webhook Verification">
    Meta webhooks are verified using the configured verify token.
  </Accordion>

  <Accordion title="HTTPS Required">
    Production webhook endpoints must use HTTPS.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Configuration" icon="gear" href="/agent-ts/configuration">
    Environment variable setup
  </Card>

  <Card title="KYC Validation" icon="shield-check" href="/agent-ts/kyc-validation">
    Image processing details
  </Card>
</CardGroup>
