Purchases, trials and cancellations on the timeline

Trials, purchases, cancellations and billing issues. Sandbox counts land on separate *_sandbox metrics.

What does not arrive

  • EXPIRATION. Discarded.
  • Every other RevenueCat type that is not listed under What arrives.

What arrives

trial_starts is the early indicator with a fixed offset — trials lead paying users by the trial length in the chart compare, not by attribution. A shifted compare line on the chart comes later; without this metric it is unbuildable, and each day without capture is history you cannot reconstruct. No timeline marker (same rule as purchases): many trials in one day would make the axis unreadable.

Trial start: INITIAL_PURCHASE with period_type: TRIAL, or TRIAL_STARTED if RevenueCat sends that type. Increments daily trial_starts with role trials. Does not count as a paying user.

Paid start: INITIAL_PURCHASE without a trial period increments purchases and new_paying_users (paying-users role — a flow of new payers for CAC and the funnel, not a stock of active customers). Active paying customers are derived separately as active_payers from the subscribers table. No timeline event.

RENEWAL increments purchases. When is_trial_conversion is true (or the type is TRIAL_CONVERTED), it also increments new_paying_users — that is the first paid period after a trial, not a second INITIAL_PURCHASE, so paying users are not double-counted.

Trial cancel: CANCELLATION with period_type: TRIAL, or TRIAL_CANCELLED, increments trial_cancellations. No marker.

Sandbox (environment: SANDBOX or Test Store) writes the same metrics with a _sandbox suffix (trial_starts_sandbox, purchases_sandbox, …) so test traffic does not inflate production series. Those sandbox defs never carry evaluation roles; turn on Show test data in project settings to see them in pickers. Sandbox cancellations and billing issues do not become timeline markers. Sandbox is also discarded for the subscriber cohort table — only production ids are stored for later retention analysis.

CANCELLATION (paid). Kind external.

FieldWhat it is
kindexternal
titleSubscription cancelled
external_idEvent id.
occurred_atevent_timestamp_ms, otherwise purchased_at_ms.
meta.product_idproduct_id, when present.
meta.storestore, when present.
meta.countrycountry_code, when present.
meta.priceprice, otherwise price_in_purchased_currency.
meta.currencycurrency, when present.

BILLING_ISSUE. Kind incident.

FieldWhat it is
kindincident
titleBilling issue
external_idEvent id.
occurred_atevent_timestamp_ms, otherwise purchased_at_ms.
metaSame product, store, country, price and currency fields.

Signature

Authorization: Bearer compared to a SHA-256 hash of the secret. Not an HMAC of the body.

Set up in RevenueCat

  1. Select your project → Integrations (left column, near the bottom) → Webhooks → Add webhook.

    Not under Project settings.

  2. Paste the URL.
  3. Environment: Production and Sandbox both fine.

    Sandbox events write *_sandbox metrics so they do not inflate paying users. Prefer Production-only if you do not need the sandbox series.

  4. App: pick the specific app, not All apps.

    Otherwise the Test Store and other apps on the same account land in this project.

  5. Event type: All events.

    Erdi decides which events become metrics or markers.

  6. Authorization header value: paste the secret from Erdi.

Set it up under Settings → Webhooks in your project.

Get started with ErdiKnows