---
title: "subscription.line_item_spend.threshold_recovered"
method: POST
path: "/webhook-events/subscription.line_item_spend.threshold_recovered"
tags: ["Webhook Events"]
---

# subscription.line_item_spend.threshold_recovered

`POST /webhook-events/subscription.line_item_spend.threshold_recovered`

Fired when a subscription line item's metered spend falls back below all configured alert thresholds for the current billing period. Doc-only for parsing.

## Response `200`

Webhook payload

- WebhookDtoSpendAlertEvent
  - `alert_status` 'ok' | 'info' | 'warning' | 'in_alarm'
  - `alert_type` 'low_ongoing_balance' | 'low_credit_balance' | 'feature_wallet_balance' | 'subscription_spend' | 'subscription_line_item_spend' | 'subscription_group_spend' | 'entitlement_grant_threshold' | 'entitlement_grant_exhausted'
  - `current_spend` string
  - `group_id` string
  - `subscription` WebhookDtoSubscription
    - `billing_cadence` 'RECURRING'
    - `billing_period` 'MONTHLY' | 'ANNUAL' | 'WEEKLY' | 'DAILY' | 'QUARTERLY' | 'HALF_YEARLY' | 'ONETIME'
    - `billing_period_count` integer
    - `cancel_at` string, date-time
    - `cancel_at_period_end` boolean
    - `cancelled_at` string, date-time
    - `coupon_associations` WebhookDtoCouponAssociation[]
      - `coupon_id` string
      - `end_date` string, date-time
      - `id` string
      - `metadata` object
      - `start_date` string, date-time
      - `subscription_id` string
      - `subscription_line_item_id` string
    - `currency` string
    - `current_period_end` string, date-time
    - `current_period_start` string, date-time
    - `customer` WebhookDtoCustomer
      - `address_city` string
      - `address_country` string
      - `address_line1` string
      - `address_line2` string
      - `address_postal_code` string
      - `address_state` string
      - `email` string
      - `environment_id` string
      - `external_id` string
      - `id` string
      - `metadata` object
      - `name` string
      - `timezone` string
    - `customer_id` string
    - `end_date` string, date-time
    - `id` string
    - `line_items` WebhookDtoSubscriptionLineItem[]
      - `billing_period` 'MONTHLY' | 'ANNUAL' | 'WEEKLY' | 'DAILY' | 'QUARTERLY' | 'HALF_YEARLY' | 'ONETIME'
      - `billing_period_count` integer
      - `currency` string
      - `display_name` string
      - `end_date` string, date-time
      - `entity_id` string
      - `entity_type` 'plan' | 'addon' | 'subscription'
      - `id` string
      - `invoice_cadence` 'ARREAR' | 'ADVANCE'
      - `metadata` object
      - `meter_display_name` string
      - `meter_id` string
      - `plan_display_name` string
      - `price` WebhookDtoPrice
        - `amount` string
        - `billing_cadence` 'RECURRING'
        - `billing_model` 'FLAT_FEE' | 'PACKAGE' | 'TIERED'
        - `billing_period` 'MONTHLY' | 'ANNUAL' | 'WEEKLY' | 'DAILY' | 'QUARTERLY' | 'HALF_YEARLY' | 'ONETIME'
        - `billing_period_count` integer
        - `currency` string
        - `description` string
        - `display_amount` string
        - `display_name` string
        - `display_price_unit_amount` string
        - `id` string
        - `invoice_cadence` 'ARREAR' | 'ADVANCE'
        - `lookup_key` string
        - `metadata` PriceJSONBMetadata
        - `meter` WebhookDtoMeter
          - `aggregation` MeterAggregation
            - `bucket_size` 'MINUTE' | '15MIN' | '30MIN' | 'HOUR' | '3HOUR' | '6HOUR' | '12HOUR' | 'DAY' | 'WEEK' | 'MONTH'
            - `expression` string — Expression is an optional CEL expression to compute per-event quantity from event.properties. When set, it replaces Field-based extraction. Property names are used directly (e.g., token * duration * pixel).
            - `field` string — Field is the key in $event.properties on which the aggregation is to be applied For ex if the aggregation type is sum for API usage, the field could be "duration_ms" Ignored when Expression is set.
            - `group_by` string — GroupBy is the property name in event.properties to group by before aggregating. Requires MAX aggregation. Windowing comes from the price, so this no longer implies a meter-level bucket_size. When set, aggregation is applied per unique value of this property within each bucket, then the per-group results are summed to produce the bucket total.
            - `multiplier` string — Multiplier is the multiplier for the aggregation For ex if the aggregation type is sum_with_multiplier for API usage, the multiplier could be 1000 to scale up by a factor of 1000. If not provided, it will be null.
            - `type` 'COUNT' | 'SUM' | 'AVG' | 'COUNT_UNIQUE' | 'LATEST' | 'SUM_WITH_MULTIPLIER' | 'MAX' | 'WEIGHTED_SUM'
          - `event_name` string
          - `id` string
          - `name` string
          - `reset_usage` 'BILLING_PERIOD' | 'NEVER'
        - `meter_id` string
        - `price_unit` string
        - `price_unit_amount` string
        - `tier_mode` 'VOLUME' | 'SLAB'
        - `tiers` PricePriceTier[]
          - `flat_amount` string — flat_amount is the flat amount for the given tier (optional) Applied on top of unit_amount*quantity. Useful for cases like "2.7$ + 5c"
          - `unit_amount` string — unit_amount is the amount per unit for the given tier
          - `up_to` integer — up_to is the quantity up to which this tier applies. It is null for the last tier. IMPORTANT: Tier boundaries are INCLUSIVE. - If up_to is 1000, then quantity less than or equal to 1000 belongs to this tier - This behavior is consistent across both VOLUME and SLAB tier modes
        - `transform_quantity` PriceJSONBTransformQuantity
          - `divide_by` integer — Divide quantity by this number
          - `round` 'up' | 'down'
        - `type` 'USAGE' | 'FIXED'
      - `price_id` string
      - `price_type` 'USAGE' | 'FIXED'
      - `price_unit` string
      - `quantity` string
      - `start_date` string, date-time
      - `subscription_id` string
    - `lookup_key` string
    - `metadata` TypesMetadata
    - `parent_subscription_id` string
    - `pause_status` 'none' | 'active' | 'scheduled' | 'completed' | 'cancelled'
    - `plan` WebhookDtoPlan
      - `description` string
      - `id` string
      - `lookup_key` string
      - `metadata` TypesMetadata
      - `name` string
      - `prices` WebhookDtoPrice[]
        - `amount` string
        - `billing_cadence` 'RECURRING'
        - `billing_model` 'FLAT_FEE' | 'PACKAGE' | 'TIERED'
        - `billing_period` 'MONTHLY' | 'ANNUAL' | 'WEEKLY' | 'DAILY' | 'QUARTERLY' | 'HALF_YEARLY' | 'ONETIME'
        - `billing_period_count` integer
        - `currency` string
        - `description` string
        - `display_amount` string
        - `display_name` string
        - `display_price_unit_amount` string
        - `id` string
        - `invoice_cadence` 'ARREAR' | 'ADVANCE'
        - `lookup_key` string
        - `metadata` PriceJSONBMetadata
        - `meter` WebhookDtoMeter
          - `aggregation` MeterAggregation
            - `bucket_size` 'MINUTE' | '15MIN' | '30MIN' | 'HOUR' | '3HOUR' | '6HOUR' | '12HOUR' | 'DAY' | 'WEEK' | 'MONTH'
            - `expression` string — Expression is an optional CEL expression to compute per-event quantity from event.properties. When set, it replaces Field-based extraction. Property names are used directly (e.g., token * duration * pixel).
            - `field` string — Field is the key in $event.properties on which the aggregation is to be applied For ex if the aggregation type is sum for API usage, the field could be "duration_ms" Ignored when Expression is set.
            - `group_by` string — GroupBy is the property name in event.properties to group by before aggregating. Requires MAX aggregation. Windowing comes from the price, so this no longer implies a meter-level bucket_size. When set, aggregation is applied per unique value of this property within each bucket, then the per-group results are summed to produce the bucket total.
            - `multiplier` string — Multiplier is the multiplier for the aggregation For ex if the aggregation type is sum_with_multiplier for API usage, the multiplier could be 1000 to scale up by a factor of 1000. If not provided, it will be null.
            - `type` 'COUNT' | 'SUM' | 'AVG' | 'COUNT_UNIQUE' | 'LATEST' | 'SUM_WITH_MULTIPLIER' | 'MAX' | 'WEIGHTED_SUM'
          - `event_name` string
          - `id` string
          - `name` string
          - `reset_usage` 'BILLING_PERIOD' | 'NEVER'
        - `meter_id` string
        - `price_unit` string
        - `price_unit_amount` string
        - `tier_mode` 'VOLUME' | 'SLAB'
        - `tiers` PricePriceTier[]
          - `flat_amount` string — flat_amount is the flat amount for the given tier (optional) Applied on top of unit_amount*quantity. Useful for cases like "2.7$ + 5c"
          - `unit_amount` string — unit_amount is the amount per unit for the given tier
          - `up_to` integer — up_to is the quantity up to which this tier applies. It is null for the last tier. IMPORTANT: Tier boundaries are INCLUSIVE. - If up_to is 1000, then quantity less than or equal to 1000 belongs to this tier - This behavior is consistent across both VOLUME and SLAB tier modes
        - `transform_quantity` PriceJSONBTransformQuantity
          - `divide_by` integer — Divide quantity by this number
          - `round` 'up' | 'down'
        - `type` 'USAGE' | 'FIXED'
    - `plan_id` string
    - `start_date` string, date-time
    - `subscription_status` 'active' | 'paused' | 'cancelled' | 'incomplete' | 'trialing' | 'draft'
    - `subscription_type` 'standalone' | 'delegated_invoicing' | 'parent' | 'inherited' | 'grouped_invoicing'
    - `trial_end` string, date-time
    - `trial_start` string, date-time
  - `subscription_line_item_id` string
  - `threshold` string
  - `triggered_at` string, date-time

## Changes

- **2026-09-02** `2bd70d9bd657` — 3 info
  - added the optional property `subscription/coupon_associations` to the response with the `200` status
  - added the optional property `subscription/line_items` to the response with the `200` status
  - added the optional property `subscription/plan` to the response with the `200` status
- **2026-08-20** `562f13cf61dd` — 1 info
  - added the optional property `subscription/customer/environment_id` to the response with the `200` status
- **2026-08-14** `29f14678f58f` — 44 warning, 3 info
  - removed the optional property `alert_settings` from the response with the `200` status
  - removed the optional property `group` from the response with the `200` status
  - removed the optional property `subscription/active_pause_id` from the response with the `200` status
  - removed the optional property `subscription/auto_invoice_threshold` from the response with the `200` status
  - …43 more
- **2026-07-31** `50b7421a9690` — 2 warning, 4 info
  - added the new `entitlement_grant_exhausted` enum value to the `alert_type` response property for the response status `200`
  - added the new `entitlement_grant_threshold` enum value to the `alert_type` response property for the response status `200`
  - added the optional property `subscription/coupon_associations/items/subscription_line_item/meter` to the response with the `200` status
  - added the optional property `subscription/entitlements` to the response with the `200` status
  - …2 more
- …earlier changes not shown

[Full history](https://skmtc.dev/flexprice/apis/flexprice-api/changes/webhook-events/subscription.line_item_spend.threshold_recovered/post.md)

---

[API](https://skmtc.dev/flexprice/apis/flexprice-api.md) · [All operations](https://skmtc.dev/flexprice/apis/flexprice-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/flexprice/flexprice-api/revisions/2bd70d9bd657/schema)
