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
| Field | Description | Example |
|---|---|---|
integration_id | Must be set to "meta" | "meta" |
access_token | Meta access token with ads_management permission | "EAAG..." |
pixel_id | Your Facebook Pixel ID | "123456789012345" |
sales_reporting | Whether to report gross Revenue or net Proceeds | "Revenue" or "Proceeds" |
Optional Settings
| Field | Description | Default |
|---|---|---|
sandbox_access_token | Separate access token for sandbox/test events | None (sandbox events skipped) |
sandbox_pixel_id | Separate Pixel ID for sandbox/test events | None (sandbox events skipped) |
test_event_code | Test event code for validation in Events Manager | None |
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
{
"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
- Go to Meta Events Manager
- Select your Pixel from Data Sources
- Click Settings tab
- Scroll to Conversions API section
- Click Generate access token or use an existing System User token
- 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
- Go to Meta Events Manager
- Select your Pixel from Data Sources
- The Pixel ID is displayed at the top of the page (e.g., "Pixel ID: 123456789012345")
Test Event Code (Optional)
- In Events Manager, select your Pixel
- Click the Test Events tab
- Your test event code is displayed (e.g., "TEST12345")
- 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 Event | Meta Standard Event | Description |
|---|---|---|
sw_subscription_start | Subscribe | New paid subscription |
sw_trial_start | StartTrial | Free trial begins |
sw_renewal | Purchase | Subscription renewal payment |
sw_trial_converted | Purchase | Trial converts to paid |
sw_intro_offer_converted | Purchase | Intro offer converts to paid |
Custom Event Mappings
Events without a standard Meta equivalent are sent with their Superwall event names:
| Superwall Event | Meta Event Name |
|---|---|
sw_subscription_cancelled | sw_subscription_cancelled |
sw_trial_cancelled | sw_trial_cancelled |
sw_subscription_expired | sw_subscription_expired |
sw_billing_issue | sw_billing_issue |
sw_refund | sw_refund |
sw_product_change | sw_product_change |
Complete Event Mapping Reference
| Superwall Event | Condition | Meta Event |
|---|---|---|
INITIAL_PURCHASE | periodType = Trial | StartTrial |
INITIAL_PURCHASE | periodType = Normal | Subscribe |
INITIAL_PURCHASE | periodType = Intro | sw_intro_offer_start |
RENEWAL | periodType = Trial | Purchase |
RENEWAL | periodType = Normal | Purchase |
RENEWAL | isTrialConversion = true | Purchase |
CANCELLATION | periodType = Trial | sw_trial_cancelled |
CANCELLATION | periodType = Normal | sw_subscription_cancelled |
EXPIRATION | Any | sw_*_expired |
| Any event | price < 0 | sw_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
| Field | Description | Example |
|---|---|---|
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" |
user_data | User identification data | {"external_id": ["user_12345"]} |
custom_data | Event-specific data including revenue | See below |
Custom Data Fields
| Field | Description | Example |
|---|---|---|
value | Revenue amount (based on sales_reporting setting) | 9.99 |
currency | ISO 4217 currency code | "USD" |
content_type | Always "product" for subscription events | "product" |
content_name | Product identifier | "com.app.premium.monthly" |
content_ids | Array 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:
- Get your test event code from Meta Events Manager → Test Events
- Add
test_event_codeto your configuration - Send test events from your app
- 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
- Go to Meta Events Manager → your Pixel
- Click the Test Events tab
- Look for events with your test event code
- Verify event names, parameters, and user data are correct
4. Check Event Quality
- Go to Meta Events Manager → your Pixel → Overview
- Check the Event Match Quality score
- 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
-
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.
-
Configure sandbox credentials: Use a separate test Pixel for development to keep your production data clean.
-
Remove test event code for production: Test event codes prevent events from being used for optimization.
-
Match user IDs across platforms: Use consistent
external_idvalues between your Pixel browser events and server events for better cross-device attribution. -
Monitor Event Match Quality: Check your Event Match Quality score in Events Manager regularly. Scores below 6.0 indicate potential matching issues.
-
Use standard events when possible: Standard events like
Subscribe,Purchase, andStartTrialenable Meta's machine learning to optimize for those specific conversions.
Common Use Cases
Optimizing Campaigns for Subscriptions
- Send
Subscribeevents for new paid subscriptions - Create a Custom Conversion in Meta Ads Manager based on
Subscribe - Optimize your campaigns for subscription conversions
- Meta will show your ads to users most likely to subscribe
Measuring Trial-to-Paid Conversion
- Track
StartTrialevents for trial starts - Track
Purchaseevents for trial conversions - Create a funnel in Meta Analytics
- Analyze conversion rate and time-to-convert
Retargeting Churned Users
- Track
sw_subscription_cancelledevents - Create a Custom Audience of users who cancelled
- Run re-engagement campaigns with special offers
- Exclude recent subscribers to avoid wasted ad spend
Value-Based Optimization
- Include revenue in
custom_data.value - Create Value-Based Custom Conversions
- Optimize campaigns for highest value subscribers
- 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:
- Verify your access token has
ads_managementpermission - Confirm your Pixel ID matches Events Manager
- Check for sandbox credentials if testing
- Remove
test_event_codeto 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:
- Generate a new access token in Events Manager
- Ensure the token has
ads_managementpermission - Consider using a System User token for stability
Low Event Match Quality
Possible causes:
- Only
external_idis 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_idvalues 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_idfor 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
eventNameMappingsconfiguration - Check the event mapping reference table above
- Test with
test_event_codeto verify event names
Rate Limits
Meta's Conversion API has the following limits:
| Limit | Value |
|---|---|
| Requests per hour | 10,000 per Pixel |
| Events per request | 1,000 maximum |
| Request body size | 1MB 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}/eventsAuthentication
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 GitHubApple Search Ads
Integrate Apple Search Ads with Superwall. View details on users acquired via search ads, visualize conversions from Apple Search Ads in charts, and create powerful campaign filters to target users using search ad data. Search ad integration requires 3.12.0 of the Superwall SDK or higher.
Mixpanel
The Mixpanel integration allows you to automatically send Superwall subscription and payment events to your Mixpanel project.