Compliance9 min read

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.xcprivacy to 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.

Related docs