Webhooks
Billing events
The reference card for billing.* deliveries — types, envelope, and the data payload, in one place.
Fictura → your server, POST, JSON, one attempt with an 8-second timeout. Setup and integration guidance live in Billing webhooks; this page is the contract.
type | data.event_name | Semantics |
|---|---|---|
billing.purchase | subscription_started | Paid subscription, no trial. |
billing.trial_start | trial_started | Trial began; price is 0. |
billing.conversion | subscription_renewed | Trial's first paid period. |
billing.renewal | subscription_renewed | Paid period renewed. |
billing.cancellation | subscription_cancelled | Auto-renew off; access continues to expires_at. |
billing.expiration | subscription_expired | Access ended — the only type that means that. |
billing.billing_issue | billing_issue | Payment failed; grace period. |
billing.other | varies — e.g. subscription_uncancelled | Everything else, e.g. auto-renew restored. |
Delivery
{
"type": "billing.purchase",
"app_id": "6b8506b9-2f01-499b-a95a-e64ee67b2d3a",
"sent_at": "2026-08-10T18:22:41.000Z",
"data": {
"event_name": "subscription_started",
"app_user_id": "8f14e45f-ceea-467f-a9d2-5f9e4b1c2d3e",
"product_id": "price_1TmKgSDnJtk7pxNB…",
"price": 9.99,
"currency": "USD",
"store": "STRIPE",
"country": "US",
"expires_at": "2026-09-10T18:22:41.000Z",
"period_type": "NORMAL",
"environment": "PRODUCTION",
"master_user_id": "0f1e2d3c-4b5a-6978-8695-a4b3c2d1e0f9"
}
}Stripe-originated and RevenueCat-originated events arrive in this identical shape — store tells them apart (STRIPE, RC_BILLING, APP_STORE, PLAY_STORE). Skip environment: "SANDBOX" in production handlers. The same connection also delivers error.*, uptime.* and experiment events — the full catalog is on Outgoing webhooks.