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.
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.privacyManifestsin 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:
| Key | What it declares |
|---|---|
NSPrivacyAccessedAPITypes | Required-reason APIs used, each with approved reason codes |
NSPrivacyCollectedDataTypes | Types of data collected, and how they're used |
NSPrivacyTracking | Whether the app or SDK tracks users as Apple defines it |
NSPrivacyTrackingDomains | Domains 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:
| Category | Example use in a React Native app |
|---|---|
| User defaults | Storing small settings; many libraries use it under the hood |
| File timestamp | Checking when a cached file was created or modified |
| System boot time | Measuring elapsed time, for example in performance tracking |
| Disk space | Checking free space before downloading or caching media |
| Active keyboard | Detecting 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:
- Older SDK versions without manifests. Upgrade to a version that includes one.
- Manifests Apple doesn't pick up. Expo's documentation notes that Apple doesn't correctly parse all
PrivacyInfofiles 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
- Read the email and list every API category it names.
- Find who uses each one. Search your
node_modulesand Pods for the API names, or check which libraries shipPrivacyInfo.xcprivacyfiles declaring them. - 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.
- Add the declarations to
ios.privacyManifests(Expo) orPrivacyInfo.xcprivacy(bare), rebuild and upload again. - 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.xcprivacyfile 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.privacyManifestslike 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
- Privacy manifests, Expo
- Describing use of required reason API, Apple
- Privacy manifest files, Apple
- Third-party SDK requirements, Apple
- Solve "Missing API declaration" (ITMS-91053), SwiftLee
Related
How to Publish a React Native App to the App Store, Step by Step
Publish a React Native or Expo app to the App Store in 2026: developer account, App Store Connect, EAS Build and Submit, TestFlight, review and release.
App Store Rejection Reasons in 2026, and How to Fix Each One
Apple rejected 2.09M submissions in 2025. The App Store rejection reasons that come up most, what each guideline means, and how to fix them fast.
EAS Build Explained: Profiles, Credentials, and What It Costs
EAS Build explained for 2026: build profiles in eas.json, managed credentials, local builds, versioning, and what Expo's plans and per-build prices cost.
