Glossary/iOS platform and privacy
Crowd Anonymity
Definition
Crowd anonymity is Apple's privacy mechanism that decides how much campaign and conversion detail an attribution postback may contain, based on whether the install cohort is large enough that the report cannot identify an individual.
It is the reason two campaigns with identical instrumentation return different amounts of data, and the reason most SKAN troubleshooting is not a bug hunt. Apple does not publish the install volumes behind each tier, does not tell you which tier a postback came from, and evaluates the tier per install rather than per campaign. What you can do is understand which fields disappear at each level and structure spend so your important dimensions are the ones that survive.
The four tiers
A tier determines two things at once: how many digits of the source identifier you receive, and whether a conversion value is included at all.
| Tier | Source identifier | Conversion value | Publisher identity |
|---|---|---|---|
| 0 | 2 digits | None | No |
| 1 | 2 digits | Coarse only | No |
| 2 | 3 digits | Coarse only | No |
| 3 | 4 digits | Fine (0–63) | Sometimes |
Tier 0 is not an error state. It is a correctly functioning postback that tells you an install happened and which two-digit bucket the ad belonged to, and nothing else. A campaign that lives permanently at tier 0 is a campaign whose creative and audience decisions cannot be informed by SKAN, no matter how the SDK is configured.
Tier is assigned per install, not per campaign
The same campaign can produce tier 3 postbacks in a high-volume market and tier 0 postbacks in a small one, in the same week. This means a campaign's average reported conversion value is a biased estimate — it is computed only over the installs that were large-cohort enough to report one, which skews toward your biggest geos.
The hierarchy is the lever you control
You always get the first two digits of the source identifier. Digits three and four are conditional. Since the ad network chooses the encoding, the order of that hierarchy is the single most consequential thing to agree with them.
| Digits | Encoding A | Encoding B |
|---|---|---|
| 1–2 (always sent) | Campaign | Ad network region |
| 3 (tier 2+) | Geo | Campaign |
| 4 (tier 3 only) | Creative | Creative |
Under Encoding A, a small campaign still tells you which campaign it was. Under Encoding B, the same install tells you only a region, and campaign-level reporting collapses entirely below tier 2. Both are valid SKAN implementations; only one is usable at low volume.
- Ask each network how it maps the four digits, and get it in writing. Several networks let you configure this.
- Put the dimension you would optimise on tomorrow in digits one and two.
- Consolidate spend. Fewer, larger campaigns reach higher tiers; the same budget split across twenty ad sets may report nothing useful from any of them.
- Avoid narrow geo and audience splits at campaign level — that fragmentation is exactly what pushes cohorts under the threshold.
- Design a coarse value that is decision-grade on its own, because tiers 1 and 2 are where most campaigns live.
Diagnosing what you are actually seeing
Because the tier is never stated, you infer it from the shape of what arrived. This table is the diagnostic.
| What arrived | Inferred tier | Action |
|---|---|---|
4-digit source ID and conversion-value | 3 | Nothing — this is the full signal |
3-digit source ID, coarse-conversion-value only | 2 | Consolidate to reach tier 3, or accept coarse |
2-digit source ID, coarse-conversion-value only | 1 | Campaign is small; merge ad sets |
| 2-digit source ID, no value field at all | 0 | No behavioural signal is available for this cohort |
| Nothing at all | Not a tier issue | Check SKAdNetworkItems registration and the endpoint |
function inferredTier(postback) {
const digits = String(postback["source-identifier"] ?? "").length;
const hasFine = postback["conversion-value"] !== undefined;
const hasCoarse = postback["coarse-conversion-value"] !== undefined;
if (digits >= 4 && hasFine) return 3;
if (digits === 3 && hasCoarse) return 2;
if (hasCoarse) return 1;
return 0; // no value field survived
}
// Report tier mix alongside installs. A campaign whose tier-0 share
// is rising is losing measurability, which no CV schema change fixes.
const mix = postbacks.reduce((acc, p) => {
const t = inferredTier(p);
acc[t] = (acc[t] ?? 0) + 1;
return acc;
}, {});Do not average across tiers
Averaging conversion values over a mixed-tier cohort compares a fine 0–63 scale against coarse buckets against absent data, and the result tracks your tier mix more than your user quality. Report tier mix as a first-class metric, and compute value averages within a tier only.
The same thresholds apply to AdAttributionKit, so none of this is resolved by adopting the newer framework. It is the price of attribution without a cross-app identifier, and the useful response is structural — fewer, larger campaigns and a coarse value you can act on.
SKAN conversion value builder
Because most campaigns sit at tier 1 or 2, the coarse value carries the decision more often than the fine one. Our builder makes you define both, so your schema still says something useful when the fine value is stripped.
Open the skan conversion value builder →Frequently asked questions
- What is crowd anonymity in SKAdNetwork?
- Crowd anonymity is Apple's privacy threshold that decides how much detail an attribution postback may carry, based on whether enough installs share the same campaign characteristics that the report cannot single out an individual. Larger cohorts unlock more digits of the campaign source identifier and a more precise conversion value; smaller cohorts receive progressively less.
- What are the crowd anonymity tiers?
- There are four. Tier 0 returns a two-digit source identifier and no conversion value at all. Tier 1 adds a coarse low, medium or high value. Tier 2 extends the source identifier to three digits, still with only a coarse value. Tier 3 gives the full four-digit source identifier and the fine 0 to 63 conversion value.
- How many installs do I need to reach tier 3?
- Apple does not publish the volumes, and they are evaluated per install against the cohort of similar installs rather than as a fixed campaign threshold. The practical guidance is directional: consolidating spend into fewer campaigns with broader targeting raises tiers, while splitting the same budget across many narrow ad sets lowers them.
- Why is my conversion value missing but the install reported?
- Because the install landed in tier 0, where the postback confirms an install and a two-digit campaign bucket but carries no behavioural payload. This is a functioning postback rather than a bug, and it cannot be fixed by changing your SDK or conversion value schema — only by increasing the cohort size behind the campaign.
- Does AdAttributionKit remove the crowd anonymity limits?
- No. AdAttributionKit inherits the same crowd anonymity model, the same hierarchical source identifier and the same fine and coarse conversion values, so cohorts too small to report detail under SKAdNetwork remain too small under AdAttributionKit. What it adds is re-engagement measurement and marketplace support, not more granular data at low volume.
Related terms
- SKAdNetwork — SKAdNetwork is Apple's StoreKit framework that attributes app installs to advertising campaigns without exposing a device identifier, by having the operating system send a delayed, aggregated postback to the ad network that won the install.
- Conversion Value — A conversion value is a 6-bit integer between 0 and 63 that an iOS app sets after install to describe post-install behaviour, and which the operating system reports to the ad network in an attribution postback.
- SKAN Postback — A SKAN postback is a signed JSON report that iOS sends from the device to an ad network's server after an advertised app is installed, containing the campaign identifier and any conversion value the install's privacy tier permits.
- Unattributed installs — An install is unattributed when no signal linking it to a prior ad click or link tap survived the journey through the app store, which can mean the install was organic or that the signal existed and was lost.