# Attribution (/docs/concepts/attribution)



Attribution in Layers means: &#x2A;*a conversion happened in your app — which ad
caused it?** Layers' answer combines three signals:

1. **SDK events** from the Layers SDK (server-side, via `in.layers.com`).
2. **CAPI / Events API forwarding** to Meta and TikTok with `event_id` for
   deduplication against the platform's pixel/SDK.
3. **SKAdNetwork** (iOS) and Apple Search Ads attribution token.

## Server-side first [#server-side-first]

The Layers SDK does **not** ship a Meta Pixel or TikTok Pixel SDK. Instead,
events go to the SDK ingest endpoint and Layers forwards them server-side
via:

* **Meta Conversions API** (CAPI) — SDK events are mapped to standard Meta
  events (`purchase_success` → `Purchase`, `subscription_start` → `Subscribe`,
  `sign_up` → `CompleteRegistration`, etc.). Unmapped events are dropped at
  the relay.
* **TikTok Events API** — SDK events are mapped to standard TikTok events
  (`purchase_success` → `Purchase`, `content_open` → `ViewContent`, etc.).
  Unmapped events are dropped at the relay.
* **Apple Search Ads** — the SDK reports the `AAAttribution.attributionToken()`
  on first launch; Layers requests attribution data from Apple Search Ads on
  your behalf.

The canonical mapping tables are documented in
[standard events](/docs/sdk/standard-events). You can override
individual events per app via `sdk_apps.settings.eventMap`.

This means you get **iOS 14.5+ attribution** without any pixel-blocking risk,
and you do not have to manage CAPI / Events API tokens or pixel IDs in your
app code.

## Why `event_id` matters [#why-event_id-matters]

If you also have a client-side Meta Pixel installed (e.g., on your marketing
website), you'll get **duplicate events** at Meta unless they share an
`event_id`. The Layers SDK generates a UUID v4 per event and forwards it. If
your client Pixel sends the same `event_id` for the same event, Meta dedupes
them.

Recommendation: emit `event_id` from your client Pixel that matches the SDK
event\_id. The simplest pattern is "fire both at the same time with the same
ID."

## Attribution windows [#attribution-windows]

Attribution windows are set on the ad platform itself (Meta Ads Manager,
TikTok Ads Manager, Apple Search Ads), not by Layers. Each platform's default
window applies to how it reports conversions back through Insights / Reporting
APIs.

Layers does **not** dedupe across platforms — a single conversion attributed
by both Meta and Apple will show up in both platforms' reports. The
cross-platform rollup in the dashboard displays per-platform attribution; the
`sdk_events` table is the source of truth for actual conversions observed by
the SDK.

## SKAdNetwork (iOS) [#skadnetwork-ios]

Layers does not run a custom SKAdNetwork conductor. Meta's and TikTok's own
SKAN integrations handle this through the SDK + CAPI flow. If you need a
managed SKAN conductor (postback aggregation, conversion-value schema), keep
using AppsFlyer / Adjust alongside.

## Honest about gaps [#honest-about-gaps]

* **iOS install attribution** for paid ads is fundamentally probabilistic
  post-iOS 14. Even with CAPI + SKAN, expect measurement loss vs the
  pre-ATT era.
* **Cross-platform install attribution** (e.g., Meta-aided install but TikTok
  saw the user too) is not reconciled. The platform that matched first wins.
* **App Tracking Transparency** dialogs are your responsibility — Layers' SDK
  does not prompt. If you've removed Meta's SDK in favor of Layers', schedule
  the ATT prompt yourself.

## What gets attributed in the dashboard [#what-gets-attributed-in-the-dashboard]

The project dashboard shows:

* **SDK conversions** — the count from `sdk_events` (Layers' source of truth
  for events observed by the SDK).
* **Meta / TikTok / Apple conversions** — what each platform reports back via
  its Insights / Reporting / attribution endpoints after the platform has
  done its own attribution.

These should be close but rarely identical. The biggest divergences are:

* iOS users without ATT consent (Meta/TikTok rely on probabilistic matching).
* Users who clicked an ad but had ad-blockers active (CAPI catches these
  server-side; Pixel-only setups don't).
