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

# Webhook

> Set up a webhook so your agent can receive incoming texts, calls, and form responses.

Poku needs a public URL to forward inbound events to your agent. How you set this up depends on where your agent is running.

***

## Step 1: Get a public URL

### Option A — Local machine (via ngrok)

If your agent is running on your local machine, use ngrok to create a public tunnel.

1. Create an account at [ngrok.com](https://ngrok.com).

2. After logging in, follow the installation instructions for your operating system. On macOS you can install via Homebrew:

   ```bash theme={null}
   brew install ngrok
   ```

3. Grab your authtoken from the [ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken) and authenticate:

   ```bash theme={null}
   ngrok config add-authtoken <your-token>
   ```

4. Start a tunnel pointed at the port your agent is listening on:

   ```bash theme={null}
   ngrok http <your-agent-port>
   ```

   ngrok will output a forwarding URL:

   ```
   Forwarding https://abc123.ngrok-free.app -> http://localhost:<your-agent-port>
   ```

   Copy this URL — you'll need it in Step 3.

***

### Option B — VPS (no ngrok needed)

If your agent is hosted on a VPS, it's already on the public internet — no tunnel required.

**Recommended:** Set up HTTPS using a reverse proxy such as nginx or Caddy with a free Let's Encrypt certificate. This gives you a clean, secure URL:

```
https://yourdomain.com
```

If you are not using a reverse proxy, open the port your agent is running on in your cloud provider's security group or firewall dashboard. Your webhook URL will be:

```
http://YOUR_VPS_IP:<your-agent-port>
```

***

## Step 2: Configure your agent

Set up your agent to accept incoming `POST` requests at your chosen path. Poku sends a JSON body for each event. All events share the same wrapper:

```json theme={null}
{
  "eventType": "<event-type>",
  "payload": { ... }
}
```

### `message.received`

Fired when an inbound SMS, WhatsApp, or Slack message is received on your number or workspace.

```json theme={null}
{
  "eventType": "message.received",
  "payload": {
    "interactionId": "ia_abc123",
    "medium": "sms",
    "from": "+14155550199",
    "to": "+14155550100",
    "body": "Hey, are you available tomorrow?",
    "mediaUrls": []
  }
}
```

| Field                   | Type       | Description                                                   |
| ----------------------- | ---------- | ------------------------------------------------------------- |
| `payload.interactionId` | string?    | Present when the message is a reply to a Poku interaction     |
| `payload.medium`        | string     | Channel the message arrived on: `sms`, `whatsapp`, or `slack` |
| `payload.from`          | string     | Sender's phone number or Slack ID                             |
| `payload.to`            | string     | Your Poku number or Slack channel that received the message   |
| `payload.body`          | string     | Text content of the message                                   |
| `payload.mediaUrls`     | string\[]? | Media attachments, if any (MMS)                               |

***

### `form.received`

Fired when a recipient submits a form sent via SMS or WhatsApp.

```json theme={null}
{
  "eventType": "form.received",
  "payload": {
    "interactionId": "ia_abc123",
    "values": {
      "email": "johnsmith@gmail.com",
      "phone": "+14155550199"
    }
  }
}
```

| Field                   | Type   | Description                                |
| ----------------------- | ------ | ------------------------------------------ |
| `payload.interactionId` | string | ID of the interaction the form belongs to  |
| `payload.values`        | object | Key-value map of the submitted form fields |

***

### `call.conversation.ended`

Fired when an outbound call completes.

```json theme={null}
{
  "eventType": "call.conversation.ended",
  "payload": {
    "interactionId": "ia_abc123",
    "summary": "Caller confirmed their appointment for tomorrow at 3pm.",
    "from": "+14155550199",
    "to": "+14155550100"
  }
}
```

| Field                   | Type   | Description                              |
| ----------------------- | ------ | ---------------------------------------- |
| `payload.interactionId` | string | ID of the call interaction               |
| `payload.summary`       | string | AI-generated summary of the conversation |
| `payload.from`          | string | Phone number that placed the call        |
| `payload.to`            | string | Phone number that received the call      |

***

Using OpenClaw? See the [OpenClaw installation guide](/poku-skill/openclaw) for the `openclaw.json` webhook config.

***

## Step 3: Register your webhook with Poku

Register your public URL from Step 1 with Poku so events get forwarded to your agent. Specify which event types you want to receive:

```bash theme={null}
curl -X POST "https://api.pokulabs.com/webhooks" \
  -H "Authorization: Bearer <your-poku-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "<your-webhook-url>",
    "eventTypes": ["message.received", "form.received", "call.conversation.ended"]
  }'
```

If your agent requires an authorization header on incoming requests, include it via the optional `headers` field:

```bash theme={null}
curl -X POST "https://api.pokulabs.com/webhooks" \
  -H "Authorization: Bearer <your-poku-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "<your-webhook-url>",
    "eventTypes": ["message.received", "form.received", "call.conversation.ended"],
    "headers": {"Authorization": "Bearer <your-agent-token>"}
  }'
```

See the [Create Webhook](/api-reference/webhooks/create-webhook) API reference for all available parameters.

***

## Verify your webhook

You can check which webhooks are currently registered on your account:

```bash theme={null}
curl -X GET https://api.pokulabs.com/webhooks \
  -H 'Authorization: Bearer <your-poku-api-key>'
```

See the [List Webhooks](/api-reference/webhooks/list-webhooks) API reference for the full response schema.

***

## Delete your webhook

```bash theme={null}
curl -X DELETE "https://api.pokulabs.com/webhooks/<webhook-id>" \
  -H "Authorization: Bearer <your-poku-api-key>"
```

See the [Delete Webhook](/api-reference/webhooks/delete-webhook) API reference for details.
