Shipping & Release· 5 min read

Privacy Manifests and Required-Reason APIs for React Native Apps

Privacy manifests for React Native and Expo apps: what PrivacyInfo.xcprivacy is, required-reason APIs, fixing ITMS-91053, and handling third-party SDKs.

By

Full-Stack, Mobile & AI Engineer

You upload a build, it processes, and an email arrives: "ITMS-91053: Missing API declaration". Your app uses something called NSPrivacyAccessedAPICategoryUserDefaults, and you never wrote a line of code touching it. Welcome to privacy manifests, Apple's way of making every app and SDK explain why it uses APIs that could be used to fingerprint a device.

This guide explains what a privacy manifest is, which "required reason" APIs it covers, how to add one to a React Native or Expo app, how to deal with third-party SDKs, and a quick way to work through an ITMS-91053 email.

Key takeaways

  • A privacy manifest (PrivacyInfo.xcprivacy) declares why your app and its SDKs use certain APIs, what data they collect, and whether they track users.
  • Required-reason APIs include user defaults, file timestamps, system boot time, disk space and active keyboard APIs. Using them without an approved reason is flagged on upload.
  • Apple has required these declarations since May 2024 for new apps and updates. Missing ones arrive as ITMS-91053 emails.
  • In Expo, add declarations under ios.privacyManifests in your app config; prebuild writes the file for you.
  • Third-party SDKs should ship their own manifests, but Apple doesn't always parse those inside static CocoaPods, so you may need to copy their reasons into your app's manifest.

What a privacy manifest contains

The file is a property list with four main parts:

KeyWhat it declares
NSPrivacyAccessedAPITypesRequired-reason APIs used, each with approved reason codes
NSPrivacyCollectedDataTypesTypes of data collected, and how they're used
NSPrivacyTrackingWhether the app or SDK tracks users as Apple defines it
NSPrivacyTrackingDomainsDomains used for tracking, which iOS can block if the user hasn't allowed tracking

The API declarations are the part that blocks uploads. The data and tracking parts support your App Privacy label and App Tracking Transparency behaviour.

Which APIs need a reason

Apple groups required-reason APIs into categories:

CategoryExample use in a React Native app
User defaultsStoring small settings; many libraries use it under the hood
File timestampChecking when a cached file was created or modified
System boot timeMeasuring elapsed time, for example in performance tracking
Disk spaceChecking free space before downloading or caching media
Active keyboardDetecting which keyboards are installed

For each category you use, you pick one or more approved reason codes from Apple's documentation. For example, CA92.1 covers reading and writing user defaults that are only accessible to the app itself.

Adding a privacy manifest in Expo

With Continuous Native Generation, declare everything in your app config and let prebuild generate the file:

{
  "expo": {
    "ios": {
      "privacyManifests": {
        "NSPrivacyAccessedAPITypes": [
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
            "NSPrivacyAccessedAPITypeReasons": ["CA92.1"]
          }
        ]
      }
    }
  }
}

Expo's own SDK packages include their own PrivacyInfo.xcprivacy files. In bare React Native projects, edit the PrivacyInfo.xcprivacy file in your iOS project directly in Xcode.

The third-party SDK problem

Every SDK in your app is responsible for its own privacy manifest, and Apple maintains a list of commonly used SDKs that must include one (and be signed). In practice, two problems show up:

  1. Older SDK versions without manifests. Upgrade to a version that includes one.
  2. Manifests Apple doesn't pick up. Expo's documentation notes that Apple doesn't correctly parse all PrivacyInfo files included by static CocoaPods dependencies. The workaround is to copy the SDK's declared API reasons into your app's own manifest.

Expo's guide suggests a practical route: look at the PrivacyInfo.xcprivacy files inside the libraries in your ios folder or node_modules, and aggregate their reasons into ios.privacyManifests.

Working through an ITMS-91053 email

  1. Read the email and list every API category it names.
  2. Find who uses each one. Search your node_modules and Pods for the API names, or check which libraries ship PrivacyInfo.xcprivacy files declaring them.
  3. Choose the correct reason code for how your app actually uses the API, from Apple's documentation. Don't pick codes that don't describe your usage.
  4. Add the declarations to ios.privacyManifests (Expo) or PrivacyInfo.xcprivacy (bare), rebuild and upload again.
  5. Check for a follow-up email. If none arrives after processing, you're done.
From the field: Privacy work like this sits inside the release path I own: builds, submission and store review, including the rejections and warnings that come with them. Privacy manifests are a good example of why release ownership matters, because the problem appears at upload time, long after the code that caused it was written.

Keeping the manifest correct over time

A privacy manifest isn't a one-off task. It drifts every time your dependencies change, so build it into your routine:

  • When you add an SDK, check whether it ships a PrivacyInfo.xcprivacy file and what it declares, before the first upload that includes it.
  • After Expo SDK or React Native upgrades, watch the next upload for new warnings, since libraries add and change declarations between versions.
  • During release prep, compare your manifest's collected data types with your App Privacy answers in App Store Connect.
  • In code review, treat changes to ios.privacyManifests like any other release-affecting change, with a note on which library needed it.

Treating the React Native privacy manifest as part of the release checklist means the next ITMS email is a five-minute fix instead of a release-day surprise.

How this relates to your App Privacy label

The privacy manifest and the App Privacy label in App Store Connect describe the same reality from two angles. The manifest is attached to the code, including each SDK. The label is what users see on your store page. Keep them consistent: if your manifest or an SDK declares collected data types, your App Privacy answers should include them too.

FAQ

What is ITMS-91053?

It's an App Store Connect message saying your uploaded build uses a required-reason API without declaring an approved reason in a privacy manifest. It lists the API categories involved. Add the missing declarations to your app's privacy manifest and upload a new build.

Do React Native apps need a privacy manifest?

Yes. Any iOS app that uses required-reason APIs, directly or through libraries, needs declarations, and almost every React Native app uses at least user defaults through its dependencies. Expo apps declare them in app config; bare apps edit PrivacyInfo.xcprivacy directly.

Where do I put the privacy manifest in an Expo app?

In your app config under expo.ios.privacyManifests. When you run prebuild or build with EAS, Expo generates the PrivacyInfo.xcprivacy file in the native project from that configuration.

Do I need to declare APIs used by third-party libraries?

Each library should ship its own manifest, but Apple doesn't always parse manifests inside static CocoaPods dependencies. If Apple's email lists APIs you don't use directly, copy the relevant reasons from the library's manifest into your app's manifest.

Next steps

If ITMS-91053 or other upload warnings are blocking your releases, send me the email and I'll find the source and fix the declarations. Get in touch, or see my services.

Sources

Bhuwanesh Sisodia

Bhuwanesh Sisodia

Full-Stack, Mobile & AI Engineer

Bhuwanesh Sisodia is a Full-Stack, Mobile & AI Engineer based in Mumbai, with 7+ years of experience and 50+ apps shipped to the App Store and Google Play. He works independently with startups and product teams worldwide.

About meGitHubLinkedInX

Related