> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.qonversion.io/llms.txt
> Use this file to discover all available pages before exploring further.

# How do I collect Apple Ads attribution with the Qonversion SDK?

> Call collectAppleSearchAdsAttribution() on every app launch after Qonversion is initialized, on iOS 14.3 or later with AdServices.framework added to the app target. ATT consent is not required, Android is not supported, and the attribution appears on the customer page, in analytics filters, in the Apple Ads report and in webhooks as asa_attribution.

To attribute users to Apple Ads campaigns, your iOS app must call `collectAppleSearchAdsAttribution()` from the Qonversion SDK. Attribution collection is not automatic: the SDK fetches Apple's AdServices token and sends it to Qonversion only after the app makes this call, and the app has to make it on every app launch where collection is wanted, after Qonversion is initialized. The token is requested only on iOS 14.3 and later, App Tracking Transparency (ATT) consent is not required, and you must add `AdServices.framework` to the app target. Qonversion's servers then exchange the token with Apple and record the user's campaign, ad group, keyword and ad.

User-level attribution does not need an Apple Ads API connection. Connecting your Apple Ads account in the dashboard is a separate step (see [How do I connect Apple Ads to Qonversion?](apple-search-ads)); it is what turns Apple's numeric IDs into readable campaign, ad group and keyword names.

## Which method do I call on each platform?

On iOS, Apple Ads attribution is enabled by calling `collectAppleSearchAdsAttribution()`:

<CodeGroup>
  ```swift Swift theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  Qonversion.shared().collectAppleSearchAdsAttribution()
  ```

  ```objc Objective-C theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  [[Qonversion sharedInstance] collectAppleSearchAdsAttribution];
  ```
</CodeGroup>

| Platform | Call | Behavior on Android |
| - | - | - |
| iOS (Swift) | `Qonversion.shared().collectAppleSearchAdsAttribution()` | — |
| iOS (Objective-C) | `[[Qonversion sharedInstance] collectAppleSearchAdsAttribution]` | — |
| Android (native SDK) | Not available | The native Android SDK has no Apple Ads attribution; its attribution providers are only AppsFlyer, Branch and Adjust. |
| Flutter | `collectAppleSearchAdsAttribution()` (returns `Future<void>`) | iOS-only; does nothing on Android. |
| React Native | `collectAppleSearchAdsAttribution()` on the Qonversion instance | iOS-only; a no-op on Android. |
| Unity | `CollectAppleSearchAdsAttribution()` | Takes effect only on iOS; does nothing on Android. |
| Cordova | `collectAppleSearchAdsAttribution()` | Runs only on iOS. |
| Capacitor | `collectAppleSearchAdsAttribution()` | Runs only on iOS. |

All cross-platform SDKs (Flutter, React Native, Capacitor, Cordova, Unity) forward the call to the native iOS SDK, so the native iOS behavior — iOS 14.3 or later, AdServices linking, no ATT — applies to them as well.

## When and where do I call it?

* **After initialization.** Call `collectAppleSearchAdsAttribution()` after Qonversion is initialized (`initWithConfig`). Before initialization the shared instance is unavailable and the SDK logs "Attempt to get Qonversion instance before initialization".
* **On every launch.** The SDK fetches and sends the AdServices token only after the app calls `collectAppleSearchAdsAttribution()`; call it on every app launch where collection is wanted. Without the call, no token is sent.
* **Regardless of ATT.** Collecting the AdServices token does not require App Tracking Transparency consent: the SDK neither requests nor checks ATT before fetching and sending the token. You do not need to wait for the ATT prompt.

## Which iOS versions are supported?

| Requirement | Value |
| - | - |
| Qonversion iOS SDK minimum | iOS 13.0 |
| Apple Ads (AdServices) attribution minimum | iOS 14.3 |

The Qonversion iOS SDK supports iOS 13.0 and later, but Apple Ads (AdServices) attribution is collected only on iOS 14.3 and later. On older iOS versions no AdServices token is sent, so those users are not attributed to Apple Ads by the Qonversion SDK.

## How do I link the AdServices framework?

The SDK obtains the token from Apple's `AAAttribution` `attributionToken` API (`attributionTokenWithError:`). It looks up Apple's `AAAttribution` class at runtime and does not link AdServices through CocoaPods or Swift Package Manager.

Add `AdServices.framework` to your app target. Otherwise the SDK logs "AdServices framework not found. Make sure that you import AdServices" and sends no token.

## Does Apple Ads attribution need ATT consent?

No. Collecting the AdServices token does not require App Tracking Transparency consent. The SDK neither requests nor checks ATT before fetching and sending the token.

## How does Qonversion resolve the token?

Qonversion's servers exchange the token with Apple's AdServices attribution API (`https://api-adservices.apple.com/api/v1/`); the app does not call Apple itself. The exchange is sent without any Apple Ads credentials, so user-level attribution works without an Apple Ads API connection.

Attribution is resolved asynchronously after the SDK has sent the token. It appears on the user some time after the app's first launch, not in the SDK call's response: `collectAppleSearchAdsAttribution()` does not return the campaign.

If Apple has no attribution record for a submitted token, that token produces no Apple Ads attribution. The user stays unattributed unless a later token sent by the SDK (for example on a later app launch) resolves.

## What does Qonversion record?

From Apple's attribution response Qonversion keeps:

| Apple field | Meaning |
| - | - |
| `attribution` | `true` or `false` |
| `orgId` | Apple Ads organization ID |
| `campaignId` | Campaign ID |
| `adGroupId` | Ad group ID |
| `keywordId` | Keyword ID |
| `adId` | Ad ID |
| `conversionType` | Conversion type |
| `countryOrRegion` | Country or region |
| `clickDate` | Click date |
| `claimType` | Claim type |
| `impressionDate` | Impression date |
| `supplyPlacement` | Supply placement |

How Apple's structure maps to Qonversion's attribution dimensions:

| Apple Ads | Qonversion |
| - | - |
| Campaign | Campaign |
| Ad group | Ad set (`ad_set_*`) |
| Keyword | Keyword |
| Ad | Ad |

* Users attributed through the SDK's AdServices token get the media source value "Apple AdServices".
* An attributed response with `conversionType` "Download" is recorded as an install event.
* If Apple's response has no `keywordId`, the keyword is recorded as "Unknown" (both ID and text) with match type "Unknown", and it is never resolved to a keyword name.
* If Apple's response has no `adId`, or one that is 0 or less (Apple uses `-1` when there is no ad), the user is recorded under one shared ad named "No ad" per ad group (identifier `Q-NOAD-` followed by the organization, campaign and ad group IDs). Ads recorded before this behavior was introduced on 2026-10-17 keep an individual identifier that starts with "Q-".

## Are reinstalls credited to the campaign?

Yes. Redownloads (reinstalls) after a tap on an Apple Ads ad are credited to the Apple Ads campaign, like first downloads.

## What happens to organic users?

When Apple answers `attribution=false`, the user is treated as not attributed to Apple Ads: no media source, campaign, ad set or ad is assigned from this token. Such users are not in the Apple Ads report population, and webhooks for them carry no `asa_attribution` object.

## Why do I see numeric IDs instead of campaign names?

Apple's attribution response identifies the campaign, ad group, keyword and (when there is one) the ad by numeric ID only, without names. When attribution is first recorded, the campaign name, ad set (ad group) name, ad name (when Apple sent an ad ID) and keyword text are set to Apple's numeric IDs.

Readable campaign, ad group and keyword names (and the keyword match type) replace the numeric IDs only when the app's project has a connected Apple Ads account that can access the campaign's organization; otherwise names stay as numeric IDs. Analytics data recorded before a name was resolved can keep showing the numeric ID.

The Ad dimension for Apple Ads is never renamed: it shows Apple's numeric ad ID, or "No ad" when Apple sent no ad ID (missing, or 0 or less — Apple uses `-1`) (older records: an identifier starting with "Q-").

To get readable names, connect Apple Ads under **Settings → Connections → Apple Ads** — see [How do I connect Apple Ads to Qonversion?](apple-search-ads).

## Where does Apple Ads attribution show up?

### Customer page

The customer detail page in the Qonversion dashboard has an **Attribution** card that lists **Media Source**, **Campaign**, **Ad Set** and **Ad** of the user's latest attribution, or "No attribution data" when there is none. The keyword is not shown there.

Via the REST API v4, `GET /v4/customers/{customer_id}` returns the customer's latest attribution in `data.attributionData` as a list of `{key, value}` with keys "Media Source", "Campaign", "Ad Set" and "Ad" (`null` when the customer has no attribution).

### Analytics filters and dimensions

There is no keyword filter in analytics: the keyword is available in the Apple Ads report (the **Keywords** level) and in webhooks (`keyword_id`), not on the customer page or in analytics filters.

| Dashboard filter label | Attribute code (dashboard, Analytics API and MCP) | What a value matches |
| - | - | - |
| **Media source** | `media_source_name` | The media source value |
| **Campaign** | `campaign_name` | The campaign name; in most charts also the campaign ID, but subscription-state charts (for example MRR, active and new subscriptions) match the name only |
| **Ad set** | `ad_set_name` | The ad set (Apple ad group) name; in most charts also the ad set ID, but subscription-state charts match the name only |
| **Ad** | `ad_name` | The ad name only |

* Apple's ad group is filtered via `ad_set_name`.
* In filter metadata, Campaign and Ad set values use the ID as the value code and the name as the label.

Media source values in general analytics filters:

| Stored value | Shown as | Source |
| - | - | - |
| `Apple AdServices` | "Apple AdServices" | Qonversion SDK (AdServices token) |
| `apple_search_ads` | "Apple Search Ads" | Legacy value |
| `Apple Search Ads` | "Apple Search Ads (via MMP)" | Sent by MMP integrations |

### Apple Ads report

* The Apple Ads report counts users whose media source is one of Apple's sources — "Apple AdServices" (Qonversion SDK), `apple_search_ads` (legacy) or "Apple Search Ads" (forwarded by an MMP) — and whose campaign ID is known.
* Users carrying Apple's sample attribution payload (campaign ID and ad group ID both 1234567890) are excluded from the Apple Ads report.
* In the Apple Ads report, a `media_source_name` filter narrows only the Qonversion users side; Apple spend is not split by media source.
* The report's onboarding checklist has a step **Attribution is matching** that completes once at least one attributed user appears in the report. While Apple spend exists but no users matched, it shows **No users matched** and links to this guide.

### Webhooks

Webhook payloads include an `asa_attribution` object. It reflects the most recent Apple attribution response stored for the user.

| Key | Type |
| - | - |
| `org_id` | Apple's numeric ID |
| `campaign_id` | Apple's numeric ID |
| `adgroup_id` | Apple's numeric ID (the ad group; note the spelling `adgroup_id`) |
| `keyword_id` | Apple's numeric ID |
| `ad_id` | Apple's numeric ID |
| `country_or_region` | String as Apple sent it |
| `conversion_type` | String as Apple sent it |
| `click_date` | String as Apple sent it |
| `claim_type` | String as Apple sent it |
| `impression_date` | String as Apple sent it |
| `supply_placement` | String as Apple sent it: where the ad was shown, for example search results or the Today tab |

* Keys whose value is empty or missing (for example `keyword_id` for Search Match, `ad_id` when Apple sends no ad identifier — Apple's placeholder `-1` is not empty and is sent as is — or `claim_type`/`impression_date`/`supply_placement` when Apple does not send them) are left out rather than sent as `null`.
* The `asa_attribution` object is omitted from the webhook when Qonversion has no Apple attribution response for the user or Apple reported the user as not attributed.
* Webhooks carry IDs, not campaign names.

### SplitMetrics and Asapty

The SplitMetrics and Asapty integrations forward events only for users that Apple attributed to an Apple Ads campaign. Events of unattributed users or users without an Apple response are not sent.

## What happens when a user also gets attribution from an MMP?

Qonversion keeps one current attribution per user: the most recently recorded one, from any source (Apple Ads or another provider such as an MMP). Qonversion does not prefer one source over another, and the first attribution is not kept forever.

* User-level views such as the Apple Ads report and the customer page use that current attribution.
* Events are tagged with the attribution the user had when each event was recorded, so a newer attribution does not re-tag earlier events.
* The Apple Ads report includes users from all of Apple's sources: "Apple AdServices" (Qonversion SDK), `apple_search_ads` (legacy) and "Apple Search Ads" forwarded by an MMP.

## What is not supported?

* **Android.** The native Android SDK has no Apple Ads attribution; in Flutter, React Native and Unity the call does nothing on Android, and in Cordova and Capacitor it runs only on iOS.
* **Other Apple platforms.** The token is collected only in iOS builds (including Mac Catalyst) and visionOS builds; in native macOS, tvOS and watchOS builds the call does nothing.
* **iOS earlier than 14.3.** No AdServices token is requested or sent.
* **Automatic collection.** Without a call to `collectAppleSearchAdsAttribution()`, no token is sent.
* **Manual attribution on iOS.** The manual attribution method (Objective-C `attribution:fromProvider:`, Swift `attribution(_:from:)`, and `attribution(data, provider)` in the cross-platform SDKs) is deprecated and does nothing on iOS, including with the `AppleSearchAds`/`AppleAdServices` providers. Apple Ads attribution is collected only by calling `collectAppleSearchAdsAttribution()`.
* **Reading attribution from the SDK call.** `collectAppleSearchAdsAttribution()` does not return attribution; it is resolved later on Qonversion's servers.
* **Readable Ad names.** The Ad dimension always shows Apple's numeric ad ID, or "No ad" when Apple sent no ad ID (missing, or 0 or less — Apple uses `-1`) (records from before 2026-10-17: an identifier starting with "Q-").

## Related pages

* [How do I connect Apple Ads to Qonversion?](apple-search-ads) — connect the Apple Ads account so names resolve and the report shows Apple spend.
* [Apple Ads overview](apple-ads) — what Qonversion does with Apple Ads data and where you read it.
* [How do I read the Apple Ads report?](apple-ads-report) — how attributed users are counted against Apple spend.
* [Webhooks](webhooks) — webhook payloads, including the `asa_attribution` object.
* [Customer details](customer-details) — the customer page with the **Attribution** card.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.