Superwall

Facebook Pixel

The Meta Conversion API integration sends subscription lifecycle events from Superwall directly to Facebook's server-side Conversion API. This enables accurate attribution for Facebook and Instagram ad campaigns, optimizes ad delivery for subscription events, and provides reliable tracking that isn't affected by browser privacy restrictions or ad blockers.

In the Marketing section within Integrations, you can connect your Facebook Pixel account to Superwall:

Features

  • Server-Side Event Tracking: Events are sent directly to Meta's servers, bypassing browser limitations
  • Standard Event Mapping: Automatically maps subscription events to Meta's standard events (Subscribe, Purchase, StartTrial)
  • Sandbox Environment Support: Separate Pixel ID and access token for testing without affecting production data
  • Test Event Mode: Use test event codes to validate integration in Meta Events Manager
  • Flexible Revenue Reporting: Report either gross revenue or net proceeds after store fees
  • Anonymous User Handling: Configurable behavior for users without an identified app user ID
  • Custom Event Names: Override default event mappings to match your existing Meta Pixel conventions
  • Deduplication: Event IDs prevent duplicate events from being counted multiple times

Configuration

Required Settings

FieldDescriptionExample
integration_idMust be set to "meta""meta"
access_tokenMeta access token with ads_management permission"EAAG..."
pixel_idYour Facebook Pixel ID"123456789012345"
sales_reportingWhether to report gross Revenue or net Proceeds"Revenue" or "Proceeds"

Optional Settings

FieldDescriptionDefault
sandbox_access_tokenSeparate access token for sandbox/test eventsNone (sandbox events skipped)
sandbox_pixel_idSeparate Pixel ID for sandbox/test eventsNone (sandbox events skipped)
test_event_codeTest event code for validation in Events ManagerNone
anonymous_user_behaviorHow to handle events from users without an app user ID"send"
eventNameMappingsCustom mapping to rename default event namesNone

Example Configuration

{
  "integration_id": "meta",
  "access_token": "EAAG1234567890abcdef...",
  "pixel_id": "123456789012345",
  "sales_reporting": "Revenue",
  "sandbox_access_token": "EAAG0987654321fedcba...",
  "sandbox_pixel_id": "543210987654321",
  "test_event_code": "TEST12345",
  "anonymous_user_behavior": "send",
  "eventNameMappings": {
    "sw_subscription_cancelled": "CancelSubscription",
    "sw_refund": "Refund"
  }
}

Getting Your Credentials

Access Token

  1. Go to Meta Events Manager
  2. Select your Pixel from Data Sources
  3. Click Settings tab
  4. Scroll to Conversions API section
  5. Click Generate access token or use an existing System User token
  6. Copy the access token

Note: The access token requires ads_management permission. For production use, Meta recommends using a System User token rather than a personal access token.

Pixel ID

  1. Go to Meta Events Manager
  2. Select your Pixel from Data Sources
  3. The Pixel ID is displayed at the top of the page (e.g., "Pixel ID: 123456789012345")

Test Event Code (Optional)

  1. In Events Manager, select your Pixel
  2. Click the Test Events tab
  3. Your test event code is displayed (e.g., "TEST12345")
  4. Events sent with this code appear in the Test Events tab for validation

Event Mapping

Superwall events are mapped to Meta's standard events when possible. Using standard events enables Meta's machine learning to optimize ad delivery for specific conversion goals.

Standard Event Mappings

Superwall EventMeta Standard EventDescription
sw_subscription_startSubscribeNew paid subscription
sw_trial_startStartTrialFree trial begins
sw_renewalPurchaseSubscription renewal payment
sw_trial_convertedPurchaseTrial converts to paid
sw_intro_offer_convertedPurchaseIntro offer converts to paid

Custom Event Mappings

Events without a standard Meta equivalent are sent with their Superwall event names:

Superwall EventMeta Event Name
sw_subscription_cancelledsw_subscription_cancelled
sw_trial_cancelledsw_trial_cancelled
sw_subscription_expiredsw_subscription_expired
sw_billing_issuesw_billing_issue
sw_refundsw_refund
sw_product_changesw_product_change

Complete Event Mapping Reference

Superwall EventConditionMeta Event
INITIAL_PURCHASEperiodType = TrialStartTrial
INITIAL_PURCHASEperiodType = NormalSubscribe
INITIAL_PURCHASEperiodType = Introsw_intro_offer_start
RENEWALperiodType = TrialPurchase
RENEWALperiodType = NormalPurchase
RENEWALisTrialConversion = truePurchase
CANCELLATIONperiodType = Trialsw_trial_cancelled
CANCELLATIONperiodType = Normalsw_subscription_cancelled
EXPIRATIONAnysw_*_expired
Any eventprice < 0sw_refund

Event Format

Events are sent to Meta's Conversion API in the following format:

API Endpoint

POST https://graph.facebook.com/v21.0/{pixel_id}/events?access_token={access_token}

Request Payload

{
  "data": [
    {
      "event_name": "Subscribe",
      "event_time": 1705312200,
      "event_id": "evt_abc123",
      "action_source": "app",
      "user_data": {
        "external_id": ["user_12345"]
      },
      "custom_data": {
        "value": 9.99,
        "currency": "USD",
        "content_type": "product",
        "content_name": "com.app.premium.monthly",
        "content_ids": ["com.app.premium.monthly"]
      }
    }
  ],
  "test_event_code": "TEST12345"
}

Event Fields

FieldDescriptionExample
event_nameMeta standard event or custom event name"Subscribe"
event_timeUnix timestamp in seconds1705312200
event_idUnique event ID for deduplication"evt_abc123"
action_sourceAlways set to "app" for mobile app events"app"
user_dataUser identification data{"external_id": ["user_12345"]}
custom_dataEvent-specific data including revenueSee below

Custom Data Fields

FieldDescriptionExample
valueRevenue amount (based on sales_reporting setting)9.99
currencyISO 4217 currency code"USD"
content_typeAlways "product" for subscription events"product"
content_nameProduct identifier"com.app.premium.monthly"
content_idsArray containing the product ID["com.app.premium.monthly"]

User Identification

Meta's Conversion API requires user identification for event matching. The integration uses external_id to identify users.

Known Users

For users with an originalAppUserId set in Superwall:

{
  "user_data": {
    "external_id": ["user_12345"]
  }
}

Anonymous Users

For users without an originalAppUserId, the behavior depends on anonymous_user_behavior:

When set to "send" (default):

  • Events are sent with a synthetic ID: $STORE_NAME:originalTransactionId
{
  "user_data": {
    "external_id": ["$APP_STORE:1000000123456789"]
  }
}

When set to "dontSend":

  • Events from anonymous users are skipped entirely

Revenue Tracking

Revenue vs Proceeds

The sales_reporting setting controls which amount is sent in the value field:

  • Revenue: The full price charged to the customer (e.g., $9.99)
  • Proceeds: The amount after store fees are deducted (e.g., $8.49 after Apple's 15-30% commission)

Zero-Value Events

For events without revenue (cancellations, expirations), the value and currency fields are omitted:

{
  "custom_data": {
    "content_type": "product",
    "content_name": "com.app.premium.monthly",
    "content_ids": ["com.app.premium.monthly"]
  }
}

Refund Events

Refunds are sent with negative values:

{
  "event_name": "sw_refund",
  "custom_data": {
    "value": -9.99,
    "currency": "USD",
    "content_type": "product",
    "content_name": "com.app.premium.monthly",
    "content_ids": ["com.app.premium.monthly"]
  }
}

Sandbox Handling

The integration supports separate handling for sandbox (test) events:

With Sandbox Credentials Configured

When both sandbox_pixel_id and sandbox_access_token are provided:

  • Production events use the main credentials
  • Sandbox events use the sandbox credentials
  • Events are tracked separately in Meta Events Manager

Without Sandbox Credentials

When sandbox credentials are not provided:

  • Production events are sent normally
  • Sandbox events are skipped entirely
  • This prevents test data from affecting your production Pixel

Test Event Mode

Use the test_event_code setting to validate your integration without affecting production data:

  1. Get your test event code from Meta Events Manager → Test Events
  2. Add test_event_code to your configuration
  3. Send test events from your app
  4. View events in the Test Events tab of Events Manager

Events sent with a test event code:

  • Appear in the Test Events tab
  • Are not counted in your main event metrics
  • Are not used for ad optimization
  • Help validate your integration before going live

Important: Remove the test_event_code before deploying to production.

Custom Event Names

Use eventNameMappings to override default event names:

{
  "eventNameMappings": {
    "sw_trial_start": "CustomTrialStart",
    "sw_subscription_start": "CustomSubscribe",
    "sw_renewal": "CustomRenewal"
  }
}

Note: Mappings override both standard and custom event names. For example, mapping sw_subscription_start will send your custom name instead of the Meta standard Subscribe event.

Testing the Integration

1. Configure Test Event Code

Add your test_event_code from Meta Events Manager to validate events without affecting production metrics.

2. Send Test Events

Trigger subscription events from your app in sandbox mode.

3. Verify in Meta Events Manager

  1. Go to Meta Events Manager → your Pixel
  2. Click the Test Events tab
  3. Look for events with your test event code
  4. Verify event names, parameters, and user data are correct

4. Check Event Quality

  1. Go to Meta Events Manager → your Pixel → Overview
  2. Check the Event Match Quality score
  3. Higher scores indicate better event matching

5. Test Scenarios

Verify these scenarios work correctly:

  • Production event sends to main Pixel
  • Sandbox event sends to sandbox Pixel (if configured)
  • Sandbox event is skipped when no sandbox credentials
  • Trial start maps to StartTrial
  • Subscription start maps to Subscribe
  • Renewal maps to Purchase
  • Cancellation sends as custom event
  • Anonymous users handled per configuration
  • Revenue is included for paid events
  • Test event code appears in Test Events tab

Best Practices

  1. Use System User tokens: For production, create a System User in Meta Business Manager and use its access token instead of a personal token for better security and stability.

  2. Configure sandbox credentials: Use a separate test Pixel for development to keep your production data clean.

  3. Remove test event code for production: Test event codes prevent events from being used for optimization.

  4. Match user IDs across platforms: Use consistent external_id values between your Pixel browser events and server events for better cross-device attribution.

  5. Monitor Event Match Quality: Check your Event Match Quality score in Events Manager regularly. Scores below 6.0 indicate potential matching issues.

  6. Use standard events when possible: Standard events like Subscribe, Purchase, and StartTrial enable Meta's machine learning to optimize for those specific conversions.

Common Use Cases

Optimizing Campaigns for Subscriptions

  1. Send Subscribe events for new paid subscriptions
  2. Create a Custom Conversion in Meta Ads Manager based on Subscribe
  3. Optimize your campaigns for subscription conversions
  4. Meta will show your ads to users most likely to subscribe

Measuring Trial-to-Paid Conversion

  1. Track StartTrial events for trial starts
  2. Track Purchase events for trial conversions
  3. Create a funnel in Meta Analytics
  4. Analyze conversion rate and time-to-convert

Retargeting Churned Users

  1. Track sw_subscription_cancelled events
  2. Create a Custom Audience of users who cancelled
  3. Run re-engagement campaigns with special offers
  4. Exclude recent subscribers to avoid wasted ad spend

Value-Based Optimization

  1. Include revenue in custom_data.value
  2. Create Value-Based Custom Conversions
  3. Optimize campaigns for highest value subscribers
  4. Meta prioritizes showing ads to users likely to generate more revenue

Troubleshooting

Events Not Appearing in Events Manager

Possible causes:

  • Invalid access token (expired or insufficient permissions)
  • Incorrect Pixel ID
  • Sandbox events without sandbox credentials (events are skipped)
  • Test event code routing events to Test Events tab only

Solutions:

  1. Verify your access token has ads_management permission
  2. Confirm your Pixel ID matches Events Manager
  3. Check for sandbox credentials if testing
  4. Remove test_event_code to see events in main Overview

Authentication Errors (Error 190)

Possible causes:

  • Access token has expired
  • Token doesn't have required permissions
  • Token was revoked

Solutions:

  1. Generate a new access token in Events Manager
  2. Ensure the token has ads_management permission
  3. Consider using a System User token for stability

Low Event Match Quality

Possible causes:

  • Only external_id is being sent
  • No additional user data available

Solutions:

  • Event Match Quality can be improved by including additional user data fields (email, phone, IP address) if available in your webhook data
  • Ensure external_id values are consistent with other data sources

Events Show as "Duplicate"

Possible causes:

  • Same event being sent multiple times
  • Event ID collision

Solutions:

  • The integration uses the Superwall event ID as event_id for deduplication
  • Verify your webhook isn't triggering multiple times for the same event

Wrong Event Names

Possible causes:

  • Custom event name mappings overriding standard events
  • Unexpected event type mapping

Solutions:

  • Review your eventNameMappings configuration
  • Check the event mapping reference table above
  • Test with test_event_code to verify event names

Rate Limits

Meta's Conversion API has the following limits:

LimitValue
Requests per hour10,000 per Pixel
Events per request1,000 maximum
Request body size1MB maximum

The integration sends one event per webhook, which is well within these limits. For high-volume applications, Meta automatically handles queuing.

API Reference

Endpoint

POST https://graph.facebook.com/v21.0/{pixel_id}/events

Authentication

Access token passed as URL parameter:

?access_token={access_token}

Request Headers

Content-Type: application/json
Accept: */*

Response

Success (200 OK):

{
  "events_received": 1,
  "messages": [],
  "fbtrace_id": "ABC123..."
}

Error (400/401/403):

{
  "error": {
    "message": "Invalid OAuth access token.",
    "type": "OAuthException",
    "code": 190,
    "fbtrace_id": "ABC123..."
  }
}

Additional Resources

How is this guide?

Edit on GitHub