The two rejections that eat your first submit
Two data-safety rejections show up more than everything else combined on first submissions:
- Your Privacy Policy URL loads but doesn't mention the data types you listed in App Store Connect. The reviewer clicks your policy, ctrl-F's for "email" or "device identifier", finds nothing. Held.
- You claim "Data Not Linked to You" for analytics while your SDK sends a persistent device ID. Any default install of Firebase, Amplitude, or RevenueCat lands here.
Both are 30-minute fixes. Both cost a full review cycle. The whole game is eliminating them before you submit.
Match the policy verbatim to the Connect form
Apple's data-safety reviewer isn't reading your policy. They're diffing it against the table you filled in App Store Connect. So the policy needs to be structured the same way:
- One row per data type
- Three columns: what, why, third parties
- Language that maps 1:1 to the Connect field names ("Product Interaction", "Device or Other IDs", "Coarse Location")
Legalese from a generic policy generator won't match. Rewrite it as a table.
Build-time drift check
Drift between what your app actually collects and what your Connect form declares is the number one hold reason. Catch it in CI:
# .github/workflows/data-safety.yml
- name: Data-safety drift check
run: |
python scripts/data_safety_diff.py \
--ios-plist ios/App/Info.plist \
--android-manifest android/app/src/main/AndroidManifest.xml \
--connect-declared connect-data-safety.yml
A 40-line script parses your Info.plist and AndroidManifest.xml permission lists and compares them against a connect-data-safety.yml committed alongside the app. Any drift means a red build. You never submit a mismatch again.
Notes for Reviewer is the field that unblocks you
Reviewers spend about 90 seconds on your submission. The field they actually read is Notes for Reviewer. Use it to answer the three questions they always ask:
- Test credentials to log in. Real, working, not disabled.
- Personal vs device data. One sentence: "We collect X for Y purpose; SDK Z sends a device ID, which is why we declare Data Linked."
- IAP unlocks. What the tester sees after purchase.
Skip these and you get held. Include them and your review cycle gets a day shorter.
The one toggle that fixes 40%
In App Store Connect > App Privacy > Data Collection: if any SDK (analytics, ads, crash reporting) sends a device ID or IP, you must declare "Data Linked to You" for that category. Not "Not Linked".
This single toggle is where 40% of the data-safety rejections we've seen land. Get it right on the first submission and you save two review cycles.
What passes vs what gets held
Passes:
- Table-format policy matching Connect verbatim
- A static
/privacypage, indexed on your marketing site - Notes for Reviewer with real test creds and a data explanation
- ATT prompt shown after a value-explaining action, using Apple's exact string, with a deny path that doesn't paywall
Held:
- Legalese policy from a generic generator
- ATT prompt on splash
- "Data Not Linked" claim with any device-ID-collecting SDK
- Missing Notes for Reviewer
The fastest wins
If you're prepping an App Store submission this week: match your Privacy Policy table to Connect verbatim, add the drift check to CI, and write Notes for Reviewer for real. We built LetsDeployIt to automate this pipeline for indie teams, but the checklist matters more than the tool.
Top comments (0)