SKAdNetwork ad networks integration guide

At a glance: This article details how ad networks integrate with AppsFlyer for SKAdNetworks, enabling them to optimize campaigns and to be attributed to the traffic they generate. 

SKAdPartnerBadges.png

Learn more about the AppsFlyer SKAdNetwork solution for advertisers:

SKAdNetwork solution guide | SKAdNetwork dashboard by AppsFlyer

AppsFlyer offering for ad networks

  • Be attributed for campaign conversions:
    • Integration with AppsFlyer ensures that the ad network is attributed for all installs, in-app events, and revenue resulting from campaigns run on advertisers' behalf.
    • Without integration in place, installs, in-app events, and revenue are attributed as organic and not to the ad network. 
  • Campaign optimization:
    • The conversion value in the postback is encoded.
    • AppsFlyer enables ad networks to translate the conversion value of each postback, ensuring ad networks can optimize their campaigns based on the decoded value per app.
  • No need for direct integration with each advertiser:
    SKAd postbacks are sent only to the ad network. Advertisers can consume the data by either: 
    • Individual integration with each ad network. A solution that is not scalable, neither for ad networks nor for advertisers. 
    • A single integration with AppsFlyer. Scalable for both the advertiser and the ad network.
  • Increase your prominence in AppsFlyer: 
    • Ad networks having SKAdNetwork integration are certified and identified as such in the AppsFlyer dashboard. 
    • This assures advertisers that they are working with ad networks that can be measured deterministically via this attribution model.

SKAdNetwork data flow

PostbackProcess_us-en.png

 The full SKAd postback flow is as follows: 

  1. iOS sends the SKAd postback to the attributed ad network.
  2. The ad network does one of the following:
    • Enrich and forward: Enrich the SKAd postback with the ad network campaign ID (to overcome the SKAdNetwork limitation of 100 campaign IDs), campaign name, and the iOS device IP address. 
    • Redirect: The network requests the iOS device to redirect the postback directly to AppsFlyer. In this case, campaign data enrichment will be performed via a separate API between AppsFlyer and the ad network.
  3. AppsFlyer validates and decodes the postback. Then, it sends the decoded and enriched postback to the ad network (in parallel to sharing it with the advertiser).

Main integration parts

SKAdNetwork integration between AppsFlyer and ad networks consists of the following main parts as described in this article:

  • Ad networks send SKAdNetwork data to AppsFlyer
  • Ad networks receive enriched and decoded data from AppsFlyer via postbacks

Send data to AppsFlyer

After the ad network receives the SKAd postback from the device, the add network forwards it to AppsFlyer using one of the following methods:

  • Enrich and forward (POST)
  • Redirect (HTTP 307 redirect method)

Upon receipt of a SKAd postback, AppsFlyer performs the following:

  • Postback validation: ensure that it is unique.
  • Conversion value decode: Generate attribution install/in-app event records.
  • Send decoded postbacks to the ad network.
  • Make attribution data available to advertisers via dashboards and reports.

Enrich and forward

Using this method, ad networks forward each postback received from the device to AppsFlyer.

The ad network:

  • Receives the postback from the iOS device
  • Enriches the postback with:
    • Ad network campaign ID and campaign name
    • IP address received from the device, required mainly for geo resolution purposes. 
    • The timestamp of the postback sent from the iOS device
  • Sends the postback to AppsFlyer.
SKAdNetwork enriched postback protocol
Endpoint

https://skadpostbacks.appsflyer.com/api/postbacks

HTTP method POST
Accepted content types application/json
Return codes

200 OK: Postback received having valid format and signature

400: Bad request: Malformed JSON, empty, JSON, invalid signature

SKAdNetwork enriched postback JSON parameters

Parameter

Format

Description

Source

version String

SKAdNetwork version

Example: "version":"2.0"

SKAd postback
ad-network-id String

Ad network ID

Example: "ad-network-id":" zzzzzzzzzz.skadnetwork"

SKAd postback
campaign-id Integer

SKAdNetwork campaign ID

Example: "campaign-id":23

SKAd postback
transaction-id String

SKAdNetwork postback transaction ID

SKAd postback
app-id Integer Target app ID SKAd postback
attribution-signature String Attribution signature SKAd postback 
redownload Boolean When redownload = true, it means the user downloaded the app from the app store again. SKAd postback
source-app-id Integer

Source App ID (publisher)

SKAd postback
conversion-value Integer AppsFlyer SDK sets the conversion value according to advertiser settings. SKAd postback 
ad-network-campaign-id String

To enable a common language between ad networks, advertisers, and AppsFlyer, you must provide your campaign-id.

Ad network
ad-network-campaign-name String Ad network campaign name associated with the ad network campaign ID. This name displays in dashboards and reports.  Ad network
ip String

The IP address of the device sending the postback.

iPv4 and IPv6 addresses supported.

Example: "ip":"198.51.100.1"

Ad network
timestamp String

Time the ad network received the SKAdNetwork postback. 10-digit epoch UNIX timestamp. 

Example:

August 4, 2020, 07:25 UTC translates to "timestamp": "1596525944"

Ad network

Curl example—enriched SKAd postback

curl --location --request POST 'https://skadpostbacks.appsflyer.com/api/postbacks' \
--header 'Content-type: application/json' \
--data-raw '{
    "version":"2.0",
    "app-id": 888707086,
    "ip": "192.0.2.0",
    "ad-network-campaign-name": "skadnetwork_abc_campaign",
    "source-app-id": 888707074,
    "ad-network-id": "abcabcabc.skadnetwork",
    "transaction-id": "68eb3d91-15f5-44ee-9267-25c7655c20b6",
    "redownload": false,
    "attribution-signature": "MDYCGQCsQ4y8d4BlYU9b8Qb9BPWPi+ixk/OiRysCGQDZZ8fpJnuqs9my8iSQVbJO/oU1AXUROYU=",
    "timestamp": "1597156649200",
    "ad-network-campaign-id": "222222",
    "conversion-value": 63,
    "campaign-id": 99
}'

Redirect

Redirect_us-en__2_.png

Using this method, the ad network responds to the device with an HTTP redirect command (307), requesting the device to send the postback directly to AppsFlyer, to the following URL:

https://skadredirect.appsflyer.com/api/redirects

The redirect method has the following advantages:

  • Increased advertiser trust: The MMP acts on behalf of an advertiser. By providing AppsFlyer access to the postback firsthand, advertisers are confident that postbacks are not manipulated in transit.
  • No processing required by the ad network: Ad networks respond with the redirect command (to the device), thus eliminating the need to process postbacks. In comparison, the enrich and forward method requires that ad networks consume the postback, enrich it with additional parameters, and finally forward it to AppsFlyer.

Campaign mapping API:

  • The redirect method requires that the ad network and AppsFlyer maintain a campaign mapping API to overcome the SKAdNetwork limitation of 0-100 campaign IDs.
  • AppsFlyer will query the network once a day for the updated translation table from SKAdNetwork campaign ID to the network campaign ID.
  • AppsFlyer will soon share the spec of this protocol. For more details, reach out to your partner development manager.

Receive data from AppsFlyer

Prior to receiving your first postback, take into consideration the following: 

  • Ad-networks must define the postback end-point and template (reach out to your AppsFlyer Partner Development Manager or to integrations@appsflyer.com to ensure this is in place).
  • AppsFlyer sends SKAdNetwork postbacks using the same mechanism as with the existing postbacks used for deterministic and probabilistic modeling attribution.

Principles

  • For each postback sent from the ad network to AppsFlyer, AppsFlyer sends:
    • One install postback. Redownloads are signaled by the redownload parameter. 
    • Zero to several in-app event postbacks. The exact number depends on the translation of the conversion value.  See simulated postbacks.
  • When you consume postbacks, the same install or event can be attributed by more than one AppsFlyer attribution solution. Use the attribution_source parameter to differentiate between postback types. 

Postback macros

Postback macro (name)

Description

Format and example Relevant only to in-app events 

site_id

The app publishing the ad (source app ID)

String: 876534

 

install_time

Estimated by AppsFlyer based on the updateConversion window. Provided as a 10-digit UNIX timestamp

  • String: 1596119460 
  • Translates to July 30, 2020, 14:31 UTC.
 

event_time

 

  • String: 1596119460 
  • Translates to July 30, 2020, 14:31 UTC
 

skad_ad_network_time

Time the postback was received by the ad network from the iOS device. Reported by the ad network. Provided as a 10-digit UNIX timestamp

  • String: 1596119460 
  • Translates to July 30, 2020, 14:31 UTC



 


skad_af_received_time

Time AppsFlyer received the postback from the ad network. Provided as a 10-digit UNIX timestamp

 

  • String: 1596119460 
  • Translates to July 30, 2020, 14:31 UTC

 

event_name

Event name 

  • af_purchase
  • af_login
  • af_skad_revenue
  • or as set by the advertiser 

String: af_purchase, abc123

 

Yes

revenue

Revenue amount using the specified currency code

Number: 5, 20, 0.4

Yes

currency

Currency code being the app-specific currency set by the advertiser

String: EUR, USD, ZAR

Yes

attribution_source

The source of the attribution data:

SKAdNetwork: skadnetwork

String: skadnetwork

 

app_id

App ID (advertiser app)

String: ID123456790

 

country

Install country determined using IP address sent by the ad network

String: US, UK, ZA 

 

campaign

Campaign name populated using ad-network-campaign-name sent in the postback from the ad network

String: UA_US_23+

 

campaign_id

Ad network Campaign ID populated using ad network-campaign-id sent in the postback from the ad network

String: 3456745

 

redownload

Possible values: true, false

When redownload = true, it means the user downloaded the app from the app store again

Boolean: true, false

 

skad_ambiguous _event

Events received during the first 48-hours after an advertiser changes the SKAdNetwork settings in the dashboard. Due to the various timers employed by SKAdNetwork AppsFlyer can't map the event accurately.

Boolean: true, false

 

skad_campaign_id

SKAdNetwork campaign ID as provided by the original SKAdNetwork postback

56, 23

 

af_skad_nonce

A unique random identifier enabling partners to identify duplicate postbacks

 

 

Macros available in the postback to Ad network partners

SKAd postback examples

Example of an install SKAd postback sent by AppsFlyer

http://YourCompanyDomain.com/event?site_id=(publisher-id)&install_time=(timestamp)
&event_time=(timestamp)&skan_ad_network_time=(timestamp)
&skan_af_received_time=(timestamp)
&attribution_provider=skadnetwork
&app_id=(id123456789)&country=(ZA)&campaign=(campaign-name)
&campaign_id=(campaign-id)&skad_ambiguous_event=(boolean)
&redownload=(boolean)
&af_skad_nonce=(uuid)

Example of an in-app SKAd postback sent by AppsFlyer

http://YourCompanyDomain.com/event?site_id=(publisher-id)&install_time=(timestamp)
&event_time=(timestamp)&skan_ad_network_time=(timestamp)
&skan_af_received_time=(timestamp)&revenue=(value)
&currency=(code)&event_name=(event-name)&attribution_provider=skadnetwork
&app_id=(id123456789)&country=(ZA)&campaign=(campaign-name)
&campaign_id=(campaign-id)&skad_ambiguous_event=(boolean)
&redownload=(boolean)
&af_skad_nonce=(uuid)

Integration testing

The AppsFlyer solution for SKAdNetwork is live and ready. To validate the integration with AppsFlyer, use either or both of the following methods. 

  • Simulated postbacks: based on AppsFlyer test apps
  • Real SKAdNetwork postbacks: based on actual SKAd traffic received by the network

To receive real SKAdNetwork postbacks from iOS devices, the ad network completes the following:

 Simulated postbacks

  • Using this method, the ad network sends AppsFlyer preprepared postbacks to AppsFlyer test apps, as detailed in the table below. AppsFlyer replies with decoded postbacks to the ad network.
  • Each test app has a different conversion value mapping, as detailed in the table.
App ID Conversion mode Example
ID888707085 Revenue, in $1 units conversion value = 7, AppsFlyer responds with:
  • Install postback
  • af_purchase postback with value of $7
ID888707086 Conversion, including the in-app events:
  • af_level_complete
  • af_login
  • af_purchase
  • af_register
  • af_subscription
  • af_custom_event
For conversion value = 63, AppsFlyer responds with:
  • Install postback
  • af_level_complete postback
  • af_login postback
  • af_purchase postback
  • af_register postback
  • af_subscription postback
  • af_custom_event postback
ID888707087 Engagement, measured using af_purchase event For conversion value = 3, AppsFlyer responds with:
  • Install postback
  • 3 postbacks of af_revenue event
Responsibility Action
Ad network Notify AppsFlyer via your partner development manager (or email to integations@appsflyer.com) as to your SKAdNetwork network ID, provided by Apple.
Ad network
  • Send dozens of simulated postbacks, using the test apps listed in the preceding table. 
  • Set the app_id and conversion value as listed in the preceding table. 
  • Since Ad networks can't generate Apple compatible signatures, the simulated postbacks don't have to include the signature fields. AppsFlyer will not verify them for simulated postbacks.
  • Ad networks send the postback using either the POST or REDIRECT approach.
AppsFlyer Responds with the decoded postbacks to the endpoint designated by the ad network during integration
Integration steps
Responsibility Action
AppsFlyer Process the postback and sends postbacks to the ad network.
Ad network
  • Ad network receives and decodes the translated postbacks.
  • In-app postbacks sent by AppsFlyer match the expected flows. For example, conversion value 3 for app ID888707087, the ad network receives 3 postbacks of af_purchase event. 
Test criteria

Real environment

Using this method, the ad network sends AppsFlyer actual SKAd postbacks from live apps. 

Responsibility Action
Ad network Notify AppsFlyer via your partner development manager (or email to integations@appsflyer.com) as to your SKAdNetwork network ID, provided by Apple.
Ad network and AppsFlyer Agree on a mutual customer (having integrated the most recent AppsFlyer SDK) to use for postback integration verification.
Ad network Send app SKAd postbacks to AppsFlyer, using one of the methods described in this article.
AppsFlyer Send decoded postbacks to the ad network in accordance with the conversion value mapping set by the advertiser.
Testing integration
Responsibility Action
Ad network Notify AppsFlyer as to the quantity of SKAd postbacks sent during a specified period for the agreed mutual customer.
AppsFlyer Verify the count of postbacks received versus the count sent by the ad network.
AppsFlyer

Share with the ad network the count of postbacks sent to the network for a given app broken down by type:

  • Install/redownload postbacks
  • In-app postbacks.
Note: If you use the same endpoint for probabilistic postbacks, ensure that you filter using attribution_provider=skadnetwork to distinguish SKAd Network postbacks from other postbacks.
AppsFlyer and Ad network  [Optional] For deeper validation, AppsFlyer shares with the network a CSV file containing copies of the postbacks. 
Test criteria

Clarifications

Clarifications relating to mandatory fields, enrichment, certification, and more.

FAQ

Questions and answers about postbacks

Are the enrichment fields mandatory? 

For the present, we will process the postback even if it is missing one or more of the following enrichment parameters. Consider that the information is required for the following reasons: 

  • Ad network campaign ID: If we have cost integration with you then this is reported using your campaign ID. 
  • Ad network campaign name: Many advertisers relate to the campaign name and not the campaign number. 
  • IP address: Required for geo resolution. 
  • Timestamp: Assists us to attribute the install to the correct date. 

Can we send either our campaign ID, or our campaign name but not both?

See the previous answer. Consider populating both ID and name with the same value. 

We are using Enrich and Forward. Can we add key-value pairs that are not in the AppsFlyer specification? 

Yes, you can. We will process the postback and disregard the extra information provided that the attribution signature is valid

Are the SKAdNetwork postback templates distinct from the existing postbacks templates?

Yes. The flow and structure differ.

Will we receive a SKAdNetwork postback and a probabilistic/deterministic modeling postback related to the same install, meaning duplicate reporting of the same install?

Yes. For each case, we record an install attributed to you, irrespective of method, we will send you a postback.

Use attribution_source to differentiate SKAdNetwork postbacks.

 

Are we required to process the postback from AppsFlyer?

No. Consider, that best practice is to optimize campaigns according to user-quality reported via the postback. 

Are we expected to call AppsFlyer attribution links or is it sufficient to send the postback with the SKAdNetwork payload and enriched data?

It is sufficient to send us the SKAdNetwork payload and enriched data.

What is required for us to be certified in the AppsFlyer dashboard as a SKAdNetwork integrated partner?

  • Complete integration using one of the methods listed in this article
  • Send us postbacks of apps using AppsFlyer as their attribution partner
Was this article helpful?