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
Create an audience
Open the campaign whose placement shows the paywall, and add an audience. See Adding a new audience.
- 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
Add the paywall
On the audience's Paywalls tab, click Add paywall and pick the paywall made for that ad.
- 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 from | Filter |
|---|---|
| A network | Network (acquisition_network) is meta |
| Any paid install | Channel (acquisition_channel) is paid |
| One campaign | Campaign ID (acquisition_campaign_id) is your campaign's ID |
| A group of campaigns | Campaign name (acquisition_campaign_name) contains a word they share, like summer |
| An ad set or ad group | Ad set ID (acquisition_ad_set_id) is its ID |
| One ad | Ad ID (acquisition_ad_id) is its ID |
| An Apple Search Ads keyword | Keyword name (acquisition_keyword_name) is the keyword. Needs Advanced search ads |
| A Google Ads keyword | Keyword (acquisition_keyword) is the keyword, for Search campaigns |
| A Custom Product Page | Custom 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
| Source | What it sets |
|---|---|
| Superwall MMP | Network, 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 Ads | apple_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 MMP | Whatever your app passes with setUserAttributes. See Use another MMP. |
Your own parameters on Superwall ad links
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 field | Superwall attribute |
|---|---|
media_source | acquisition_network |
campaign | acquisition_campaign_name |
campaign_id | acquisition_campaign_id |
adset | acquisition_ad_set_name |
adset_id | acquisition_ad_set_id |
adgroup | acquisition_ad_name |
adgroup_id | acquisition_ad_id |
af_siteid | acquisition_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 field | Superwall attribute |
|---|---|
network | acquisition_network |
campaign | acquisition_campaign_name |
adgroup | acquisition_ad_set_name |
creative | acquisition_ad_name |
Branch (link data, from the session callback, when +clicked_branch_link and +is_first_session are true):
| Branch field | Superwall attribute |
|---|---|
~channel | acquisition_network |
~campaign | acquisition_campaign_name |
~campaign_id | acquisition_campaign_id |
~ad_set_name | acquisition_ad_set_name |
~ad_set_id | acquisition_ad_set_id |
~ad_name | acquisition_ad_name |
~ad_id | acquisition_ad_id |
~placement | acquisition_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
setUserAttributesfrom 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 withsetUserAttributesare cleared, like any user attribute. - Opting out of tracking stops the match. With
eventTrackingBehaviorset to.none(NONEon Android), Superwall MMP doesn't match the install, so these attributes stay empty and attribution audiences don't match..superwallOnlykeeps 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.
Related
How is this guide?
Audiences
Target users with Superwall campaign audiences: filters, rule groups, entitlement checks and limits, plus attribution, event count and app version filters.
Starting an Experiment
Run a paywall A/B test in Superwall: add paywalls to an audience, set presentation percentages, reset assignments, create holdouts and remove variants.