diff --git a/content/docs/integrations/amplitude.mdx b/content/docs/integrations/amplitude.mdx index 609b338..e238649 100644 --- a/content/docs/integrations/amplitude.mdx +++ b/content/docs/integrations/amplitude.mdx @@ -59,37 +59,70 @@ Fill out the following fields and **click** the **Enable Amplitude** button at t ### Event mapping -Superwall events are transformed into human-readable Amplitude events: +Superwall events are transformed into readable, Title Case Amplitude events. #### Event name format -All events are prefixed with `[Superwall]` followed by a descriptive name: +All events are prefixed with `[Superwall] ` followed by the Title Case name: - Example: `[Superwall] Trial Start` -- Example: `[Superwall] Subscription Renewal` - -#### Complete event mapping - -| Superwall Event | Amplitude Event | Description | -|-----------------|-----------------|-------------| -| `initial_purchase` + TRIAL | `[Superwall] Trial Start` | Trial begins | -| `initial_purchase` + INTRO | `[Superwall] Intro Offer Start` | Intro offer begins | -| `initial_purchase` + NORMAL | `[Superwall] Subscription Start` | Paid subscription begins | -| `renewal` + trial conversion | `[Superwall] Trial Conversion` | Trial converts to paid | -| `renewal` + INTRO | `[Superwall] Intro Offer Conversion` | Intro converts to regular | -| `renewal` + NORMAL | `[Superwall] Subscription Renewal` | Regular renewal | -| `cancellation` + TRIAL | `[Superwall] Trial Cancellation` | Trial cancelled | -| `cancellation` + INTRO | `[Superwall] Intro Offer Cancellation` | Intro cancelled | -| `cancellation` + NORMAL | `[Superwall] Subscription Cancellation` | Subscription cancelled | -| `uncancellation` + TRIAL | `[Superwall] Trial Uncancellation` | Trial reactivated | -| `uncancellation` + INTRO | `[Superwall] Intro Offer Uncancellation` | Intro reactivated | -| `uncancellation` + NORMAL | `[Superwall] Subscription Uncancellation` | Subscription reactivated | -| `expiration` + TRIAL | `[Superwall] Trial Expiration` | Trial ended | -| `expiration` + INTRO | `[Superwall] Intro Offer Expiration` | Intro ended | -| `expiration` + NORMAL | `[Superwall] Subscription Expiration` | Subscription ended | -| `billing_issue` | `[Superwall] Billing Issue` | Payment failed | -| `subscription_paused` | `[Superwall] Subscription Paused` | Subscription paused | -| `product_change` | `[Superwall] Product Change` | Plan changed | -| `non_renewing_purchase` | `[Superwall] Non-Renewing Purchase` | One-time purchase | -| Any with `price < 0` | `[Superwall] Refund` | Refund processed | +- Example: `[Superwall] Renewal` + +Each event also has a stable `sw_*` identifier. The identifier is internal and **not** what Amplitude receives — the value in the **Amplitude Event** column is what arrives in your project. + +These names are **not configurable**. There is no per-customer event renaming for Amplitude; every project on this integration receives the same Title Case names. + +#### Trial events + +| Superwall Event | Amplitude Event | Identifier | Description | +|-----------------|-----------------|------------|-------------| +| `initial_purchase` + TRIAL | `[Superwall] Trial Start` | `sw_trial_start` | Trial begins | +| `cancellation` + TRIAL | `[Superwall] Trial Cancelled` | `sw_trial_cancelled` | Trial cancelled | +| `uncancellation` + TRIAL | `[Superwall] Trial Uncancelled` | `sw_trial_uncancelled` | Trial reactivated | +| `expiration` + TRIAL | `[Superwall] Trial Expired` | `sw_trial_expired` | Trial ended | +| `renewal` + `isTrialConversion: true` | `[Superwall] Trial Converted` | `sw_trial_converted` | Trial converts to paid | + +#### Intro offer events + +| Superwall Event | Amplitude Event | Identifier | Description | +|-----------------|-----------------|------------|-------------| +| `initial_purchase` + INTRO | `[Superwall] Intro Offer Start` | `sw_intro_offer_start` | Intro offer begins | +| `cancellation` + INTRO | `[Superwall] Intro Offer Cancelled` | `sw_intro_offer_cancelled` | Intro offer cancelled | +| `uncancellation` + INTRO | `[Superwall] Intro Offer Uncancelled` | `sw_intro_offer_uncancelled` | Intro offer reactivated | +| `expiration` + INTRO | `[Superwall] Intro Offer Expired` | `sw_intro_offer_expired` | Intro offer ended | +| `renewal` + INTRO | `[Superwall] Intro Offer Converted` | `sw_intro_offer_converted` | Intro converts to regular | + +#### Subscription events + +| Superwall Event | Amplitude Event | Identifier | Description | +|-----------------|-----------------|------------|-------------| +| `initial_purchase` + NORMAL | `[Superwall] Subscription Start` | `sw_subscription_start` | Paid subscription begins | +| `renewal` + NORMAL | `[Superwall] Renewal` | `sw_renewal` | Regular renewal | +| `cancellation` + NORMAL | `[Superwall] Subscription Cancelled` | `sw_subscription_cancelled` | Subscription cancelled | +| `uncancellation` + NORMAL | `[Superwall] Subscription Uncancelled` | `sw_subscription_uncancelled` | Subscription reactivated | +| `expiration` + NORMAL | `[Superwall] Subscription Expired` | `sw_subscription_expired` | Subscription ended | + +#### Other events + +Matched on the event name alone, **before** `periodType` is consulted: + +| Superwall Event | Amplitude Event | Identifier | Description | +|-----------------|-----------------|------------|-------------| +| `test` | `[Superwall] Test Event` | `sw_test` | Test event | +| `product_change` | `[Superwall] Product Change` | `sw_product_change` | Plan changed | +| `subscription_paused` | `[Superwall] Subscription Paused` | `sw_subscription_paused` | Subscription paused | +| `non_renewing_purchase` | `[Superwall] Non-Renewing Purchase` | `sw_non_renewing_purchase` | One-time purchase | +| `billing_issue` | `[Superwall] Billing Issue` | `sw_billing_issue` | Payment failed | +| Any with `price < 0` | `[Superwall] Refund` | `sw_refund` | Refund processed | + +#### Matching order + +Events are matched in this order — which is why a `billing_issue` during a trial arrives as `[Superwall] Billing Issue`, not a trial event: + +1. `test`, `product_change`, `subscription_paused`, `non_renewing_purchase`, `billing_issue` — matched on the event name, for any `periodType`. +2. `price < 0` → `Refund`. +3. `periodType` selects the Trial / Intro / Subscription table. +4. Unmatched names within a known `periodType` → `Unknown` (`sw_unknown`). + +A `renewal` during a trial without `isTrialConversion` is a plain `[Superwall] Renewal`. There is no transfer event, so subscription transfers fall through to `Unknown`. ### Event properties @@ -108,7 +141,7 @@ Every Amplitude event includes comprehensive properties: - `price`: Same as revenue - `quantity`: Always 1 - `productId`: Product identifier -- `revenueType`: Same as event type (for revenue categorization) +- `revenueType`: The event name **without** the `[Superwall] ` prefix (for revenue categorization) #### Event properties object All Superwall webhook data fields are included: @@ -149,7 +182,7 @@ The `sales_reporting` setting determines which value is used: "revenue": 9.99, "price": 9.99, "productId": "com.example.premium", - "revenueType": "[Superwall] Subscription Start" + "revenueType": "Subscription Start" } ``` @@ -160,7 +193,7 @@ The `sales_reporting` setting determines which value is used: "revenue": -9.99, "price": -9.99, "productId": "com.example.premium", - "revenueType": "[Superwall] Refund" + "revenueType": "Refund" } ``` @@ -258,7 +291,7 @@ Check your Amplitude project: #### Revenue analytics ``` -Events: [Superwall] Subscription Start, [Superwall] Subscription Renewal +Events: [Superwall] Subscription Start, [Superwall] Renewal Metric: Sum of revenue Segment by: platform, productId, countryCode ``` @@ -266,13 +299,13 @@ Segment by: platform, productId, countryCode #### Conversion funnel ``` 1. [Superwall] Trial Start -2. [Superwall] Trial Conversion +2. [Superwall] Trial Converted Conversion Rate: Step 2 / Step 1 ``` #### Churn analysis ``` -Events: [Superwall] Subscription Cancellation +Events: [Superwall] Subscription Cancelled Segment by: cancelReason, periodType, price tier ``` @@ -302,7 +335,7 @@ Calculate: Sum of revenue per user #### Duplicate events The integration uses `insert_id` to prevent duplicates: -- Format: `sw_eventId-eventName` +- Format: `sw_` + the Superwall event id with its first colon replaced by a dash - Amplitude automatically deduplicates by `insert_id` #### User attribution issues diff --git a/content/docs/integrations/customer-io.mdx b/content/docs/integrations/customer-io.mdx index 4c190be..f48d8cd 100644 --- a/content/docs/integrations/customer-io.mdx +++ b/content/docs/integrations/customer-io.mdx @@ -34,7 +34,6 @@ In the **Communication** section within **Integrations**, you can connect your C |-------|-------------|---------| | `sandbox_api_key` | Separate Pipelines API key for sandbox/test events | None (sandbox events skipped) | | `anonymous_user_behavior` | How to handle events from users without an app user ID | `"send"` | -| `eventNameMappings` | Custom mapping to rename default event names | None | ### Example Configuration @@ -45,12 +44,7 @@ In the **Communication** section within **Integrations**, you can connect your C "api_key": "your-pipelines-api-key", "sales_reporting": "Revenue", "sandbox_api_key": "your-sandbox-pipelines-api-key", - "anonymous_user_behavior": "send", - "eventNameMappings": { - "sw_trial_start": "trial_started", - "sw_subscription_start": "subscription_started", - "sw_renewal": "subscription_renewed" - } + "anonymous_user_behavior": "send" } ``` @@ -69,7 +63,9 @@ The Customer.io integration uses the **Pipelines API** (part of Customer.io Data ## Event Mapping -Superwall subscription events are transformed into Customer.io events based on the event type and subscription period. All events are prefixed with `sw_` by default. +Superwall subscription events are transformed into Customer.io events based on the event type and subscription period. Customer.io receives the `sw_*` identifier itself — unlike Mixpanel, Amplitude and Statsig, which receive a Title Case name and keep `sw_*` internal. + +These names are **not configurable**. There is no per-customer event renaming for Customer.io; every workspace on this integration receives the same `sw_*` names. ### Trial Events @@ -104,14 +100,28 @@ Superwall subscription events are transformed into Customer.io events based on t ### Other Events +Matched on the event name alone, **before** `periodType` is consulted: + | Superwall Event | Customer.io Event | |-----------------|-------------------| +| `TEST` | `sw_test` | | `PRODUCT_CHANGE` | `sw_product_change` | -| `BILLING_ISSUE` | `sw_billing_issue` | | `SUBSCRIPTION_PAUSED` | `sw_subscription_paused` | | `NON_RENEWING_PURCHASE` | `sw_non_renewing_purchase` | +| `BILLING_ISSUE` | `sw_billing_issue` | | Any event with `price < 0` | `sw_refund` | +### Matching Order + +Events are matched in this order — which is why a `BILLING_ISSUE` during a trial arrives as `sw_billing_issue`, not a trial event: + +1. `TEST`, `PRODUCT_CHANGE`, `SUBSCRIPTION_PAUSED`, `NON_RENEWING_PURCHASE`, `BILLING_ISSUE` — matched on the event name, for any `periodType`. +2. `price < 0` → `sw_refund`. +3. `periodType` selects the Trial / Intro / Subscription table. +4. Unmatched names within a known `periodType` → `sw_unknown`. + +There is no transfer event, so subscription transfers fall through to `sw_unknown`. + ## Event Properties Each event sent to Customer.io includes comprehensive properties from the original Superwall event, plus additional formatted fields for revenue tracking. @@ -224,23 +234,6 @@ Customer.io offers data residency in two regions. The integration automatically Choose the region that matches your Customer.io workspace configuration. Using the wrong region will result in authentication errors. -## Custom Event Names - -Use `eventNameMappings` to rename default event names to match your existing Customer.io conventions: - -```json -{ - "eventNameMappings": { - "sw_trial_start": "Started Free Trial", - "sw_subscription_start": "Subscribed", - "sw_renewal": "Subscription Renewed", - "sw_subscription_cancelled": "Subscription Cancelled", - "sw_refund": "Refund Processed" - } -} -``` - -Only events you specify in the mapping are renamed. All other events keep their default `sw_` prefixed names. ## Testing the Integration @@ -275,7 +268,7 @@ Verify these scenarios work correctly: 3. **Handle anonymous users thoughtfully**: If your app requires login, use `"dontSend"` to avoid cluttering Customer.io with unidentifiable users. -4. **Keep event names consistent**: If you have existing events in Customer.io, use `eventNameMappings` to maintain naming consistency across your data. +4. **Map names on your side**: Superwall always sends the `sw_*` names above. If you need different naming in Customer.io, transform them downstream in your Data Pipelines source. 5. **Verify your region**: Ensure your `region` setting matches your Customer.io workspace location to avoid authentication failures. @@ -343,13 +336,13 @@ Build comprehensive revenue reporting: **Solution:** Revenue properties (`price`, `currency`, `product_id`, `subscription_id`) are only added when the price is non-zero. This is expected behavior. -### Wrong Event Names +### Unexpected Event Names **Possible causes:** -- Event name mappings not configured -- Typo in mapping configuration +- Expecting custom names — Superwall always sends the fixed `sw_*` names listed above +- The event resolved differently than expected (see [Matching Order](#matching-order)) -**Solution:** Check your `eventNameMappings` configuration. Keys should be the default event names (e.g., `sw_trial_start`), and values should be your desired custom names. +**Solution:** Compare the received name against the mapping tables above. A `BILLING_ISSUE` during a trial, for example, arrives as `sw_billing_issue` rather than a trial event. ## Rate Limits diff --git a/content/docs/integrations/discord.mdx b/content/docs/integrations/discord.mdx index b5e5c4c..01392d4 100644 --- a/content/docs/integrations/discord.mdx +++ b/content/docs/integrations/discord.mdx @@ -34,7 +34,6 @@ In the **Communication** section within **Integrations**, you can connect your D |-------|-------------|---------| | `event_type` | Filter which events to send | `"All Subscription Events"` | | `anonymous_user_behavior` | How to handle events from users without an app user ID | `"send"` | -| `eventNameMappings` | Custom mapping to rename default event titles | None | ### Example Configuration @@ -44,11 +43,7 @@ In the **Communication** section within **Integrations**, you can connect your D "webhook_url": "https://discord.com/api/webhooks/1234567890/abcdefghijklmnop", "sales_reporting": "Revenue", "event_type": "All Subscription Events", - "anonymous_user_behavior": "send", - "eventNameMappings": { - "sw_subscription_start": "New Premium Member!", - "sw_trial_start": "New Trial Started" - } + "anonymous_user_behavior": "send" } ``` @@ -143,51 +138,69 @@ Each event type has a distinct emoji, title, and color for quick visual identifi | Color | Hex Code | Meaning | |-------|----------|---------| -| Green | `#36A64F` | Revenue events (purchases, renewals, conversions) | -| Blue | `#3498DB` | Trial events (non-revenue) | -| Red | `#FA6A6A` | Negative events (cancellations, refunds, expirations) | +| Green | `#36A64F` | Revenue events (purchases, renewals, conversions, uncancellations) | +| Blue | `#3498DB` | Trial-period events other than renewals — including trial cancellations, expirations and refunds | +| Red | `#FA6A6A` | Negative non-trial events (cancellations, refunds, expirations) | | Orange | `#FF9500` | Billing issues | | Purple | `#9B59B6` | Product changes | | Gray | `#666666` | Other events | +The trial check runs **before** the negative check, so every trial-period event that isn't a renewal is Blue — a cancelled or refunded trial is Blue, not Red. + ### Event Title Reference +Discord receives these titles, not the `sw_*` identifiers — the identifier is internal and never appears in a message. + +These titles are **not configurable**. There is no per-customer event renaming for Discord; every server on this integration receives the same titles. + #### Trial Events -| Event | Title | Color | -|-------|-------|-------| -| Trial Start | 🤩 Trial Start | Blue | -| Trial Conversion | 💰 Trial Conversion | Green | -| Trial Cancelled | 😞 Cancelled Trial | Red | -| Trial Refunded | 🤬 Refunded Trial | Red | -| Trial Expired | 😞 Expired Trial | Red | -| Trial Uncancelled | 🤩 Trial Uncancelled | Blue | +| Event | Title | Identifier | Color | +|-------|-------|------------|-------| +| Trial Start | 🤩 Trial Start | `sw_trial_start` | Blue | +| Trial Conversion | 💰 Trial Conversion | `sw_trial_converted` | Green | +| Renewal during trial (no conversion) | 💰 Renewal | `sw_renewal` | Green | +| Trial Cancelled | 😞 Cancelled Trial | `sw_trial_cancelled` | Blue | +| Trial Refunded | 🤬 Refunded Trial | `sw_refund` | Blue | +| Trial Expired | 😞 Expired Trial | `sw_trial_expired` | Blue | +| Trial Uncancelled | 🤩 Trial Uncancelled | `sw_trial_uncancelled` | Blue | #### Intro Offer Events -| Event | Title | Color | -|-------|-------|-------| -| Intro Start (free) | 🤩 Intro Offer Start | Blue | -| Intro Start (paid) | 💰 Intro Offer Start | Green | -| Intro Conversion | 💰 Intro Offer Conversion | Green | -| Intro Cancelled | 😞 Cancelled Intro Offer | Red | -| Intro Refunded | 🤬 Refunded Intro Offer | Red | +| Event | Title | Identifier | Color | +|-------|-------|------------|-------| +| Intro Start (free) | 🤩 Intro Offer Start | `sw_intro_offer_start` | Green | +| Intro Start (paid) | 💰 Intro Offer Start | `sw_intro_offer_start` | Green | +| Intro Conversion | 💰 Intro Offer Conversion | `sw_intro_offer_converted` | Green | +| Intro Cancelled | 😞 Cancelled Intro Offer | `sw_intro_offer_cancelled` | Red | +| Intro Refunded | 🤬 Refunded Intro Offer | `sw_refund` | Red | +| Intro Expired | 😞 Expired Intro Offer | `sw_intro_offer_expired` | Red | +| Intro Uncancelled | 🤩 Intro Offer Uncancelled | `sw_intro_offer_uncancelled` | Green | #### Subscription Events -| Event | Title | Color | -|-------|-------|-------| -| New Subscription | 💰 New Subscriber | Green | -| Renewal | 💰 Renewal | Green | -| Cancellation | 😞 Cancelled Subscription | Red | -| Refund | 🤬 Refunded Subscription | Red | -| Expiration | 😞 Expired Subscription | Red | -| Uncancellation | 🤩 Subscription Uncancelled | Green | +| Event | Title | Identifier | Color | +|-------|-------|------------|-------| +| New Subscription | 💰 New Subscriber | `sw_subscription_start` | Green | +| Renewal | 💰 Renewal | `sw_renewal` | Green | +| Cancellation | 😞 Cancelled Subscription | `sw_subscription_cancelled` | Red | +| Refund | 🤬 Refunded Subscription | `sw_refund` | Red | +| Expiration | 😞 Expired Subscription | `sw_subscription_expired` | Red | +| Uncancellation | 🤩 Subscription Uncancelled | `sw_subscription_uncancelled` | Green | #### Other Events -| Event | Title | Color | -|-------|-------|-------| -| One-Time Purchase | 💰 One-Time Purchase | Green | -| Product Change | 😵‍💫 Product Change | Purple | -| Billing Issue | 🫠 Billing Issue | Orange | -| Subscription Paused | ⏸️ Subscription Paused | Gray | +| Event | Title | Identifier | Color | +|-------|-------|------------|-------| +| One-Time Purchase | 💰 One-Time Purchase | `sw_non_renewing_purchase` | Green | +| Product Change | 😵‍💫 Product Change | `sw_product_change` | Purple | +| Billing Issue | 🫠 Billing Issue | `sw_billing_issue` | Orange | +| Subscription Paused | ⏸️ Subscription Paused | `sw_subscription_paused` | Gray | + +### Matching Order + +Titles are chosen in this order — which is why a `billing_issue` during a trial gets the 🫠 Billing Issue title rather than a trial title: + +1. `product_change`, `billing_issue`, `subscription_paused` — matched on the event name, for any `periodType`. +2. `periodType` selects the Trial / Intro / Subscription title, with the refund variant chosen by `price < 0`. +3. `non_renewing_purchase` outside a `NORMAL` period → 💰 One-Time Purchase. +4. Anything unmatched falls back to the raw Superwall event name. ## Revenue Display @@ -243,37 +256,6 @@ Events from sandbox/test environments are clearly marked: - Helps distinguish test events from production activity - Production events do not show any environment indicator -## Custom Event Names - -Use `eventNameMappings` to customize event titles: - -```json -{ - "eventNameMappings": { - "sw_trial_start": "🎉 New Trial User!", - "sw_subscription_start": "💎 VIP Member Joined", - "sw_renewal": "🔄 Subscription Renewed", - "sw_subscription_cancelled": "👋 Member Churned" - } -} -``` - -### Available Event Keys - -| Key | Default Title | -|-----|---------------| -| `sw_trial_start` | 🤩 Trial Start | -| `sw_trial_converted` | 💰 Trial Conversion | -| `sw_trial_cancelled` | 😞 Cancelled Trial | -| `sw_subscription_start` | 💰 New Subscriber | -| `sw_renewal` | 💰 Renewal | -| `sw_subscription_cancelled` | 😞 Cancelled Subscription | -| `sw_subscription_expired` | 😞 Expired Subscription | -| `sw_refund` | 🤬 Refunded Subscription | -| `sw_billing_issue` | 🫠 Billing Issue | -| `sw_product_change` | 😵‍💫 Product Change | -| `sw_non_renewing_purchase` | 💰 One-Time Purchase | - ## Testing the Integration ### 1. Validate Credentials @@ -377,16 +359,16 @@ Display the Discord channel on a team dashboard or TV: 2. Consider using a less busy channel 3. Events will be queued and retried automatically -### Wrong Event Names or Emojis +### Unexpected Event Titles or Emojis **Possible causes:** -- Custom `eventNameMappings` overriding defaults -- Unexpected event type mapping +- Expecting custom titles — Superwall always sends the fixed titles listed above +- The event resolved differently than expected (see [Matching Order](#matching-order)) **Solutions:** -1. Review your `eventNameMappings` configuration -2. Check the event title reference table above -3. Remove custom mappings to restore defaults +1. Check the event title reference table above +2. Confirm the `periodType` and `price` on the event — a negative price selects the 🤬 refund variant +3. Remember that `billing_issue`, `product_change` and `subscription_paused` match before `periodType` is consulted ### Missing Revenue Field diff --git a/content/docs/integrations/firebase.mdx b/content/docs/integrations/firebase.mdx index 08a133c..32b2180 100644 --- a/content/docs/integrations/firebase.mdx +++ b/content/docs/integrations/firebase.mdx @@ -122,30 +122,47 @@ Events with non-zero amounts use Firebase's standard ecommerce events for proper ### Non-Revenue Events (Custom Events) -Events without revenue are mapped to custom Firebase events (lowercase, underscores): - -| Superwall Event | Firebase Event | Description | -|-----------------|----------------|-------------| -| `initial_purchase` + TRIAL | `trial_start` | Trial begins | -| `initial_purchase` + INTRO | `intro_offer_start` | Intro offer begins | -| `initial_purchase` + NORMAL | `subscription_start` | Paid subscription begins | -| `renewal` + trial conversion | `trial_conversion` | Trial converts to paid | -| `renewal` + INTRO | `intro_offer_conversion` | Intro converts to regular | -| `renewal` + NORMAL | `subscription_renewal` | Regular renewal | -| `cancellation` + TRIAL | `trial_cancellation` | Trial cancelled | -| `cancellation` + INTRO | `intro_offer_cancellation` | Intro cancelled | -| `cancellation` + NORMAL | `subscription_cancellation` | Subscription cancelled | -| `uncancellation` + TRIAL | `trial_uncancellation` | Trial reactivated | -| `uncancellation` + INTRO | `intro_offer_uncancellation` | Intro reactivated | -| `uncancellation` + NORMAL | `subscription_uncancellation` | Subscription reactivated | -| `expiration` + TRIAL | `trial_expiration` | Trial ended | -| `expiration` + INTRO | `intro_offer_expiration` | Intro ended | -| `expiration` + NORMAL | `subscription_expiration` | Subscription ended | -| `billing_issue` | `billing_issue` | Payment failed | -| `subscription_paused` | `subscription_paused` | Subscription paused | -| `product_change` | `product_change` | Plan changed | -| `non_renewing_purchase` | `non_renewing_purchase` | One-time purchase | -| `test` | `test` | Test event | +Events without revenue are mapped to custom Firebase events. The name is derived mechanically from the Title Case event name: spaces become underscores and the result is lowercased. Nothing else is stripped — so `Non-Renewing Purchase` keeps its hyphen and becomes `non-renewing_purchase`. + +Each event also has a stable `sw_*` identifier. The identifier is internal and **not** what Firebase receives. + +These names are **not configurable**. There is no per-customer event renaming for Firebase; every project on this integration receives the same derived names. + +| Superwall Event | Firebase Event | Identifier | Description | +|-----------------|----------------|------------|-------------| +| `initial_purchase` + TRIAL | `trial_start` | `sw_trial_start` | Trial begins | +| `cancellation` + TRIAL | `trial_cancelled` | `sw_trial_cancelled` | Trial cancelled | +| `uncancellation` + TRIAL | `trial_uncancelled` | `sw_trial_uncancelled` | Trial reactivated | +| `expiration` + TRIAL | `trial_expired` | `sw_trial_expired` | Trial ended | +| `renewal` + `isTrialConversion: true` | `trial_converted` | `sw_trial_converted` | Trial converts to paid | +| `initial_purchase` + INTRO | `intro_offer_start` | `sw_intro_offer_start` | Intro offer begins | +| `cancellation` + INTRO | `intro_offer_cancelled` | `sw_intro_offer_cancelled` | Intro cancelled | +| `uncancellation` + INTRO | `intro_offer_uncancelled` | `sw_intro_offer_uncancelled` | Intro reactivated | +| `expiration` + INTRO | `intro_offer_expired` | `sw_intro_offer_expired` | Intro ended | +| `renewal` + INTRO | `intro_offer_converted` | `sw_intro_offer_converted` | Intro converts to regular | +| `initial_purchase` + NORMAL | `subscription_start` | `sw_subscription_start` | Paid subscription begins | +| `renewal` + NORMAL | `renewal` | `sw_renewal` | Regular renewal | +| `cancellation` + NORMAL | `subscription_cancelled` | `sw_subscription_cancelled` | Subscription cancelled | +| `uncancellation` + NORMAL | `subscription_uncancelled` | `sw_subscription_uncancelled` | Subscription reactivated | +| `expiration` + NORMAL | `subscription_expired` | `sw_subscription_expired` | Subscription ended | +| `billing_issue` | `billing_issue` | `sw_billing_issue` | Payment failed | +| `subscription_paused` | `subscription_paused` | `sw_subscription_paused` | Subscription paused | +| `product_change` | `product_change` | `sw_product_change` | Plan changed | +| `non_renewing_purchase` | `non-renewing_purchase` | `sw_non_renewing_purchase` | One-time purchase | +| `test` | `test_event` | `sw_test` | Test event | + +Note that most rows above only apply when the event carries no revenue. A `subscription_start` or `renewal` with a non-zero amount is sent as the standard `purchase` event instead, and any event with `price < 0` is sent as `refund`. + +#### Matching order + +Events are matched in this order — which is why a `billing_issue` during a trial arrives as `billing_issue`, not a trial event: + +1. Non-zero amount → `purchase` (positive) or `refund` (negative). Everything below applies only to zero-amount events. +2. `test`, `product_change`, `subscription_paused`, `non_renewing_purchase`, `billing_issue` — matched on the event name, for any `periodType`. +3. `periodType` selects the Trial / Intro / Subscription name. +4. Unmatched names within a known `periodType` → `unknown` (`sw_unknown`). + +There is no transfer event, so subscription transfers fall through to `unknown`. ## Event Parameters @@ -348,7 +365,7 @@ Conversion Rate: Step 2 / Step 1 ### Churn Analysis ``` -Events: subscription_cancellation, subscription_expiration +Events: subscription_cancelled, subscription_expired Segment by: period_type, store ``` diff --git a/content/docs/integrations/meta-conversion-api.mdx b/content/docs/integrations/meta-conversion-api.mdx index 740542d..ad274df 100644 --- a/content/docs/integrations/meta-conversion-api.mdx +++ b/content/docs/integrations/meta-conversion-api.mdx @@ -99,6 +99,10 @@ personal token. Superwall maps revenue lifecycle events to Meta standard events when possible. Using standard events helps Meta optimize ad delivery for those outcomes. +Meta is one of the integrations that receives the `sw_*` identifier itself for anything without a standard equivalent — unlike Mixpanel, Amplitude and Statsig, which receive a Title Case name. + +These names are **not configurable**. There is no per-customer event renaming for Meta; every Pixel on this integration receives the same names. + ### Standard event mappings | Superwall event | Meta standard event | Description | @@ -116,12 +120,22 @@ names by default: | Superwall event | Meta event name | |-----------------|-----------------| -| `sw_subscription_cancelled` | `sw_subscription_cancelled` | +| `sw_intro_offer_start` | `sw_intro_offer_start` | | `sw_trial_cancelled` | `sw_trial_cancelled` | +| `sw_trial_uncancelled` | `sw_trial_uncancelled` | +| `sw_trial_expired` | `sw_trial_expired` | +| `sw_intro_offer_cancelled` | `sw_intro_offer_cancelled` | +| `sw_intro_offer_uncancelled` | `sw_intro_offer_uncancelled` | +| `sw_intro_offer_expired` | `sw_intro_offer_expired` | +| `sw_subscription_cancelled` | `sw_subscription_cancelled` | +| `sw_subscription_uncancelled` | `sw_subscription_uncancelled` | | `sw_subscription_expired` | `sw_subscription_expired` | +| `sw_subscription_paused` | `sw_subscription_paused` | +| `sw_non_renewing_purchase` | `sw_non_renewing_purchase` | | `sw_billing_issue` | `sw_billing_issue` | | `sw_refund` | `sw_refund` | | `sw_product_change` | `sw_product_change` | +| `sw_test` | `sw_test` | ### Complete event mapping reference @@ -132,12 +146,30 @@ names by default: | `INITIAL_PURCHASE` | `periodType = Intro` | `sw_intro_offer_start` | | `RENEWAL` | `periodType = Trial` | `Purchase` | | `RENEWAL` | `periodType = Normal` | `Purchase` | +| `RENEWAL` | `periodType = Intro` | `Purchase` | | `RENEWAL` | `isTrialConversion = true` | `Purchase` | | `CANCELLATION` | `periodType = Trial` | `sw_trial_cancelled` | +| `CANCELLATION` | `periodType = Intro` | `sw_intro_offer_cancelled` | | `CANCELLATION` | `periodType = Normal` | `sw_subscription_cancelled` | +| `UNCANCELLATION` | Any | `sw_*_uncancelled` | | `EXPIRATION` | Any | `sw_*_expired` | +| `SUBSCRIPTION_PAUSED` | Any | `sw_subscription_paused` | +| `NON_RENEWING_PURCHASE` | Any | `sw_non_renewing_purchase` | +| `BILLING_ISSUE` | Any | `sw_billing_issue` | +| `PRODUCT_CHANGE` | Any | `sw_product_change` | | Any event | `price < 0` | `sw_refund` | +### Matching order + +The Superwall event is resolved first, then mapped to a Meta name. Resolution order: + +1. `TEST`, `PRODUCT_CHANGE`, `SUBSCRIPTION_PAUSED`, `NON_RENEWING_PURCHASE`, `BILLING_ISSUE` — matched on the event name, for any `periodType`. This is why a `BILLING_ISSUE` during a trial is `sw_billing_issue`, not a trial event. +2. `price < 0` → `sw_refund`. +3. `periodType` selects the Trial / Intro / Subscription event. +4. Unmatched names within a known `periodType` → `sw_unknown`. + +Only `sw_subscription_start`, `sw_trial_start`, `sw_renewal`, `sw_trial_converted` and `sw_intro_offer_converted` become Meta standard events. Everything else is forwarded under its `sw_*` identifier verbatim. + ## Event format Superwall sends events to Meta's Conversion API in the following format: @@ -157,7 +189,7 @@ POST https://graph.facebook.com/v21.0/{pixel_id}/events?access_token={access_tok "event_name": "Subscribe", "event_time": 1705312200, "event_id": "evt_abc123", - "action_source": "app", + "action_source": "system_generated", "user_data": { "external_id": ["user_12345"] }, @@ -181,7 +213,7 @@ POST https://graph.facebook.com/v21.0/{pixel_id}/events?access_token={access_tok | `event_name` | Meta standard event or custom event name | `"Subscribe"` | | `event_time` | Unix timestamp in seconds | `1705312200` | | `event_id` | Unique event ID for deduplication | `"evt_abc123"` | -| `action_source` | Always set to `"app"` for mobile app events | `"app"` | +| `action_source` | Always set to `"system_generated"` — these are server-side webhook events, not in-app signals | `"system_generated"` | | `user_data` | User identification data | `{"external_id": ["user_12345"]}` | | `custom_data` | Event-specific data including revenue | See below | diff --git a/content/docs/integrations/statsig.mdx b/content/docs/integrations/statsig.mdx index 318d51c..d3bcee6 100644 --- a/content/docs/integrations/statsig.mdx +++ b/content/docs/integrations/statsig.mdx @@ -19,7 +19,7 @@ Fill out the following fields and **click** the **Enable Statsig** button at the ### Features -- **Automatic Event Mapping**: Converts Superwall events to Statsig-friendly event names with `sw_` prefix +- **Automatic Event Mapping**: Converts Superwall events to readable, Title Case Statsig event names - **Revenue Tracking**: Tracks both price (gross) and proceeds (net after fees) - **User Property Enrichment**: Attaches store, product, and transaction metadata to user objects - **Environment Tier Separation**: Uses Statsig's tier system to separate production and staging data @@ -39,47 +39,65 @@ Fill out the following fields and **click** the **Enable Statsig** button at the ### Event mapping -Superwall events are transformed into standardized Statsig events with the `sw_` prefix: +Superwall events are transformed into readable, Title Case Statsig event names. + +Each event also has a stable `sw_*` identifier. The identifier is internal and **not** what Statsig receives — the value in the **Statsig Event** column is what arrives in your Events Stream. + +These names are **not configurable**. There is no per-customer event renaming for Statsig; every project on this integration receives the same Title Case names. #### Trial events -| Superwall Event | Statsig Event | Description | -| ---------------------------------------- | ---------------------- | ----------------------- | -| `initial_purchase` + `periodType: TRIAL` | `sw_trial_start` | Trial period begins | -| `cancellation` + `periodType: TRIAL` | `sw_trial_cancelled` | Trial cancelled | -| `uncancellation` + `periodType: TRIAL` | `sw_trial_uncancelled` | Trial reactivated | -| `expiration` + `periodType: TRIAL` | `sw_trial_expired` | Trial ended | -| `renewal` + `isTrialConversion: true` | `sw_trial_converted` | Trial converted to paid | +| Superwall Event | Statsig Event | Identifier | Description | +| ---------------------------------------- | ------------------- | ---------------------- | ----------------------- | +| `initial_purchase` + `periodType: TRIAL` | `Trial Start` | `sw_trial_start` | Trial period begins | +| `cancellation` + `periodType: TRIAL` | `Trial Cancelled` | `sw_trial_cancelled` | Trial cancelled | +| `uncancellation` + `periodType: TRIAL` | `Trial Uncancelled` | `sw_trial_uncancelled` | Trial reactivated | +| `expiration` + `periodType: TRIAL` | `Trial Expired` | `sw_trial_expired` | Trial ended | +| `renewal` + `isTrialConversion: true` | `Trial Converted` | `sw_trial_converted` | Trial converted to paid | #### Intro offer events -| Superwall Event | Statsig Event | Description | -| ---------------------------------------- | ---------------------------- | -------------------------- | -| `initial_purchase` + `periodType: INTRO` | `sw_intro_offer_start` | Intro offer begins | -| `cancellation` + `periodType: INTRO` | `sw_intro_offer_cancelled` | Intro offer cancelled | -| `uncancellation` + `periodType: INTRO` | `sw_intro_offer_uncancelled` | Intro offer reactivated | -| `expiration` + `periodType: INTRO` | `sw_intro_offer_expired` | Intro offer ended | -| `renewal` + `periodType: INTRO` | `sw_intro_offer_converted` | Intro converted to regular | +| Superwall Event | Statsig Event | Identifier | Description | +| ---------------------------------------- | ------------------------- | ---------------------------- | -------------------------- | +| `initial_purchase` + `periodType: INTRO` | `Intro Offer Start` | `sw_intro_offer_start` | Intro offer begins | +| `cancellation` + `periodType: INTRO` | `Intro Offer Cancelled` | `sw_intro_offer_cancelled` | Intro offer cancelled | +| `uncancellation` + `periodType: INTRO` | `Intro Offer Uncancelled` | `sw_intro_offer_uncancelled` | Intro offer reactivated | +| `expiration` + `periodType: INTRO` | `Intro Offer Expired` | `sw_intro_offer_expired` | Intro offer ended | +| `renewal` + `periodType: INTRO` | `Intro Offer Converted` | `sw_intro_offer_converted` | Intro converted to regular | #### Subscription events -| Superwall Event | Statsig Event | Description | -| ----------------------------------------- | ----------------------------- | ------------------------ | -| `initial_purchase` + `periodType: NORMAL` | `sw_subscription_start` | Subscription begins | -| `renewal` + `periodType: NORMAL` | `sw_renewal` | Subscription renewed | -| `cancellation` + `periodType: NORMAL` | `sw_subscription_cancelled` | Subscription cancelled | -| `uncancellation` + `periodType: NORMAL` | `sw_subscription_uncancelled` | Subscription reactivated | -| `expiration` + `periodType: NORMAL` | `sw_subscription_expired` | Subscription ended | -| `subscription_paused` | `sw_subscription_paused` | Subscription paused | -| `billing_issue` | `sw_billing_issue` | Payment failed | +| Superwall Event | Statsig Event | Identifier | Description | +| ----------------------------------------- | -------------------------- | ----------------------------- | ------------------------ | +| `initial_purchase` + `periodType: NORMAL` | `Subscription Start` | `sw_subscription_start` | Subscription begins | +| `renewal` + `periodType: NORMAL` | `Renewal` | `sw_renewal` | Subscription renewed | +| `cancellation` + `periodType: NORMAL` | `Subscription Cancelled` | `sw_subscription_cancelled` | Subscription cancelled | +| `uncancellation` + `periodType: NORMAL` | `Subscription Uncancelled` | `sw_subscription_uncancelled` | Subscription reactivated | +| `expiration` + `periodType: NORMAL` | `Subscription Expired` | `sw_subscription_expired` | Subscription ended | #### Other events -| Superwall Event | Statsig Event | Description | -| -------------------------- | -------------------------- | ----------------- | -| `product_change` | `sw_product_change` | Plan changed | -| `non_renewing_purchase` | `sw_non_renewing_purchase` | One-time purchase | -| Any event with `price < 0` | `sw_refund` | Refund processed | +Matched on the event name alone, **before** `periodType` is consulted: + +| Superwall Event | Statsig Event | Identifier | Description | +| -------------------------- | ----------------------- | -------------------------- | ------------------- | +| `test` | `Test Event` | `sw_test` | Test event | +| `product_change` | `Product Change` | `sw_product_change` | Plan changed | +| `subscription_paused` | `Subscription Paused` | `sw_subscription_paused` | Subscription paused | +| `non_renewing_purchase` | `Non-Renewing Purchase` | `sw_non_renewing_purchase` | One-time purchase | +| `billing_issue` | `Billing Issue` | `sw_billing_issue` | Payment failed | +| Any event with `price < 0` | `Refund` | `sw_refund` | Refund processed | + +#### Matching order + +Events are matched in this order — which is why a `billing_issue` during a trial arrives as `Billing Issue`, not a trial event: + +1. `test`, `product_change`, `subscription_paused`, `non_renewing_purchase`, `billing_issue` — matched on the event name, for any `periodType`. +2. `price < 0` → `Refund`. +3. `periodType` selects the Trial / Intro / Subscription table. +4. Unmatched names within a known `periodType` → `Unknown` (`sw_unknown`). + +There is no transfer event, so subscription transfers fall through to `Unknown`. ### Event properties @@ -87,7 +105,7 @@ Every Statsig event includes the following structure: #### Core event fields -- `eventName`: The mapped event name with `sw_` prefix +- `eventName`: The mapped Title Case event name (for example, `Trial Start`) - `value`: Revenue amount (when applicable) - `time`: Unix timestamp in milliseconds - `user`: User object with identity and properties @@ -177,7 +195,7 @@ This allows you to: Refunds are automatically detected when `price < 0`: -- Event type: `sw_refund` +- Event name: `Refund` - Value field: Negative amount - All metadata preserved for analysis @@ -213,7 +231,7 @@ This ensures consistent user tracking even for: Check your Statsig project: 1. Navigate to **Metrics** → **Events Stream** -2. Look for events with `sw_` prefix +2. Look for the Title Case Superwall event names (for example, `Trial Start`, `Renewal`) 3. Click on an event to view properties and metadata 4. Verify the `statsigEnvironment.tier` matches your configuration