Meta Ads

Run Meta ads with Superwall as your mobile measurement partner. Superwall attributes installs to your campaigns and sends conversion events back to Meta.

The Meta Ads integration makes Superwall your mobile measurement partner (MMP) for Meta campaigns. Superwall generates the links you put in your ads, attributes installs to the campaign, ad set, and ad that drove them, and sends conversion events back to Meta so it can optimize delivery. Spend and results show up in charts as ROAS, cost per trial, and cost per paid user.

This integration is separate from Meta Conversion API, which forwards subscription webhook events to a Meta Pixel.

We are gradually rolling out performance marketing. If you don't see Performance Marketing under Integrations, reach out to us at support@superwall.com and we'll enable it for your app.

This page describes the new dashboard at app.superwall.com. The Meta page in the legacy dashboard uses different labels and lacks some of the controls described here.

Requirements

  • An iOS app using SuperwallKit 4.16.0 or later. Meta Ads attribution is iOS only for now. On Expo, use expo-superwall 1.2.0 or later and ship a new app build (an EAS Update can't change the native SDK). On Flutter, use superwallkit_flutter 2.5.0 or later.
  • Revenue tracking configured for your app.
  • A Meta ad account you have admin access to, and access to Meta Events Manager. Confirming custom events in Step 3 requires full control of the dataset in your business portfolio.
  • If you sell outside of Superwall paywalls, enable observer mode so transactions are tracked.

Attribution only applies to new installs. The SDK matches an install once, shortly after first launch, and only when that first launch happens within 7 days of the ad click. Users who installed your app before it shipped with SDK 4.16.0 are never attributed, so test with a fresh install.

Step 1: Set up your Meta dataset

Superwall sends conversion events to a Meta dataset. Set it up before connecting Superwall.

Use a web dataset, the kind backed by a Meta Pixel. In Meta, your app is itself a dataset, and you can't use it here: Superwall sends its events as website events, and app datasets don't accept them. The dataset picker in Superwall only lists web datasets, so if yours is missing, this is usually why.

  1. 1

    Create a web dataset

    Go to Meta Events Manager and click Datasets in the left menu. If you already have a web dataset backed by a Meta Pixel, select it and skip to the next step.

    Otherwise, click Connect data, choose Web in the Connect a new data source dialog (not App, even though its description mentions installs and purchases), then follow the prompts to name and create the dataset.

    Events Manager with the Connect a new data source dialog open, listing Web, App, Offline, CRM, and Messaging
  2. 3

    Generate a Conversions API access token

    Open the dataset in Events Manager: click Datasets in the left menu, select your dataset, and click the Settings tab. Scroll to the Conversions API section and find Set up direct integration. Leave Set up with Dataset Quality API selected and click Generate access token. Copy the token; you'll paste it into Superwall in the next step.

    Events Manager lists other ways to set up the Conversions API, like partner integrations. Skip them. Superwall is the direct integration, and the access token is all it needs.

    The dataset's Settings tab showing the Conversions API section with Set up direct integration and the Generate access token button

Step 2: Connect Meta in Superwall

  1. 1

    Open the integration

    In your app's dashboard, go to Integrations, find Performance Marketing, and click the Meta card.

    The Integrations page showing the Performance Marketing section with the Meta card
  2. 2

    Connect your Meta account

    Click Connect Meta account and sign in with a Facebook account that has admin access to your business portfolio. Meta's consent dialog is where you choose which ad accounts Superwall may read. There is no separate account picker afterwards.

  3. 3

    Choose your dataset and paste the access token

    Pick your dataset from the Dataset dropdown. Options are labelled by the business portfolio or ad account that owns them, so several datasets with similar names are still easy to tell apart. If Superwall can't read the list from the Meta account you connected, a text field takes its place and accepts a dataset ID typed in directly.

    Paste the access token from step 1 into Conversions API Access Token and click Save. Superwall checks the pair with Meta first and won't store a dataset and token Meta rejects, showing you what Meta said instead.

    The Configuration card with the Dataset dropdown open, listing datasets labelled by their owning business and ID

Once saved, the page shows your configuration as a summary and the token as its last four characters. Superwall never sends the token back to your browser, so it can't be displayed or copied. To change it, click Edit configuration and then Replace token; leaving the token alone keeps the stored one. The Events to send and Ad links cards only appear once a dataset and token are saved.

Step 3: Choose events to send

Superwall sends these events to your dataset. All six are on by default; leave them on unless you have a reason not to.

Dashboard labelSuperwall eventSent to Meta as
Paywall Openpaywall_opensw_paywall_open
Transaction Starttransaction_startsw_transaction_start
Transaction Abandontransaction_abandonsw_transaction_abandon
Free Trial StartfreeTrial_startsw_freeTrial_start
Subscription Startsubscription_startsw_subscription_start
One-Time PurchasenonRecurringProduct_purchasesw_nonRecurringProduct_purchase
The Events to send card with all six events checked and the Send test events button enabled, above the saved token shown as its last four characters with a Replace token button

Events are sent for every user, not just users attributed to your ads. Meta uses them for delivery optimization and its own attribution.

Because organic users are included, the dataset's Event Match Quality score in Events Manager reads lower than it would for a pixel on a website. Organic users have no ad click for Meta to match against, so their events carry fewer matching signals. This is expected and doesn't affect attribution in Superwall. To raise the score, set user attributes as described in Improving Event Match Quality below.

When Subscription Start is enabled, a free trial converting to paid also sends sw_subscription_start, carrying the purchase's value and currency plus is_trial_conversion: true in custom_data, so Meta sees revenue at the moment a trial starts paying, not just the trial start. Direct paid signups and trial conversions share one event on purpose: Meta's delivery optimizes per event, and pooling both keeps its volume high. Ordinary renewals (rebills) are never sent.

If you connected Meta before trial-conversion forwarding shipped, it activates the next time you click Save changes on this page.

Meta requires you to acknowledge new custom events and allow the domain they come from:

  1. 1

    Send test events

    Click Save changes, then Send test events. Test events are sent from your saved selection, so save first if you've just changed which events are ticked. They appear in your dataset's Test events tab within a few minutes.

  2. 2

    Confirm the custom events

    Meta flags new custom events for review. Confirm they belong to you so they can be used in ad campaigns. In Events Manager, open your dataset, click the Settings tab, and scroll to Data controls. Under Manage event blocking, click Review to open the Event statuses dialog. In its Action required tab, select every event that starts with sw_, click Next, choose Confirm the custom event, click Review, then click Done. The events usually show up here within a few minutes of sending test events.

    After you confirm them, all six move to the Confirmed tab with the status Confirmed by you:

    The Event statuses dialog's Confirmed tab listing the six sw_ events, each marked Confirmed by you

    The Overview tab can also show a Confirm custom event(s) that belong to you warning with a Review events button that leads to the same review. That warning can take up to 30 minutes to appear and sometimes never does, so don't wait for it.

    If the sw_ events are already under Confirmed, there's nothing to do. If Meta blocked an event, it appears under Blocked. Select it and click View details to request a review.

    Confirmed events also stay listed in the Overview events table under the Conversions API integration:

    A confirmed sw_subscription_start event listed in the dataset's Overview events table under the Conversions API integration

Improving Event Match Quality

Meta scores every event on how many signals it can match to a person. Superwall always sends a hashed external_id. Everything else comes from user attributes you set, so setting them as early as you know them is the highest-leverage change you can make:

Superwall.shared.setUserAttributes([
  "email": "someone@example.com",
  "phoneNumber": "+1 555-123-4567",
  "firstName": "Ada",
  "lastName": "Lovelace",
  "city": "London",
  "state": "England",
  "postalCode": "SW1A 1AA",
  "birthday": "1992-05-14"
])

Superwall normalizes each value and hashes it with SHA-256 before it leaves Superwall, the way Meta's Advanced Matching expects. Raw email addresses, phone numbers and names are never sent. An attribute you haven't set is omitted rather than sent empty.

AttributeMeta fieldNotes
emailemLowercased before hashing
phoneNumberphMust include the country code. Plus signs, spaces and punctuation are stripped, so +1 555-123-4567 hashes as 15551234567
firstName / lastNamefn / lnIf you store one whole name under name instead, Superwall splits it on the last space, so Mary Anne Evans becomes Mary Anne and Evans. A single word is sent as the first name only
cityctAccents are folded and everything except letters is stripped, so St. Louis hashes as stlouis
statestUse the two-letter code for the US and Canada and the region name elsewhere, as Meta expects. Superwall lowercases and strips spaces but doesn't convert names to codes
postalCodezpSpaces stripped, so SW1A 1AA hashes as sw1a1aa
birthdaydbYear, month, day. Separators are stripped, so 1992-05-14 works. Anything that isn't eight digits afterwards is dropped rather than sent
countrycountryTwo-letter code. Read for paywall and transaction events only. Purchase events always use the store transaction's country

Superwall also accepts spellings you may already use: phone_number / phone, first_name, last_name, name / fullName / full_name, region for state, postal_code / zip / zipCode, and dateOfBirth. Paywall and transaction events also read date_of_birth, countryCode and country_code.

Purchase events pick up new attributes immediately. Paywall and transaction events pick them up within about five minutes.

Country is sent whenever Superwall has one. Free Trial Start, Subscription Start and One-Time Purchase use the store transaction's country. Paywall and transaction events use the country attribute when set, otherwise the region of the user's matched install or the device's locale.

If the score stays low, the usual causes are attributes stored under names Superwall doesn't read, a phone number without its country code, or a birthday that isn't in year-month-day order. The last two hash to a value that matches nobody.

Under Ad links, Superwall generates the URL you'll use in your Meta ads.

Deleting or disabling a link immediately breaks any live ads pointing at it. Keep links in place while campaigns are running.

You can give a creator a link on your own domain, like yourapp.com/creator, that redirects to an ad link. Create an ad link for each creator. The copied link contains placeholders that only Meta fills in, URL-encoded, so {{campaign.name}} appears as %7B%7Bcampaign.name%7D%7D:

https://install.link/pk_abc123/meta-mfk3x9q2?app_store_language=english&placement=%7B%7Bplacement%7D%7D&campaign_name=%7B%7Bcampaign.name%7D%7D&site_source_name=%7B%7Bsite_source_name%7D%7D&campaignid=%7B%7Bcampaign.id%7D%7D&...

Replace them with your own values and remove the ones you don't use:

https://install.link/pk_abc123/meta-mfk3x9q2?app_store_language=english&campaign_name=creator&campaignid=creator

Set campaignid as well as campaign_name. The Acquisition Campaign chart breakdown groups by campaign ID and shows installs without one as Organic. These installs are recorded with meta as the network, so they count toward Meta in charts, including its ROAS.

Reconnecting and disconnecting

The Meta page header shows whether your account is connected, with two controls beside it.

Reconnect runs the sign-in again against the same app. Use it if Meta's access expires or you granted the wrong ad accounts the first time. Your dataset, token and event selection are left alone.

Disconnect clears the Meta account, the dataset, the Conversions API token and your event selection, and stops sending events. It asks for confirmation first, because none of it can be recovered from Superwall: the token isn't readable once stored, so reconnecting means generating a new one in Events Manager and setting the integration up again.

Disconnecting does not delete your ad links, but it does stop events reaching Meta, so campaigns optimising on sw_ events lose their signal. Your links keep redirecting and installs keep being attributed.

Step 5: Create your Meta campaign

Superwall ad links are website links. That means you'll run a Sales campaign with a website conversion location, not an App Promotion campaign, even though the goal is installs. When someone taps your ad, the link records the click and sends them straight to the App Store.

  1. 1

    Create a manual Sales campaign

    In Ads Manager, click Create and choose the Sales objective. Set the campaign up manually; don't use Meta's AI-assisted setup.

    Meta Ads Manager campaign creation with Manual campaign setup and the Sales objective selected
  2. 2

    Point the ad set at your dataset

    Set Conversion location to Website. Choose your dataset and the conversion event to optimize for. We recommend sw_transaction_start, since starting a transaction signals purchase intent.

    The ad set level showing Website conversion location, the dataset, and the conversion event
  3. 3

    Restrict placements to iOS

    Under Placements, click Show more settings, then limit devices to Mobile and operating systems to iOS, and turn off Audience Network.

  4. 5

    Publish the campaign

    Click Publish to put your campaign and ads live.

Verify it's working

  • Test events appear in the Test events tab of your dataset in Events Manager.
  • Once ads run, attributed users appear in Superwall with acquisition_ user attributes set and an attribution_match event in their event stream.
  • The Advertising charts populate after spend syncs from Meta, which happens daily.

How attribution works

When someone taps your ad, Superwall records the click and sends them to the App Store. If they install and open your app, Superwall looks for a recent ad click that may correspond to that install. When a match can be made, the install is attributed to the campaign. Otherwise, it remains unattributed and appears as organic.

  • Matching runs once per install, within 7 days of the click.
  • No ATT prompt or IDFA is required; matching never uses them.
  • Unmatched installs stay unattributed and show as Organic in charts.

User attributes

A matched install sets these user attributes. Attributes without a value are omitted.

AttributeValue
acquisition_sourceThe network that drove the install, like meta
acquisition_networkSame as acquisition_source
acquisition_channelAlways paid
acquisition_campaign_nameThe Meta campaign name, or the value you set on the link
acquisition_campaign_idThe Meta campaign ID, or the value you set on the link
acquisition_ad_set_nameThe ad set name
acquisition_ad_set_idThe ad set ID
acquisition_ad_nameThe ad name
acquisition_ad_idThe ad ID
acquisition_placementThe Meta placement that showed the ad
acquisition_site_source_nameWhere the ad ran, like ig or fb
acquisition_link_idThe Superwall ad link ID
acquisition_click_idThe matched click ID
acquisition_matched_atWhen the match happened
acquisition_app_store_languageThe link's App Store language. Links that share a language report the same value
acquisition_product_page_idThe Custom Product Page ID, when the link uses one. Omitted for links on the default listing. To tell two links on the same language apart in every case, use acquisition_link_id
acquisition_deeplink_idThe link's deep link ID, when set

Use them as breakdowns and filters in charts, or in audience filters to show different paywalls to users acquired from ads.

The attribution_match event

The SDK tracks attribution_match when the match request completes, matched or not.

ParameterValue
providermmp, or apple_search_ads for Apple Search Ads attribution
matchedWhether the install was attributed
sourceThe network, like meta
confidencehigh, medium, or low
match_scoreThe match score
reasonmatched when the install was attributed. Otherwise no_candidates, below_threshold, ambiguous, or request_failed

The event and its parameters are available in charts and audience filters. It can't be used to trigger a paywall directly.

Charts

With the integration enabled, Superwall pulls campaign spend from Meta daily and adds an Advertising chart group:

The Advertising chart group in the Charts sidebar, listing Ad Spend, ROAS, CPM, CPT, CPP, and Blended CPT
  • Ad Spend
  • ROAS: proceeds divided by spend
  • CPM: cost per thousand impressions
  • CPT: cost per trial
  • CPP: cost per paid user
  • Blended CPT: total spend divided by all trials, including organic

Revenue charts can also be broken down by Acquisition Network and Acquisition Campaign to split any metric by the campaign that acquired the user. Those breakdowns fill in as installs match; unmatched installs group under Organic.

Troubleshooting

Installs aren't being attributed

  • The app must ship SuperwallKit 4.16.0 or later, and the install must be new. Delete and reinstall the app to test; updating an existing install never attributes.
  • The app must be opened for the first time within 7 days of the ad click.
  • SuperwallOptions.eventTrackingBehavior must not be set to .none. That setting disables install matching entirely.
  • The ad link must be saved and enabled. A deleted or disabled link returns a 404 and records no clicks.

My dataset isn't listed in Superwall

The Dataset dropdown only shows web datasets. If the only dataset you see in Events Manager is your app, create a web dataset as described in Step 1 and use that instead.

If a text field appears instead of the dropdown, Superwall couldn't read the dataset list from the Meta account you connected. Type the dataset ID in directly; saving still validates it against Meta.

Events aren't showing in Meta

  • Sandbox purchases are never forwarded. Only production events are sent to Meta; use Send test events to validate before going live.
  • Confirm the dataset ID and access token still validate by editing and re-saving the configuration.
  • Confirm the sw_ custom events under Settings > Data controls > Manage event blocking in Events Manager.
  • Add install.link to the dataset's website traffic allow list. Allowing superwall.com instead is the most common cause: it is the wrong domain.

No transaction or purchase events

  • If you sell outside of Superwall paywalls, enable observer mode.
  • Check that revenue tracking is configured. Subscription events come from App Store server notifications.

How is this guide?

On this page