The iOS privacy manifest for Capacitor apps, explained
Apple's privacy manifest and required-reason APIs are now mandatory. What a Capacitor app needs in its PrivacyInfo.xcprivacy, how plugins factor in, and common submission errors to avoid.
Apple now requires a privacy manifest for App Store submissions, and it's a common source of surprise rejections for Capacitor apps. The manifest declares what data your app collects and why it uses certain sensitive APIs. This guide explains what a Capacitor app needs, how plugins factor in, and the mistakes that get submissions bounced.
Mental model: the privacy manifest is a native, store-time declaration — it's part of the binary you submit, not something you change over the air.
What the privacy manifest is
A PrivacyInfo.xcprivacy file that ships inside your app (and inside SDKs it uses). It declares two main things: the data types your app collects, and the reasons it calls certain “required reason” APIs — APIs Apple has flagged because they can be misused for fingerprinting (file timestamps, disk space, system boot time, UserDefaults, and a few others).
What a Capacitor app needs to check
- Your app's own manifest. Add a
PrivacyInfo.xcprivacyto the iOS project declaring the data you collect and required-reason APIs you use. - Plugin manifests. Capacitor plugins that touch sensitive APIs should ship their own privacy manifests. Keep plugins updated — maintained plugins add these as Apple's requirements tighten.
- Third-party SDK manifests. Analytics, ads, and similar SDKs each need their manifest; Apple aggregates them into your app's privacy report.
A minimal example
A required-reason declaration for UserDefaults (commonly used for app settings) looks like this:
<!-- ios/App/App/PrivacyInfo.xcprivacy -->
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array><string>CA92.1</string></array>
</dict>
</array>
</dict>Add it to the Xcode project so it's bundled with the app. The exact data types and reason codes depend on what your app and plugins actually do — declare accurately, not defensively.
Common rejection causes
- Missing manifest entirely — the most frequent cause.
- Using a required-reason API without declaring a reason code.
- Outdated plugins or SDKs that lack their own manifests.
- Data-collection declarations that don't match your Play/App Store privacy labels.
Why OTA doesn't touch this
The privacy manifest is native and evaluated at submission, so it's firmly in store-release territory — you can't (and don't need to) change it over the air. It's a good example of the OTA line: native compliance artifacts go through review; your web layer ships over the air. See what OTA can and can't change.
Keep your Capacitor and plugin versions current — a lot of privacy-manifest compliance is handled for you by up-to-date plugins.
Where to go next
See passing your first store review for the broader submission checklist, and the plugin docs for OtaKit's own footprint.