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

# Partner webhooks

> One endpoint receives every customer's events.

Subscribe once and every customer, current and future, sends its events to your one URL, signed with one secret. Each event names the customer it's about.

> [!NOTE]
>
> **Partner accounts only.** These calls need a partner key, without the `Blujay-Workspace` header.

## Subscribe once

Use an `admin` key. Pick the [events](https://docs.blujay.io/webhooks/events.md) you want.

```bash curl theme={null}
curl -X POST https://api.blujay.io/v1/partner/webhook-subscriptions \
  -H "Authorization: Bearer blu_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/blujay",
    "event_types": ["message.received", "message.delivered", "message.failed", "customer.created"]
  }'
```

```javascript Node.js theme={null}
const response = await fetch("https://api.blujay.io/v1/partner/webhook-subscriptions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BLUJAY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://hooks.example.com/blujay",
    event_types: ["message.received", "message.delivered", "message.failed", "customer.created"],
  }),
});
const subscription = (await response.json()).data;
console.log(subscription.subscription_id, subscription.signing_secret);
```

```python Python theme={null}
import os
import requests

response = requests.post(
    "https://api.blujay.io/v1/partner/webhook-subscriptions",
    headers={"Authorization": f"Bearer {os.environ['BLUJAY_API_KEY']}"},
    json={
        "url": "https://hooks.example.com/blujay",
        "event_types": ["message.received", "message.delivered", "message.failed", "customer.created"],
    },
    timeout=60,
)
subscription = response.json()["data"]
print(subscription["subscription_id"], subscription["signing_secret"])
```

```json 201 Created theme={null}
{
  "status": "success",
  "data": {
    "subscription_id": "whsub_abc123",
    "url": "https://hooks.example.com/blujay",
    "event_types": ["message.received", "message.delivered", "message.failed", "customer.created"],
    "webhook_version": "2026-10-30",
    "status": "active",
    "signing_secret": "whsec_ZXhhbXBsZS1zZWNyZXQtZG8tbm90LXVzZS0xMjM0NTY3OA==",
    "signing_secret_hint": "Y3OA==",
    "created_at": "2026-10-28T17:00:00.000Z",
    "updated_at": "2026-10-28T17:00:00.000Z"
  },
  "trace_id": "trc_8f2a1c0e4b7d",
  "timestamp": "2026-10-28T17:00:00.000Z"
}
```

Save `signing_secret` now; it's shown only once. [Verify each delivery](https://docs.blujay.io/webhooks/verify-signatures.md) with it. Full reference: [Create a partner webhook subscription](https://docs.blujay.io/api-reference/partners/create-a-partner-webhook-subscription).

## Tell customers apart

Every event carries `workspace_id`: the same customer ID you send in `Blujay-Workspace`. Route on it.

```json message.received (shortened) theme={null}
{
  "api_version": "v1",
  "webhook_version": "2026-10-03",
  "event_type": "message.received",
  "event_id": "evt_abc123",
  "created_at": "2026-10-28T17:05:00.120Z",
  "workspace_id": "workspace_abc123",
  "subscription_id": "whsub_abc123",
  "data": {
    "message_id": "msg_def456",
    "chat_id": "chat_abc123",
    "phone_number_id": "phone_abc123",
    "text": "Sounds good, see you then!",
    "direction": "inbound",
    "service": "imessage"
  }
}
```

The full payload for each event is on [Webhook events](https://docs.blujay.io/webhooks/events.md).

## Customer events

| Event | When |
| - | - |
| `customer.created` | You created a customer. |
| `customer.paused` | A customer was paused. |
| `customer.closed` | A customer started closing. Its data can still be read. |

These are about the customer itself: `workspace_id` is your own partner workspace and `data.customer_id` names the customer. Every other event type is sent for every customer.

## See and replay deliveries

One delivery log covers all your customers, newest first. Narrow it with `customer_id` or `event_id`.

```bash curl theme={null}
curl "https://api.blujay.io/v1/partner/webhook-subscriptions/whsub_abc123/deliveries?customer_id=workspace_abc123" \
  -H "Authorization: Bearer blu_your_api_key"
```

Replay any customer's event, keeping its `event_id`:

```bash curl theme={null}
curl -X POST https://api.blujay.io/v1/partner/webhook-subscriptions/whsub_abc123/events/evt_abc123/replay \
  -H "Authorization: Bearer blu_your_api_key"
```

## Good to know

* **Changes apply to every customer at once.** Updating the URL or events, disabling, deleting, and rotating the secret all reach every customer together.
* **Rotating switches secrets at once.** Blujay signs with the new secret as soon as `POST .../rotate-secret` returns it, so have your endpoint accept both until the new one is deployed.
* **Your own workspace's subscriptions stay yours.** Ones made with `/v1/webhook-subscriptions` never receive customers' events.

## Next steps

> [card] [Webhook events](https://docs.blujay.io/webhooks/events.md)
>
> Every event type and its payload.

> [card] [Embedded view](https://docs.blujay.io/partners/embedded-view)
>
> Show a customer's texts inside your product.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.