---
updatedAt: 2026-03-24T22:30:34.000Z
agentTools:
  projectIndex: https://developer.bill.com/llms.txt
---

# Test with BILL webhook security

In this section, we walk through the steps for validating the BILL webhook security measures.

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.

## Generate test notification URL

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>. In the rest of this article, we refer to a <Anchor label="webhook.site" target="_blank" href="https://webhook.site">webhook.site</Anchor> test notification URL.

## Create test subscription

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

Create a test subscription for the `bill.created` event with `POST /v3/subscriptions`.

### Sample request

In your request, set the required fields (`name`, `status`, `events`, and `notificationUrl`). Set `notificationUrl` as the generated notification URL in the previous step.

```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": "Created bills",
  "status": {
    "enabled": true
  },
  "events": [{
    "type": "bill.created",
    "version": "1"
  }],
  "notificationUrl": "https://webhook.site/{unique_id}"
}'
```

### Response

In the response, a BILL-generated subscription `id` is available. The `organizationId` represents the BILL organization for which your subscription is created. In addition, the one-time generated `securityKey` is available.

```json
{
  "id": "{subscription_id}",
  "name": "Created bills",
  "organizationId": "{organization_id}",
  "status": {
    "enabled": true,
    "actor": "CLIENT"
  },
  "events": [{
    "type": "bill.created",
    "version": "1"
  }],
  "notificationUrl": "https://webhook.site/{unique_id}",
  "createdTime": "2026-12-10T23:25:27.127+00:00",
  "securityKey": "{security_key}"
}
```

## Generate test event notification

Generate a test event notification with `POST /v3/subscriptions/{subscriptionId}/test` request. 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": "625947c4-8e6b-48f0-ae72-ea9c9375ec27",
    "type": "test",
    "version": "1",
    "subscriptionId": "f6d06930-e3e2-4509-be37-4dbda29efc6i",
    "payload": "{\"metadata\":{\"eventId\":\"963507c4-8e6b-48f0-ae72-ea9c9371qw369\",
        \"subscriptionId\":\"y2c96930-e3e2-4509-be37-4dbda29ews9q\",\"organizationId\":\"00802DEVKGROHKDIY4zyx\",
        \"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
}
```

On the <Anchor label="webhook.site" target="_blank" href="https://webhook.site">webhook.site</Anchor> page, you see response header and body details of the test event notification.

* Under **Request Details & Headers**, the `x-bill-sha-signature` value is the hash generated by BILL for the `payload` JSON value.
* Under **Request Content**, the `payload` JSON value is available. In the next step, we use the unformatted (minified) version of the `payload` JSON value.

### What does the unformatted (minified) version look like?

For the above `payload` value, the unformatted (minified) JSON does not have any new lines, tabs, spaces, or special characters for formatting.

```json Unformatted (minified) JSON
{"metadata":{"eventId":"963507c4-8e6b-48f0-ae72-ea9c9371qw369","subscriptionId":"y2c96930-e3e2-4509-be37-4dbda29ews9q","organizationId":"00802DEVKGROHKDIY4zyx","eventType":"test","version":"1"},"payload":{"createdDate":"2026-12-15T23:15:27.127+00:00"}}
```

## Generate hash with the payload value

In our testing, we use an <Anchor label="online tool" target="_blank" href="https://www.devglan.com/online-tools/hmac-sha256-online">online tool</Anchor> for generating a hash with the `payload` value from the earlier step. Using this tool, enter the required information and click **Compute**.

| Information                            | Details                                                                               |
| :------------------------------------- | :------------------------------------------------------------------------------------ |
| **Enter Plain Text to Compute Hash**   | Enter the unformatted (minified) version of the `payload` value from the earlier step |
| **Enter the Secret Key**               | Enter the `securityKey` value from the subscription response                          |
| **Select Cryptographic Hash Function** | Select **SHA-256**                                                                    |
| **Output Text Format**                 | Select **Base64**                                                                     |

If the **Hashed Output** value matches the `x-bill-sha-signature` value, this confirms that BILL was the source of the event notification.

## Update your security key

> ❗️ This step is critical
>
> This step is critical. After using your security key for testing with any online tool, generate a new security key for your subscription with `POST /v3/subscriptions/{subscriptionId}/security-key`.