Campaigns

Target Paywalls by Ad Campaign

Show a different paywall to users from a given ad network, campaign, ad set, ad or keyword, using the acquisition attributes Superwall sets on each install.

Users who install from an ad can see a paywall made for that ad. Superwall stores where each install came from as acquisition_ user attributes, like acquisition_network and acquisition_campaign_name. Filter an audience on them to give users from a network, campaign, ad set, ad or keyword their own paywall, such as one that repeats the offer in the ad they tapped.

Requirements

  • An app with install attribution. Stripe (web) apps don't have it, so their audience filters have no Attribution section.
  • At least one source of attribution:
    • Superwall MMP, through the Meta Ads or Google Ads integration. See each page's requirements for SDK versions.
    • The Apple Search Ads integration, Basic or Advanced. Names, like campaign and keyword names, need Advanced.
    • Another MMP, like AppsFlyer, Adjust, Branch or Singular, with your app passing its attribution to Superwall. See Use another MMP.

Show a paywall to users from an ad

  1. 1

    Create an audience

    Open the campaign whose placement shows the paywall, and add an audience. See Adding a new audience.

  2. 2

    Filter on an attribution attribute

    Click Add filter, open the Attribution section of the property picker, and pick an attribute. For example, Network is meta. Click Save filters.

  3. 3

    Add the paywall

    On the audience's Paywalls tab, click Add paywall and pick the paywall made for that ad.

  4. 4

    Put the audience above broader ones

    Audiences are checked top to bottom, and the first match wins. Drag the new audience above any audience that matches everyone. See Reordering audiences.

Users whose install isn't attributed don't have these attributes, so they skip this audience and fall through to the next one.

Examples

To show a paywall to users fromFilter
A networkNetwork (acquisition_network) is meta
Any paid installChannel (acquisition_channel) is paid
One campaignCampaign ID (acquisition_campaign_id) is your campaign's ID
A group of campaignsCampaign name (acquisition_campaign_name) contains a word they share, like summer
An ad set or ad groupAd set ID (acquisition_ad_set_id) is its ID
One adAd ID (acquisition_ad_id) is its ID
An Apple Search Ads keywordKeyword name (acquisition_keyword_name) is the keyword. Needs Advanced search ads
A Google Ads keywordKeyword (acquisition_keyword) is the keyword, for Search campaigns
A Custom Product PageCustom product page ID (acquisition_product_page_id) is the page's ID

Combine filters to narrow it down, like Network is meta and Ad set name contains trial. IDs don't change when a campaign is renamed, so prefer them when you target one campaign.

Attribution attributes

When you add a filter, the property picker lists these in an Attribution section above User. The section always lists them, even before your app has any attribution data. Until your app sends at least one acquisition_ attribute, the section explains how to fill them in, with a Set up Superwall MMP button when it's available for your app.

Prop

Type

Any other acquisition_ attribute your app has sent also appears in the section, with a readable label. For example, Apple Search Ads sets acquisition_keyword_name, which appears as Keyword name.

The filters are saved as user attributes, like user.acquisition_network, so audiences that already filter on these attributes under User keep working.

Where the attributes come from

SourceWhat it sets
Superwall MMPNetwork, channel, campaign, ad set, ad, placement and site source from the ad link, plus the Custom Product Page ID. See Meta Ads user attributes and Google Ads attributes. Google Ads sets IDs, not names, plus the keyword and device.
Apple Search Adsapple_search_ads as the network, and IDs for the campaign, ad group, ad and keyword. Advanced search ads adds the campaign, ad group and keyword names. Apple doesn't name ads.
Another MMPWhatever your app passes with setUserAttributes. See Use another MMP.

Any other query parameter you add to a Superwall ad link reaches matched installs as acquisition_ plus the parameter's name. For example, utm_content=spring arrives as acquisition_utm_content with the value spring, ready to filter on without an app update.

  • Names are lowercased, and characters other than letters, digits and underscores become underscores. Names are cut at 40 characters, and values at 200.
  • A link carries up to 20 of your own parameters.
  • Superwall ignores a parameter whose name matches a built-in attribute or an ad network click ID, like fbclid, and a value that's still an unfilled placeholder, like {{campaign.id}}, or looks like an email address.

Use another MMP

If AppsFlyer, Adjust, Branch, Singular or another MMP attributes your installs, read the attribution from its SDK callback and pass it to Superwall with setUserAttributes, using the acquisition_ keys above. The values then appear under Attribution and you can target them.

For acquisition_network, use a consistent, lowercase value, like your MMP's media source or network name, so your filters match reliably. Set only the attributes your MMP returns a value for.

AppsFlyer (conversion data, from onConversionDataSuccess, when af_status is Non-organic):

AppsFlyer fieldSuperwall attribute
media_sourceacquisition_network
campaignacquisition_campaign_name
campaign_idacquisition_campaign_id
adsetacquisition_ad_set_name
adset_idacquisition_ad_set_id
adgroupacquisition_ad_name
adgroup_idacquisition_ad_id
af_siteidacquisition_site_source_name

Some networks return their ad set and ad in af_adset, af_adset_id, af_ad, and af_ad_id instead. Check AppsFlyer's payload for each network you run.

Adjust (attribution object, from the attribution callback):

Adjust fieldSuperwall attribute
networkacquisition_network
campaignacquisition_campaign_name
adgroupacquisition_ad_set_name
creativeacquisition_ad_name

Branch (link data, from the session callback, when +clicked_branch_link and +is_first_session are true):

Branch fieldSuperwall attribute
~channelacquisition_network
~campaignacquisition_campaign_name
~campaign_idacquisition_campaign_id
~ad_set_nameacquisition_ad_set_name
~ad_set_idacquisition_ad_set_id
~ad_nameacquisition_ad_name
~ad_idacquisition_ad_id
~placementacquisition_placement

Branch doesn't return Meta Ads attribution in the session callback, so these fields are empty for installs from Meta Ads.

For example, with Adjust. This skips organic installs and lowercases the network:

func adjustAttributionChanged(_ attribution: ADJAttribution?) {
  guard let attribution,
        let network = attribution.network,
        network != "Organic" else { return }
  let attributes: [String: Any?] = [
    "acquisition_network": network.lowercased(),
    "acquisition_campaign_name": attribution.campaign,
    "acquisition_ad_set_name": attribution.adgroup,
    "acquisition_ad_name": attribution.creative,
  ]
  // A nil value removes the attribute, so drop nils first.
  let nonNil: [String: Any] = attributes.compactMapValues { $0 }
  Superwall.shared.setUserAttributes(nonNil)
}
adjustConfig.setOnAttributionChangedListener { attribution ->
  val network = attribution.network
  if (network == null || network == "Organic") return@setOnAttributionChangedListener
  val attributes = mapOf(
    "acquisition_network" to network.lowercase(),
    "acquisition_campaign_name" to attribution.campaign,
    "acquisition_ad_set_name" to attribution.adgroup,
    "acquisition_ad_name" to attribution.creative,
  ).filterValues { it != null }
  Superwall.instance.setUserAttributes(attributes)
}

Use one attribution source for these attributes. Superwall MMP and Apple Search Ads write the same acquisition_ keys and overwrite any matching values you set. Keys they don't write keep your values, so mixing sources leaves a user with attributes from more than one source.

When the attributes arrive

Attribution isn't always there the moment your app opens, so a paywall on the first launch can be shown before it arrives.

  • Superwall MMP matches the install once, on first launch. With iOS SDK (SuperwallKit) 4.18.0 or later, or Android SDK 2.9.0 or later, a paywall on that launch waits up to 2 seconds for the match when its placement's audiences use an acquisition_ attribute. If the match takes longer, the audiences are checked without it.
  • Apple Search Ads attribution comes from Apple's servers after install, and a paywall doesn't wait for it. If it isn't ready, the SDK tries again when the app returns to the foreground.
  • Another MMP's attributes are set when your code calls setUserAttributes from the MMP's callback. A paywall doesn't wait for them.

Audiences are checked each time a placement fires, so once the attributes are set, the next placement can match your attribution audience. If the first paywall matters most, such as one on app_install or app_launch, expect some ad users to see your default paywall there.

Things to know

  • Attribution only applies to new installs. Superwall MMP matches an install once, within 7 days of the ad click. Users who installed before your app had Superwall MMP set up never get attributes from it.
  • The attributes survive a reset. After reset() or identifying a different user, the SDK sets the Superwall MMP and Apple Search Ads attributes again for the new user. Attributes you set yourself with setUserAttributes are cleared, like any user attribute.
  • Opting out of tracking stops the match. With eventTrackingBehavior set to .none (NONE on Android), Superwall MMP doesn't match the install, so these attributes stay empty and attribution audiences don't match. .superwallOnly keeps the match.
  • Values match as sent. Filters compare the stored value. Values from another MMP arrive as your code sends them, so lowercase the network as in the example above.

How is this guide?

On this page