Mobile
SKAdNetwork and AdAttributionKit
Receiving and verifying Apple privacy-preserving postbacks, conversion-value schemas, and mapping sources to campaigns.
On iOS, installs from users who deny App Tracking Transparency can only be measured with Apple's privacy-preserving attribution: SKAdNetwork (SKAN 2.0 to 4.0) and AdAttributionKit (AAK). Metrixed receives and verifies both, decodes conversion values you define, and maps sources to partners and offers.
Receiving postbacks
Point the app at your Metrixed SKAN host (the tracking domain that serves ingest):
Info.plist:NSAdvertisingAttributionReportEndpointfor SKAN and, for AdAttributionKit,AdAttributionKitReportEndpoint.- Ingest accepts them at
POST /v1/skan/postbacks(aliases/v1/aak/postbacks, and Apple's developer-copy paths/.well-known/skadnetwork/report-attributionand/.well-known/appattribution/report-attribution). The body format (SKAN version, or an AAK signed JWS) is detected automatically. - Verification: SKAN postbacks are checked against Apple's public keys per version; AAK postbacks are an ES256 JWS verified against Apple's key set. Override keys with
DT_SKAN_PUBLIC_KEYS(4.0=<base64>,3.0=<base64>,default=<base64>), fetch the AAK set fromDT_AAK_KEYS_URL, or pin it withDT_AAK_JWKS.DT_SKAN_ACCEPT_UNVERIFIED=1exists for development only. - Postbacks are de-duplicated on transaction id (or postback identifier) and sequence index, stored (
/skan/postbacks) and mirrored to ClickHouse (skan_postbacks) for reporting. The event ismobile_skan_postback.
Source mapping
A postback identifies a campaign only by the ad network id and a 1 to 4 digit source identifier (SKAN 4 and AAK) or a campaign id (SKAN 3 and earlier). Mappings (/skan/mappings) turn these into a partner, offer and campaign name; a mapping without source_identifier is the network-level default, and one without app_id applies to every app.
Conversion-value schemas
You define what the 6-bit fine value (0 to 63) and the coarse value (low, medium, high) mean as a JSON schema of windows and rules, per app (/skan/cv-schemas). Windows follow SKAN 4: window 0 is days 0 to 2 (fine and coarse), window 1 is days 3 to 7 and window 2 is days 8 to 35 (coarse only).
{
"version": 1,
"windows": [
{ "window": 0, "lock_at_fine_gte": 60, "rules": [
{ "fine": 5, "when": { "event": "register" } },
{ "fine": 20, "coarse": "medium", "when": { "event": "purchase", "count_gte": 1 } },
{ "fine": 45, "when": { "event": "purchase", "revenue_gte": "50" } }
] },
{ "window": 1, "rules": [ { "coarse": "high", "when": { "revenue_gte": "50" } } ] }
]
}
Rules: the highest matching fine value wins, values never decrease, coarse defaults to low (below 21), medium (below 42) or high from the fine value, and a rule with lock or reaching lock_at_fine_gte locks the window. Revenue thresholds are exact six-decimal decimals.
POST /skan/cv-schemas/simulatereplays events against a draft schema.POST /skan/cv-schemas/{id}/activatemakes a schema the active one for its app (one active schema per app).GET /skan/cv-schemas/{id}/decode-tablelists what every value means.- The iOS SDK downloads the active schema from
GET /sdk/v1/config(cached 6 hours), evaluates it on every event and calls Apple's update APIs (updatePostbackConversionValue,updateConversionValue, and AdAttributionKit'supdateConversionValue). The server decoder and the SDK share test vectors (sdks/test-vectors/cv-schema.json), so both sides agree. - Decoded postbacks become events with estimated revenue from the schema that was active at receipt.
Reports
POST /reports/skan (admin) and POST /partner/reports/skan (partners) report postbacks by network, source, campaign, window and conversion value. Partners see only their own mapped traffic.
Limits worth knowing
Apple's key URL for AdAttributionKit has not been verified against a live Apple endpoint in this release, so pin the key set with DT_AAK_JWKS if you need certainty. Fine values are only delivered by Apple when crowd-anonymity thresholds are met, which is an Apple behaviour no tracker can change.