Apple's required reason API categories and approved reason codes
Five categories, sixteen approved reason codes. Every one is reproduced below, transcribed on 6 September 2026 from Apple's own rendered documentation. That transcription method matters: Apple renders these tables client-side, so a plain HTTP fetch of the page returns an empty shell — which is why incorrect secondary copies of this table circulate, and why a wrong reason code produces a rejection that looks like a fixed problem.
Apple's rule is per-bundle: "For each executable or dynamic library in an app that uses a required reason API, the bundle that includes the executable or dynamic library needs to include a privacy manifest file that reports the API." Your app's PrivacyInfo.xcprivacy does not cover your dependencies. That single sentence is why ITMS-91053 and ITMS-91061 are the most common privacy-manifest rejections in React Native and Expo projects.
NSPrivacyAccessedAPICategoryFileTimestamp
Triggering APIs: creationDate, modificationDate, fileModificationDate, contentModificationDateKey, creationDateKey, getattrlist, getattrlistbulk, fgetattrlist, stat, fstat, fstatat, lstat, getattrlistat
| Code | Approved reason |
|---|---|
DDA9.1 | Display file timestamps to the person using the device. Information accessed for this reason, or any derived information, may not be sent off-device. |
C617.1 | Access the timestamps, size, or other metadata of files inside the app container, app group container, or the app's CloudKit container. |
3B52.1 | Access the timestamps, size, or other metadata of files or directories the user specifically granted access to, such as via a document picker view controller. |
0A2A.1 | Third-party SDKs only. Wrapper function around file-timestamp APIs, accessed only when the app calls the wrapper. Not available if the SDK was created primarily to wrap required reason APIs. Derived information may not be used for the SDK's own purposes or sent off-device by the SDK. |
Why RN and Expo apps hit this: stat, fstat and getattrlist are ordinary C library calls. Any native module that touches the filesystem — caching layers, image loaders, SQLite wrappers, file pickers, crash reporters — can pull the category in without a line of your own code being involved. For most app-level RN usage the correct declaration is C617.1, because you are reading metadata of files in your own container.
NSPrivacyAccessedAPICategorySystemBootTime
Triggering APIs: systemUptime, mach_absolute_time()
| Code | Approved reason |
|---|---|
35F9.1 | Measure elapsed time between events within the app, or perform calculations to enable timers. Not sent off-device — with an exception for the elapsed time between in-app events, which may be. |
8FFB.1 | Calculate absolute timestamps for events within your app, such as UIKit or AVFAudio events. Those timestamps may be sent off-device; boot time itself and anything else derived from it may not. |
3D61.1 | Include system boot time in an optional bug report the person chooses to submit, where the boot-time information is prominently displayed as part of the report. May only be sent after the user affirmatively submits that specific report. |
Why RN and Expo apps hit this: mach_absolute_time() is the standard high-resolution clock on Apple platforms. Animation libraries, performance instrumentation, analytics SDKs and the JavaScript engine itself are all plausible sources. For a React Native app measuring its own timings, 35F9.1 is normally the accurate declaration.
NSPrivacyAccessedAPICategoryDiskSpace
Triggering APIs: volumeAvailableCapacityKey, volumeAvailableCapacityForImportantUsageKey, volumeAvailableCapacityForOpportunisticUsageKey, volumeTotalCapacityKey, systemFreeSize, systemSize, statfs, statvfs, fstatfs, fstatvfs, getattrlist, fgetattrlist, getattrlistat
| Code | Approved reason |
|---|---|
85F4.1 | Display disk-space information to the person using the device, in bytes or in time-plus-media-type units. Not sent off-device, with a narrow local-network exception requiring explicit permission and never over the internet. |
E174.1 | Check whether there is sufficient disk space to write files, or whether space is low so the app can delete files. The app must behave differently based on disk space in a way that is observable to users. |
7D9E.1 | Include disk-space information in an optional, user-submitted bug report where it is prominently displayed. |
B728.1 | Health research apps only, to detect and inform research participants about low disk space impacting research data collection. Must comply with Guideline 5.1.3, and the app must not offer functionality beyond health research. |
The trap in E174.1: the "observable to users" condition is a real requirement, not boilerplate. If a dependency silently checks free space and nothing in your UI changes as a result, E174.1 is not an accurate declaration for it.
NSPrivacyAccessedAPICategoryActiveKeyboards
Triggering API: activeInputModes
| Code | Approved reason |
|---|---|
3EC4.1 | Custom keyboard apps only, where providing a systemwide custom keyboard is the primary functionality. Not sent off-device. |
54BD.1 | Present the correct customised interface. The app must have text fields for entering or editing text, and must behave observably differently based on active keyboards. Not sent off-device. |
If you are not a keyboard app and you are seeing this category, look at keyboard-management dependencies. IQKeyboardManager and IQKeyboardManagerSwift are both on Apple's SDK list, and both are common in React Native projects via wrappers.
NSPrivacyAccessedAPICategoryUserDefaults
Triggering API: UserDefaults
| Code | Approved reason |
|---|---|
CA92.1 | Read and write information accessible only to the app itself. Does not permit reading what other apps or the system wrote, or writing what other apps can read. |
1C8F.1 | Read and write information accessible only to the apps, extensions and App Clips in the same App Group. |
C56D.1 | Third-party SDKs only. Wrapper around UserDefaults APIs, accessed only when the app calls the wrapper. Not available if the SDK exists primarily to wrap required reason APIs. |
AC6B.1 | Read com.apple.configuration.managed for MDM managed app configuration, or write com.apple.feedback.managed for MDM feedback. |
Why almost every RN app needs this one: AsyncStorage and most persistence and settings libraries land on UserDefaults underneath. For an ordinary app storing its own preferences, CA92.1 is the accurate declaration. Use 1C8F.1 only if you genuinely share a suite with an extension or App Clip.
The rules people get wrong
Do not declare every code "to be safe." Apple's wording is that you must declare reasons that "accurately reflect your use," and that you "may use these APIs and the data derived from their use for the declared reasons only." Several codes carry binding conditions — not sending data off-device, behaving observably differently, being a keyboard app — that you inherit by declaring them.
Do not put your dependencies' usage in your app's manifest. Apple is explicit that a third-party SDK "can't rely on the privacy manifest files for apps that link the third-party SDK." The manifest has to be in the SDK's own bundle. If a dependency is missing one, the fix is upstream — update the package, or replace it.
Do not assume Xcode aggregates static CocoaPods correctly. Expo's own Apple privacy guide states that "Apple does not correctly parse all the PrivacyInfo files included by static CocoaPods dependencies," and recommends manually walking node_modules for PrivacyInfo.xcprivacy files and aggregating the values yourself.
Do not treat this list as permanent. Apple states it "continually reviews the list of required reason APIs and reasons for usage, and will update this article from time to time." This page carries the date it was transcribed for exactly that reason.
A first pass you can run in five seconds
find node_modules -name "PrivacyInfo.xcprivacy" | sed 's|node_modules/||' | cut -d/ -f1 | sort -uThat lists the packages that already ship a manifest. Compare the result against Apple's third-party SDK list — the gap is your risk surface.
This is roughly the first thing shipcheck does, before it goes on to read what each manifest actually declares and compare it against what the binaries appear to use. What shipcheck is.
Transcribed 6 September 2026 from Apple's rendered documentation. Apple updates this list. Before you rely on a code, open the source page in a browser and confirm it. A wrong reason code produces a rejection that looks exactly like a fixed problem.
Questions and answers
What are Apple's required reason API categories?
There are five - NSPrivacyAccessedAPICategoryFileTimestamp, NSPrivacyAccessedAPICategorySystemBootTime, NSPrivacyAccessedAPICategoryDiskSpace, NSPrivacyAccessedAPICategoryActiveKeyboards and NSPrivacyAccessedAPICategoryUserDefaults. Each has its own list of approved reason codes and you must declare one that accurately reflects your use.
What reason code do I use for UserDefaults?
CA92.1 for information accessible only to the app itself, 1C8F.1 for information shared within the same App Group, C56D.1 only if you are a third-party SDK wrapping the API for a host app, and AC6B.1 for MDM managed configuration and feedback keys. Most app-level UserDefaults usage in a React Native app is CA92.1.
Why does ITMS-91053 mention file timestamps when I never touch files?
Because a dependency does. The requirement is per-bundle - Apple's documentation says each executable or dynamic library that uses a required reason API must have a privacy manifest in its own bundle. Your app's manifest does not cover your dependencies, and stat, fstat and getattrlist are extremely common inside native modules you did not write.
Can I just declare every reason code to be safe?
No. Apple's wording is that you must declare one or more approved reasons that accurately reflect your use, and that you may use the APIs and derived data only for the declared reasons. Over-declaring is a misdeclaration, and several reason codes carry conditions such as not sending data off-device that you would then be bound by.
Which reason codes may only be used by third-party SDKs?
0A2A.1 for file timestamps and C56D.1 for user defaults. Both are wrapper-function reasons, both are explicitly limited to third-party SDKs, and both are unavailable if the SDK exists primarily to wrap required reason APIs.
shipcheck. “Apple's required reason API categories and approved reason codes.” Baker Ventures LLC, September 6, 2026. https://shipcheck.bakerventuresstudio.com/rejections/required-reason-api-reference/