App privacy labels: what gets checked, and how RN apps get them wrong
The App Privacy label is a declaration about behaviour, and review compares it against the behaviour.
The mismatch that gets caught is almost always the same one: a dependency collects something and the label does not mention it. Analytics, crash reporting, attribution, ad SDKs, session replay, support chat. Apple's position is that collection by code you include is collection by you, and disclosing it is your job, not the vendor's.
A React Native project makes this harder in a specific way. You did not choose most of what is in node_modules, and a transitive dependency can introduce collection without appearing anywhere in your own imports.
Three things people get wrong beyond that:
- "Linked to the user" is broader than a login. Data associated with an identity, account or device identifier that can reach an identity is linked.
- "Tracking" has a specific meaning: linking data with third-party data for advertising or measurement, or sharing with a data broker. It is not the same question as collection, and it is the one that triggers App Tracking Transparency.
- The label is not updated by anything automatically. Adding an SDK changes the app; only you change the label.
The label and a privacy manifest are different mechanisms. Both exist, both get checked, and an app can fail either independently.
The audit that catches it
Do this on a dependency change rather than before a release:
# what is actually in the tree that collects
grep -riE 'firebase|amplitude|mixpanel|segment|sentry|bugsnag|datadog|appsflyer|adjust|branch|facebook|onesignal|posthog|intercom|smartlook|fullstory' package.json | head -30
# transitive: what pulled in what
npm ls --all 2>/dev/null | grep -iE 'analytics|tracking|attribution|advert' | head -20
# does anything ask for the tracking permission
grep -rn 'NSUserTrackingUsageDescription' ios app.json app.config.js 2>/dev/null
grep -rn 'requestTrackingPermission\|AppTrackingTransparency' src app 2>/dev/null | headThen, for each collector, open its own privacy documentation and read what it says it collects by default. Defaults matter: several SDKs collect identifiers or coarse location unless told otherwise, and the label has to describe the configuration you shipped.
The four questions per data type
For each category Apple lists, answer:
- Do we collect it? Including through any SDK.
- Is it linked to the user's identity?
- Is it used for tracking, as Apple defines tracking?
- What is it used for, in Apple's purpose categories?
Write the answers down with the reason. When the label is questioned, six months later, the useful artefact is a table saying which dependency produced which declaration. Reconstructing that from memory is where teams get it wrong twice.
Where the label meets other requirements
| Mechanism | What it is | Where it lives |
|---|---|---|
| App Privacy label | Public summary of data practices | App Store Connect |
| Privacy manifest | Machine-readable declaration in the bundle | PrivacyInfo.xcprivacy |
| Required-reason APIs | Approved reasons for specific API use | Privacy manifest |
| ITMS-91061 | A listed SDK ships no manifest | Upload check |
| ATT prompt | Consent for tracking | Runtime, if tracking |
| Play Data safety | Google's equivalent declaration | Play Console |
The two store forms must also agree with each other. Declaring no collection on Apple and collection on Google, for one codebase, is a discrepancy that an interested party can see from the outside.
The specific ways RN apps get it wrong
Crash reporting counts. Sentry, Bugsnag, Crashlytics collect diagnostics, often with identifiers, and "we only use it for crashes" is a purpose, not an exemption.
A push SDK collects identifiers. Device tokens and the identifiers around them are collection.
Support chat collects contact info and content. An in-app messenger is a data collector.
Attribution SDKs are usually tracking, in the specific ATT sense, which means the permission prompt and the label both change.
An analytics call left in a debug path still ships. If the code is in the binary and it runs, it collects.
Before you submit
Reconcile three things and make them say the same story: what the code does, what the label says, and what the privacy policy says. A reviewer can read two of those in a minute, and a policy that contradicts the label is a finding without anyone opening a debugger.
Then check the manifest side separately, because it is a different mechanism with its own upload-time failures. The privacy manifest, for React Native. · Which RN SDKs need one.
shipcheck enumerates the collectors actually present in your dependency tree, including transitive ones, and lists what each vendor documents itself as collecting, so the label is filled in from the tree rather than from memory. What it checks. · The first-submission checklist.
More in this section
About shipcheck
shipcheck is a pre-submission checker from Baker Ventures LLC that runs inside Claude Code. It reads your React Native or Expo project, finds the things that get apps rejected or blocked at upload, cites the exact App Store Review Guideline or Google Play policy clause, and names the file and line to fix.
It exists because React Native and Expo apps fail for reasons that are invisible in the code you wrote: capability arriving through a dependency, purpose strings added by a config plugin, a privacy manifest missing from an SDK you never chose directly, and a generated ios/ directory that discards your edits on the next prebuild. shipcheck checks what the binary and the config actually declare, not what you intended. The rejection references on this site are free, need no account, and link to the primary Apple or Google document for every claim.
Questions and answers
What is the App Privacy label?
The privacy summary shown on your App Store product page, declared by you in App Store Connect. It covers what data is collected, whether it is linked to the user's identity, and whether it is used for tracking. It is a declaration about behaviour, and review compares it against what the app does.
Do third-party SDKs count as my data collection?
Yes. Apple's position is that you are responsible for disclosing collection by code you include, including analytics, crash reporting, advertising and attribution SDKs. A dependency collecting an identifier is your declaration to make.
What is the difference between the privacy label and a privacy manifest?
The label is what users see on the product page and is declared in App Store Connect. A privacy manifest is a file inside the app or an SDK, declaring required-reason API use and data collection in machine-readable form. Both exist, they are checked by different mechanisms, and an app can fail either independently.
What happens if my label is wrong?
Typically a rejection asking you to correct the label or the behaviour. It can also be raised after release. Because the label is a public statement about data handling, an inaccurate one is a trust and compliance problem beyond the review cycle.
Does the label have to change if I add an SDK?
Very often, yes. Adding an analytics or attribution SDK can change what is collected, what it is linked to and whether it is used for tracking, and the label is not updated automatically by anything.
Is IP address collection reportable?
Coarse location derived from IP, and identifiers, have their own categories, and what you declare depends on what is done with the data rather than only what is transmitted. The category definitions in Apple's own documentation are the reference, not intuition.
shipcheck. “App privacy labels: what gets checked, and how RN apps get them wrong.” Baker Ventures LLC, September 7, 2026. https://shipcheck.bakerventuresstudio.com/rejections/app-privacy-nutrition-labels/