Skip to main content
With Autumn, you don’t need webhooks for managing billing — subscription state, usage tracking, and access control are all synchronized automatically. However, webhooks can still be useful for specific use cases where you want to trigger actions in your own systems.

Use Cases

While Autumn handles billing complexity for you, webhooks are helpful for:
  • Sending activation emails — Welcome new subscribers or notify users when their plan changes
  • Triggering workflows — Start onboarding sequences, provision resources, or update CRM records
  • Syncing with external systems — Keep your database, analytics, or other tools in sync with subscription changes
  • Deprovisioning access to services — Shut off access to downstream services when a customer cancels their subscription

Available Events

billing.updated

Fired whenever a customer’s plans change — new subscriptions, upgrades, downgrades, etc. Each event carries a plan_changes array describing exactly what happened to each affected plan.
ActionDescription
activatedA plan is now active on the customer (newly attached, or a previously scheduled plan reached its start date)
scheduledA plan has been queued to start at a future date
updatedA plan’s state changed in place (cancellation set or cleared, past_due flipped, items added or removed)
expiredA plan ended and is no longer in effect
Each entry also includes the subscription (or purchase for one-off products) after the change, and previous_attributes holding the prior values of any fields that were updated. For instance, if a plan was canceled at period end:
{
  "action": "updated",
  "subscription": {
    "plan_id": "pro",
    "status": "active",
    "past_due": false,
    "started_at": 1759248000000,
    "canceled_at": 1761840000000,
    "expires_at": 1764432000000,
    "trial_ends_at": null,
    "current_period_start": 1761840000000,
    "current_period_end": 1764432000000
  },
  "previous_attributes": {
    "canceled_at": null,
    "expires_at": null
  },
  "item_changes": []
}
The top-level tags array surfaces optional reason tags describing why the event fired:
TagWhen
trial_endedA trial just ended (Stripe subscription transition or the trial-expiry cron)
phase_changedA Stripe subscription schedule phase advanced
Example payload (upgrade from free to pro):
{
  "type": "billing.updated",
  "data": {
    "object": "billing.updated",
    "customer_id": "user_123",
    "plan_changes": [
      {
        "action": "activated",
        "subscription": {
          "plan_id": "pro",
          "status": "active",
          "past_due": false,
          "started_at": 1761840000000,
          "canceled_at": null,
          "expires_at": null,
          "trial_ends_at": null,
          "current_period_start": 1761840000000,
          "current_period_end": 1764432000000
        },
        "previous_attributes": null,
        "item_changes": []
      },
      {
        "action": "expired",
        "subscription": {
          "plan_id": "free",
          "status": "expired",
          "past_due": false,
          "started_at": 1759248000000,
          "canceled_at": 1761840000000,
          "expires_at": 1761840000000,
          "trial_ends_at": null,
          "current_period_start": null,
          "current_period_end": null
        },
        "previous_attributes": { "status": "active" },
        "item_changes": []
      }
    ],
    "tags": []
  }
}
For entity-scoped events, the payload will also include an entity_id:
{
  "type": "billing.updated",
  "data": {
    "object": "billing.updated",
    "customer_id": "user_123",
    "entity_id": "team_456",
    "plan_changes": [ ... ],
    "tags": []
  }
}
Common patterns:
  • Sync Autumn state back to your DB — listen for every billing.updated and persist each plan_changes entry’s subscription snapshot keyed by customer_id (+ entity_id if set).
  • Notify on upgrades — filter for entries with action: "activated". For “upgrade from previous plan” specifically, pair it with an action: "expired" entry on the same event.
  • Detect cancellations — filter for entries where previous_attributes.canceled_at === null (a cancellation was just set) or previous_attributes.canceled_at is a number (an uncancel).
  • Trial-end emails — filter for tags.includes("trial_ended").

balances.limit_reached

Fired when a customer hits a usage limit for a feature. A limit can be the included allowance, a max purchase cap, or a spend limit.
Limit TypeDescription
includedCustomer has exhausted their included allowance
max_purchaseCustomer has reached the maximum purchase cap for overage
spend_limitCustomer has hit their configured spend limit
Example payload:
{
  "type": "balances.limit_reached",
  "data": {
    "customer_id": "user_123",
    "feature_id": "api_calls",
    "limit_type": "included"
  }
}
For entity-scoped usage, the payload will also include an entity_id:
{
  "type": "balances.limit_reached",
  "data": {
    "customer_id": "user_123",
    "feature_id": "api_calls",
    "entity_id": "team_456",
    "limit_type": "max_purchase"
  }
}

billing.auto_topup_succeeded

Fired when an auto top-up successfully grants additional prepaid balance. Useful for sending receipts, updating internal ledgers, or reconciling balance after a recharge. For auto-charged top-ups, the event fires only after the Stripe invoice is paid. For invoice_mode top-ups, the event fires once credits are granted and the invoice is finalized — invoice.status will typically be "open" until the customer pays. Use invoice.stripe_id as a stable dedupe key. The top-level id field (e.g. evt_auto_topup_...) is a unique identifier for the event itself. Example payload (auto-charge):
{
  "type": "billing.auto_topup_succeeded",
  "id": "evt_auto_topup_2abc123",
  "occurred_at": 1761840000000,
  "data": {
    "customer_id": "user_123",
    "feature_id": "credits",
    "quantity_granted": 1000,
    "threshold": 500,
    "balance_after": 1450,
    "invoice_mode": false,
    "invoice": {
      "stripe_id": "in_1A2B3C4D5E6F",
      "status": "paid",
      "total": 1000,
      "currency": "usd",
      "hosted_invoice_url": "https://invoice.stripe.com/i/..."
    }
  }
}
Example payload (invoice mode):
{
  "type": "billing.auto_topup_succeeded",
  "id": "evt_auto_topup_3xyz456",
  "occurred_at": 1761840000000,
  "data": {
    "customer_id": "user_123",
    "feature_id": "credits",
    "quantity_granted": 1000,
    "threshold": 500,
    "balance_after": 1450,
    "invoice_mode": true,
    "invoice": {
      "stripe_id": "in_2G3H4I5J6K7L",
      "status": "open",
      "total": 1000,
      "currency": "usd",
      "hosted_invoice_url": "https://invoice.stripe.com/i/..."
    }
  }
}

balances.usage_alert_triggered

Fired when a customer crosses a configured usage alert threshold. Usage alerts let you monitor when customers approach or exceed specific usage levels for a feature.
Alert Threshold TypeDescription
usageAn absolute usage count was crossed
usage_percentageA percentage of the usage allowance was crossed
Example payload:
{
  "type": "balances.usage_alert_triggered",
  "data": {
    "customer_id": "user_123",
    "feature_id": "api_calls",
    "usage_alert": {
      "name": "80% usage warning",
      "threshold": 80,
      "threshold_type": "usage_percentage"
    }
  }
}

Setup

Configure your webhook endpoints in the Autumn dashboard:
1

Navigate to Developer Settings

Go to the Developer section in your Autumn dashboard and select the Webhooks tab.
2

Add an Endpoint

Click Add Endpoint and enter the URL where you want to receive webhook events.
3

Select Events

Choose which events you want to subscribe to. You can select all events or specific ones.
4

Save and Test

Save your endpoint configuration. You can use the Send Test Event button to verify your endpoint is receiving events correctly.

Webhook Security

Autumn uses Svix for reliable webhook delivery. Each webhook request includes signature headers that you can use to verify the request is genuinely from Autumn:
  • svix-id — Unique message identifier
  • svix-timestamp — Timestamp of when the message was sent
  • svix-signature — Signature for verifying authenticity
You can use the Svix libraries to easily verify webhook signatures in your application.

Retry Policy

If your endpoint returns an error or is unavailable, Autumn will automatically retry the webhook with exponential backoff. You can view delivery attempts and retry failed webhooks from the dashboard.