ITMS-91053 "Missing API declaration": why Apple flags your build and how to fix it
4 Feb 2026 · 5 min read · Erik van Kammen
ITMS-91053 "Missing API declaration" is the warning App Store Connect sends when your build calls a Required Reason API, such as UserDefaults, file timestamps, or free disk space, without an approved reason code declared in a privacy manifest. Apple has blocked releases over it since May 2024, and third-party SDKs in your binary count against you.
The email usually arrives minutes after you upload. It is the early warning; the block comes when you submit that build for review. Apple started warning teams on March 13, 2024, began enforcing on May 1, 2024, and it still catches builds today for one simple reason: the APIs on the list look harmless.
This guide explains what NSPrivacyAccessedAPITypes is, which APIs trigger ITMS-91053, how to configure the declaration correctly, and where teams make mistakes.
Apple introduced privacy manifests to reduce device fingerprinting.
Certain system APIs can expose signals like:
These signals can be combined to identify a device across apps.
Apple now requires you to:
This creates an auditable link between API usage and user benefit.
This applies to your full binary, including all third-party SDKs.
Example: if an SDK calls attributesOfItem(atPath:) and you don't declare file timestamp usage, you get ITMS-91053.
At the time of writing, Apple defines five categories that require declared reasons.
| Category | Key APIs | Common Reason Codes |
|---|---|---|
| File timestamp | creationDate, modificationDate, stat() |
DDA9.1, C617.1, 3B52.1 |
| System boot time | systemUptime, mach_absolute_time() |
35F9.1, 8FFB.1, 3D61.1 |
| Disk space | Volume capacity queries, available storage checks | E174.1, 85F4.1, 7D9E.1 |
| Active keyboards | activeInputModes |
3EC4.1, 54BD.1 |
| User defaults | All UserDefaults reads and writes |
CA92.1, 1C8F.1, C56D.1 |
NSPrivacyAccessedAPICategoryFileTimestamp
Covers: creationDate, modificationDate, stat(), getattrlist()
Common reasons:
DDA9.1 for showing timestamps to the userC617.1 for accessing metadata inside your app container3B52.1 for user-granted file accessNSPrivacyAccessedAPICategorySystemBootTime
Covers: systemUptime, mach_absolute_time()
Common reasons:
35F9.1 for measuring elapsed time inside the app8FFB.1 for generating timestamps3D61.1 for including boot time in an optional, user-initiated bug reportNSPrivacyAccessedAPICategoryDiskSpace
Covers: checking available storage, volume capacity queries
Common reasons:
E174.1 for verifying available space before writing files85F4.1 for displaying storage to the user7D9E.1 for optional diagnostics or bug reportsNSPrivacyAccessedAPICategoryActiveKeyboards
Covers: activeInputModes
Common reasons:
3EC4.1 for keyboard apps54BD.1 for adapting UI to keyboard settingsNSPrivacyAccessedAPICategoryUserDefaults
Covers all UserDefaults reads and writes. This applies even if usage is indirect through frameworks.
Common reasons:
CA92.1 for app-local storage1C8F.1 for App Group shared storageC56D.1 for SDK wrappersThe privacy manifest is a property list file named PrivacyInfo.xcprivacy. You can create it in Xcode via File > New > File > App Privacy.
Example structure:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>
Key points:
About format: both XML and binary plist formats are valid. XML is easier to review and debug.
Apple evaluates the full binary.
Typical failure case: an analytics SDK uses systemUptime, no manifest entry exists, and you get ITMS-91053. This is the most common issue in real projects.
Reason codes are specific. Using CA92.1 while sharing data via App Groups is incorrect. The correct code is 1C8F.1.
Apple does validate reasons. Enforcement isn't fully consistent, but incorrect mappings can lead to rejection.
New SDK added, manifest not updated, violation appears in the next release. Treat privacy manifest updates as part of your dependency review process.
The file exists in your project but isn't in Copy Bundle Resources. Apple behaves as if no manifest exists.
Not all SDKs ship a privacy manifest. If a framework has no PrivacyInfo.xcprivacy, you must cover its API usage yourself, or replace the SDK.
Swift Package Manager:
In Xcode, archive your app, right-click the archive, and select "Generate Privacy Report." This shows detected API usage and included privacy manifests. Note that this report is useful but not always complete.
Manual inspection:
Open your built .app bundle, navigate to Frameworks, and check each framework for PrivacyInfo.xcprivacy.
Quick audit command:
find /path/to/YourApp.app -name "PrivacyInfo.xcprivacy"
Compare the output with your embedded frameworks. Missing entries indicate gaps.
Manual checks don't scale. New dependencies, SDK updates, and build configuration changes can all introduce issues.
A reliable approach: analyze the compiled IPA, detect actual API usage, and compare with declared reasons.
AppCompliance does this at binary level and integrates with CI systems like GitHub Actions, GitLab CI, and Jenkins. No tool guarantees approval (Apple review still includes manual checks), but catching violations before submission reduces delays.
Apple also keeps a list of commonly used SDKs that must ship their own privacy manifest and signature. Missing that one produces the sibling code ITMS-91061, and the fix belongs to the SDK vendor, not to you.
Xcode can generate a privacy report on an archive, which is a good manual check; the hard part is repeating it on every release. Missing declarations are one class of technical rejection. Code that can change your app's behaviour after review is another.
To fix NSPrivacyAccessedAPITypes violations:
This isn't optional anymore. Apple continues to expand enforcement. If you treat the privacy manifest as part of your release pipeline, these warnings become predictable and preventable.
Everything technical in this post is checkable from the build itself, and that is exactly what AppCompliance does: upload an iOS or Android build, and minutes later you have every issue that would get it rejected, with the exact fix next to it.
One email when we open the doors. No spam, just the launch.