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

# Target usage events to a specific subscription

> Route usage events to the right subscription when a customer has several subscriptions billing the same usage-based products, using per-subscription metering filters.

By default, a usage-based product counts every event of its [aggregator](https://docs.hyperline.co/docs/usage/aggregators.md) sent for the customer. When a customer has **several subscriptions with the same usage-based products**, each subscription would count the same events, and the usage would be billed several times.

To bill each subscription only for its own usage, tag every event with the subscription it belongs to, and add a **metering filter** on each subscription's usage-based products that only keeps events carrying that subscription's ID.

> [card] Example 💡
>
> A customer runs two business units, each with its own subscription to the same plan: a monthly platform fee plus usage-based "Transactions processed". Events are sent with `record.subscription_id` set to the subscription of the business unit that generated them. Each subscription's "Transactions processed" product has a metering filter `subscription_id equals <its own ID>`, so each one bills only its own transactions.

## How it works

1. A subscription is created in Hyperline (from a template, a quote, the app, or the API).
2. Hyperline sends a `subscription.created` [webhook](https://docs.hyperline.co/developers/webhooks.md) to your endpoint.
3. Your endpoint updates the subscription and adds a metering filter on its usage-based products: `subscription_id equals <subscription ID>`.
4. Your system sends usage events with `record.subscription_id` set to the subscription ID.
5. Each subscription only counts the events carrying its ID.

> [!NOTE]
>
> The filter value doesn't have to be the Hyperline subscription ID. Any identifier your system already stores per subscription (contract ID, workspace ID, etc.) works, as long as the same value is set in the filter and in the events.

## 1. Listen to the subscription creation

[Add a webhook endpoint](https://docs.hyperline.co/developers/webhooks.md#add-a-webhook-endpoint) listening to the `subscription.created` event. The payload contains the subscription and customer IDs:

```json theme={null}
{
  "event_type": "subscription.created",
  "data": {
    "id": "sub_9wm3HcmND6i5oh",
    "status": "active",
    "customer_id": "cus_qXY7itA7L9IC8P",
    "starts_at": "2026-11-10T14:46:25.961Z",
    "plan_id": null,
    "created_at": "2026-11-10T14:46:25.961Z"
  }
}
```

[Verify the signature](https://docs.hyperline.co/developers/webhooks.md#verify-webhooks) of every webhook before processing it. Hyperline sends the `webhook-id`, `webhook-timestamp` and `webhook-signature` headers.

## 2. Add the metering filter to the subscription

Metering filters on a subscription's prices are set through the API with [Update subscription](https://docs.hyperline.co/api-reference/endpoints/subscriptions/update-subscription.md).

1. Retrieve the subscription with [Get subscription](https://docs.hyperline.co/api-reference/endpoints/subscriptions/get-subscription.md).
2. For each usage-based product (`type: "dynamic"`) to filter, add a `metering_filter` on each of its prices.
3. Send the phases back with `PUT /v2/subscriptions/{id}`. The payload uses the same structure as the `GET` response, so you can send the retrieved phases with only the `metering_filter` added.

```sh theme={null}
curl -X PUT https://api.hyperline.co/v2/subscriptions/sub_9wm3HcmND6i5oh \
  -H "Authorization: Bearer <API key>" \
  -H "Content-Type: application/json" \
  -d '{
    "phases": [
      {
        "id": "sup_suivwjLk34rSEN",
        "products": [
          {
            "id": "itm_5hXEUKI1s5aaGi",
            "type": "dynamic",
            "prices": [
              {
                "type": "volume",
                "amount": 1,
                "from": 0,
                "to": null,
                "unit_count": 1,
                "metering_filter": {
                  "name": "Subscription sub_9wm3HcmND6i5oh",
                  "configuration": {
                    "conditional": "and",
                    "fields": [
                      {
                        "property": "subscription_id",
                        "operator": "equals",
                        "value": "sub_9wm3HcmND6i5oh"
                      }
                    ]
                  }
                }
              }
            ]
          }
        ]
      }
    ]
  }'
```

> [!WARNING]
>
> Send back **all** the phases and products of the subscription, with all their prices. Products missing from the payload are removed from the subscription, and pending phases are replaced by the ones you send.

To find which products to filter, check the aggregator of each usage-based product with [Get product](https://docs.hyperline.co/api-reference/endpoints/products/get-product.md) and only filter the ones linked to the aggregators you route per subscription.

> [!TIP]
>
> Webhooks can be delivered more than once. Before updating, check whether the prices already carry the filter for this subscription, and skip the update if they do.

For subscriptions created before your endpoint was in place, run the same update once for each of them.

## 3. Send events tagged with the subscription

Add the subscription ID to the `record` of every event, under the property used in the filter:

```sh theme={null}
curl -X POST https://ingest.hyperline.co/v1/events \
  -H "Authorization: Bearer <API key>" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cus_qXY7itA7L9IC8P",
    "event_type": "transactions",
    "timestamp": "2026-11-10T15:00:00Z",
    "record": {
      "id": "txn_8f2c41",
      "amount": 1500,
      "subscription_id": "sub_9wm3HcmND6i5oh"
    }
  }'
```

See [Send usage data](https://docs.hyperline.co/docs/usage/send-usage-data.md) for the other ingestion methods and the event format.

> [!NOTE]
>
> Events without the property, or with another subscription's ID, are ignored by filtered products. They still appear in the customer's usage.

## 4. Check the usage per subscription

* [Get subscription](https://docs.hyperline.co/api-reference/endpoints/subscriptions/get-subscription.md) with `include_live_billing=true` returns the usage and amount currently computed for each product of the subscription.
* Each subscription's open invoice shows its own usage. When listing invoices with the API, pass `status=open` to include them.
* The customer **Usage** tab shows the total usage of the customer, across all subscriptions.

## Good to know

* The filter is set on the subscription, not on the product or the template: every new subscription needs its own filter, which is why the update runs on `subscription.created`.
* Prices and other product settings are kept as they are: the update only adds the filter.
* A metering filter can combine several conditions. If your prices already use metering filters (for example per region), add the `subscription_id` condition to the existing fields with `conditional: "and"`.

> [!NOTE]
>
> Is something still unclear? Don't hesitate to reach out to our team
> via the in-app chat if you need additional support.


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