---
updatedAt: 2026-05-06T19:54:19.000Z
---

Fetch the complete documentation index at: https://developer.bill.com/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Webhook Events & Subscriptions

When you set up a subscription for your choice of BILL events, you receive real time event notifications when those events are triggered.

> 👍 Organization-level users vs Partner users
>
> For organization-level users, BILL sends event notifications only for the BILL organization used to set up a subscription. When a subscription is set up, the `organizationId` in the API response represents the BILL organization for which the subscription is created.
>
> When a partner user creates a subscription for events, BILL sends event notifications for all organizations created by the partner user.

## Subscribe to BILL events

BILL provides a catalog of all the events that you can subscribe to with `GET /v3/events/catalog`. See the <Anchor label="GET /v3/events/catalog" target="_blank" href="ref:geteventcatalog">GET /v3/events/catalog</Anchor> API for more information.

To create a subscription with `POST /v3/subscriptions`, set the required fields.

> ❗️ Subscription limits
>
> You can create up to 10 webhook subscriptions per organization. In addition, BILL does not allow duplicate subscriptions for the same set of events and same notification URL.

<Table align={["left","left"]}>
  <thead>
    <tr>
      <th>
        Field
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `name`
      </td>

      <td>
        Subscription name
      </td>
    </tr>

    <tr>
      <td>
        `status`
      </td>

      <td>
        Subscription status information. Set `enabled` as `true` for keeping the subscription enabled. You can use the field to disable the subscription at a later time.

        When an event notification fails, BILL tries to send the notification again with exponential backoff. When BILL does not receive a HTTP 200 `statusCode` after resending a notification even after exponential backoff, BILL sets the subscription `enabled` status as `false` and stops sending any notifications.

        The `enabled` status stays as `false` until the problem is resolved at your end and until the `enabled` status is set as `true` again.
      </td>
    </tr>

    <tr>
      <td>
        `events`
      </td>

      <td>
        In the `events` array, add events that you can subscribe to.

        * **`type`**: Event name
        * **`version`**: Event versionYou can get the full catalog of all events that you can subscribe to with `GET /v3/events/catalog`.
      </td>
    </tr>

    <tr>
      <td>
        `notificationUrl`
      </td>

      <td>
        The location where you receive event notifications. The URL that you provide must be HTTPS.
      </td>
    </tr>
  </tbody>
</Table>

> 👍 Create a subscription at the Partner level
>
> To create a subscription at the partner level, simply set your partner `sessionId` (with `POST /v3/partner/login`) and `appKey` as the required header values. The base URL and body parameters in the `POST /v3/subscriptions` request are the same for partner users and organization users.

### Sample request

In this cURL example, a subscription is created for the `bill.created`, `bank.updated`, and `bill.archived` events. The required `X-Idempotent-Key`, `devKey`, and `sessionId` header values are set. A `notificationUrl` is set as the location URL for you to receive event notifications when any of the subscribed events is triggered.

> 👍 Use an online service for setting up a notification URL
>
> When you are testing with BILL webhooks, you can use an online service for generating a test notification URL. For example, <Anchor label="webhook.site" target="_blank" href="https://webhook.site">webhook.site</Anchor> or  <Anchor label="pipedream.com/requestbin" target="_blank" href="https://pipedream.com/requestbin">pipedream.com/requestbin</Anchor>.

```curl
curl --request POST \
--url 'https://gateway.stage.bill.com/connect-events/v3/subscriptions' \
--header 'content-type: application/json' \
--header 'X-Idempotent-Key: {UUID4_key}' \
--header 'devKey: {developer_key}' \
--header 'sessionId: {session_id}' \
--data '{
  "name": "Bill management",
  "status": {
    "enabled": true
  },
  "events": [{
    "type": "bill.created",
    "version": "1"
  },
  {
    "type": "bill.updated",
    "version": "1"
  },
  {
    "type": "bill.archived",
    "version": "1"
  }],
  "notificationUrl": "https://example.com/billmanagement"
}'
```

### Response

In the response, a BILL-generated subscription `id` is available. The `organizationId` represents the BILL organization for which your subscription is created. BILL sends you event notifications only for the BILL organization used to set up this subscription.

```json
{
  "id": "{subscription_id}",
  "name": "Bill management",
  "organizationId": "{organization_id}",
  "status": {
    "enabled": true,
    "actor": "CLIENT"
  },
  "events": [{
    "type": "bill.created",
    "version": "1"
  },
  {
    "type": "bill.updated",
    "version": "1"
  },
  {
    "type": "bill.archived",
    "version": "1"
  }],
  "notificationUrl": "https://example.com/billmanagement",
  "createdTime": "2026-12-10T23:25:27.127+00:00",
  "securityKey": "{security_key}"
}
```

When you create a new subscription, a one-time `securityKey` is one of the generated values in the response. BILL uses the HMAC-SHA256 algorithm to sign all event notifications sent to your `notificationUrl` with the `securityKey`. The output format of the generated hash value is `base64`.

The generated hash is sent as the `x-bill-sha-signature` header value with all event notifications. With this value, you can verify that each notification sent to you is from BILL. See <Anchor label="Test with BILL webhook security" target="_blank" href="doc:test-with-webhook-security">Test with BILL webhook security</Anchor> for more information.

> 👍 Security key best practice
>
> Keep the security key for your subscription updated in a timely manner. Generate a new security key for your subscription with `POST /v3/subscriptions/{subscriptionId}/security-key`.

See the <Anchor label="/v3/subscriptions" target="_blank" href="ref:createsubscription">/v3/subscriptions</Anchor> API for the complete list of available operations.

### Subscribe to Spend & Expense API events

When you are subscribing to the BILL Spend & Expense API events,  your `POST /v3/subscriptions` API request must include the `apiToken` header value for authentication.

```curl
curl --request POST \
--url 'https://gateway.stage.bill.com/connect-events/v3/subscriptions' \
--header 'content-type: application/json' \
--header 'X-Idempotent-Key: {UUID4_key}' \
--header 'apiToken: {api_token}' \
--data '{
  "name": "Bill management",
  "status": {
    "enabled": true
  },
  "events": [{
    "type": "spend.transaction.updated",
    "version": "1"
  }],
  "notificationUrl": "https://example.com/billmanagement"
}'
```

## Generate a test event notification

When you set up a subscription, you can generate a test event with `POST /v3/subscriptions/{subscriptionId}/test`. Use this endpoint to confirm whether the your subscription and notifications workflow has been successfully set up. BILL sends you a test event notification to the specified notification URL.

In your request, all the fields are optional. To see specific information in the test event notification, you can set `eventType`, `version`, and any details. You can get the BILL events catalog with `GET /v3/events/catalog`.

### Sample response

In this response example, a test event notification is available. The JSON-escaped `payload` is presented as a string. You will receive such a response with you do not set any of the optional values in your `POST /v3/subscriptions/{subscriptionId}/test` request.

```json
{
    "id": "{event_id}",
    "type": "test",
    "version": "1",
    "subscriptionId": "{subscription_id}",
    "payload": "{\"metadata\":{\"eventId\":\"{event_id}\",
        \"subscriptionId\":\"{subscription_id}\",\"organizationId\":\"{organization_id}\",
        \"eventType\":\"test\",\"version\":\"1\"},
        \"payload\":{\"createdDate\":\"2026-12-15T23:15:27.127+00:00\"}}",
    "createdTime": "2026-12-15T23:15:27.127+00:00",
    "statusCode": 200
}
```

> ❗️ Important
>
> All the fields in the test event notification are test values. You cannot use any of the test values for any other operation.

## Get events for a subscription

You can get the list of event notifications sent to you for a subscription with `GET /v3/events/subscription/{subscription_id}`.

> 👍 Resend a specific event
>
> You can also resend a specific event with `POST /v3/events/subscription/{subscriptionId}/event/{eventId}`.

### Sample response

In this response example, an array of event objects are available along with a BILL-generated event `id`. Each event object represents the notification that BILL sends to your `notificationUrl` when the event is triggered. The JSON-escaped `payload` of each event notification is presented as a string.

```json Array of events
[
   {
      "id": "{event_id1}",
      "type": "bill.created",
      "version": "1",
      "subscriptionId": "{subscription_id}",
      "payload": "{\"metadata\": {\"eventId\": \"{event_id1}\",
          \"subscriptionId\": \"{subsrciption_id}\", \"organizationId\": \"{organization_id}\",
          \"eventType\": \"bill.created\", \"version\": \"1\"}, \"bill\": {\"id\": \"{bill_id1}\",
          \"vendorId\": \"{vendor_id}\", \"invoiceNumber\": \"202601\",
          \"invoiceDate\": \"2026-12-16T00:00:00.127+00:00\", \"amount\": 228.99,
          \"createdDate\": \"2026-12-15T23:15:23.127+00:00\", \"archived\": false}}"
      "createdTime": "2026-12-15T23:15:27.127+00:00",
      "statusCode": 200
   },
   {
      "id": "{event_id2}",
      "type": "bill.created",
      "version": "1",
      "subscriptionId": "{subscription_id}",
      "payload": "{\"metadata\": {\"eventId\": \"{event_id2}\",
          \"subscriptionId\": \"{subsrciption_id}\", \"organizationId\": \"{organization_id}\",
          \"eventType\": \"bill.created\", \"version\": \"1\"}, \"bill\": {\"id\": \"{bill_id2}\",
          \"vendorId\": \"{vendor_id}\", \"invoiceNumber\": \"202602\",
          \"invoiceDate\": \"2026-12-16T00:00:00.127+00:00\", \"amount\": 149,
          \"createdDate\": \"2026-12-15T23:17:31.127+00:00\", \"archived\": false}}"
      "createdTime": "2026-12-15T23:17:35.127+00:00",
      "statusCode": 200
   }
]
```

> 👍 HTTP 200 `statusCode`
>
> The HTTP 200 `statusCode` informs BILL that the event notification was successfully sent to your `notificationUrl`.