App Store Submission Reference
Overview
Complete reference for every App Store submission requirement:
- Part 1 — Required metadata fields (descriptions, screenshots, keywords, App Review info)
- Part 2 — Privacy requirements (manifest schema, nutrition labels, ATT, Required Reason APIs)
- Part 3 — App Review Guidelines quick reference (all sections 1-5)
- Part 4 — Age rating system (5-tier, capabilities, regional variations)
- Part 5 — Export compliance (encryption decision tree)
- Part 6 — Account and authentication requirements (deletion, SIWA)
- Part 7 — Monetization and IAP submission pipeline
- Part 8 — EU-specific compliance (DSA trader status)
- Part 9 — Build upload and processing
- Part 10 — WWDC25 changes (draft submissions, accessibility labels, tags)
When to Use This Skill
Use when
- Looking up specific metadata field requirements or character limits
- Checking App Review guideline numbers for a specific topic
- Verifying privacy manifest schema fields or Required Reason API categories
- Understanding age rating tiers and new capability declarations
- Checking EU compliance requirements for DSA trader status
- Understanding IAP submission pipeline and review flow
- Preparing builds for upload (SDK requirements, encryption, signing)
Do NOT use when
- Deciding if your app is ready to submit (use app-store-submission)
- Troubleshooting a rejection (use app-store-diag)
- Implementing in-app purchases (use storekit-ref)
- Writing privacy manifest code (use privacy-ux)
- Auditing accessibility compliance (use accessibility-diag)
Related Skills
- app-store-submission — Discipline skill with pre-flight checklist and workflow
- app-store-diag — Rejection troubleshooting and appeal guidance
- privacy-ux — Privacy manifest implementation, ATT UX, permission requests
- storekit-ref — StoreKit 2 API reference for IAP implementation
- accessibility-diag — Accessibility compliance scanning and VoiceOver testing
Key Terminology
| Term |
Definition |
| App Store Connect |
Web portal and API for managing app metadata, builds, pricing, TestFlight, and analytics |
| App Review |
Apple's human review process that evaluates every app update against the App Review Guidelines |
| Privacy Manifest |
PrivacyInfo.xcprivacy file declaring data collection, tracking domains, and Required Reason API usage |
| Required Reason API |
System APIs (file timestamps, disk space, user defaults, etc.) that require declared usage reasons |
| Privacy Nutrition Label |
App Store privacy cards showing what data your app collects and how it uses it |
| DSA Trader Status |
EU Digital Services Act classification determining if you are a "trader" selling to EU consumers |
| Build String |
Unique identifier for each uploaded build (e.g., "1.2.3.4"), separate from version number |
| Bundle ID |
Reverse-domain identifier (e.g., "com.company.app") uniquely identifying your app across Apple's ecosystem |
Part 1: Required Metadata Fields
Immutable Fields (Cannot Change After Creation)
These fields are locked once set. Choose carefully:
- Bundle ID — must match Xcode project exactly
- SKU — internal identifier, never shown to users
- IAP Product ID — cannot be changed or reused after creation
- Subscription Duration — locked after subscription is created
App Information
| Field |
Required |
Localizable |
Max Length |
Notes |
| App Name |
Yes |
Yes |
30 chars |
Must be unique on the App Store |
| Subtitle |
No |
Yes |
30 chars |
Appears below app name in search results |
| Description |
Yes |
Yes |
4000 chars |
Plain text, no HTML or rich formatting |
| Promotional Text |
No |
Yes |
170 chars |
Editable without new submission |
| Keywords |
Yes |
Yes |
100 bytes |
Comma-separated, each keyword >2 chars |
| What's New |
Yes* |
Yes |
4000 chars |
*Required for all versions except first |
| Copyright |
Yes |
No |
— |
Format: "YYYY Company Name" |
| Support URL |
Yes |
Yes |
— |
Must link to actual contact information |
| Marketing URL |
No |
Yes |
— |
Optional promotional page |
| Privacy Policy URL |
Yes |
Yes |
— |
HTTPS, publicly accessible |
Visual Assets
| Asset |
Required |
Localizable |
Specification |
| App Icon |
Yes |
No |
1024x1024 PNG, no alpha, no rounded corners |
| Screenshots |
Yes |
Yes |
Per device size, 2-10 per locale per device |
| App Preview |
No |
Yes |
Up to 3 videos per device size per locale |
Screenshot Requirements
Format: .jpeg, .jpg, .png. Min 1, max 10 per device size per locale.
Fallback: Provide highest resolution only — App Store auto-scales to smaller sizes. Required: 6.9" or 6.5" for iPhone, 13" for iPad.
| Device |
Portrait |
Landscape |
| iPhone 6.9" (Air, 17 Pro Max, 16 Pro Max) |
1260x2736 |
2736x1260 |
| iPhone 6.5" (14 Plus, 13 Pro Max, XS Max) |
1284x2778 or 1242x2688 |
2778x1284 or 2688x1242 |
| iPhone 6.3" (17 Pro, 16 Pro, 16, 15 Pro) |
1179x2556 or 1206x2622 |
2556x1179 or 2622x1206 |
| iPhone 6.1" (17e, 16e, 14, 13, 12) |
1170x2532, 1125x2436, or 1080x2340 |
2532x1170, 2436x1125, or 2340x1080 |
| iPhone 5.5" (8 Plus, 7 Plus) |
1242x2208 |
2208x1242 |
| iPad 13" (Pro M5/M4, Air M4/M3) |
2064x2752 or 2048x2732 |
2752x2064 or 2732x2048 |
| iPad 11" (Pro, Air, mini, 10th gen) |
1488x2266 or 1668x2420 |
2266x1488 or 2420x1668 |
| Mac |
1280x800, 1440x900, 2560x1600, or 2880x1800 |
— |
| Apple TV |
1920x1080 or 3840x2160 |
— |
| Apple Vision Pro |
3840x2160 |
— |
Screenshots must show the app in actual use. Not permitted: title art alone, login screens, splash screens, or screens from other platforms. Cannot update screenshots on an approved version — must create a new version.
App Preview Video Specifications
| Spec |
Value |
| Duration |
15-30 seconds |
| Max file size |
500 MB |
| Max frame rate |
30 fps |
| Max per device/locale |
3 |
| H.264 |
10-12 Mbps, .mov/.m4v/.mp4, 256 kbps AAC stereo |
| ProRes 422 HQ |
~220 Mbps VBR, .mov only, PCM or 256 kbps AAC stereo |
| Audio sample rate |
44.1 or 48 kHz |
| Orientation |
Portrait or landscape (Mac/tvOS/visionOS: landscape only) |
Gotchas: Processing can take up to 24 hours — do not submit for review immediately after uploading previews. All audio tracks must be enabled (disabled tracks cause rejection). Previews always appear before screenshots on the product page.
App Icon Requirements
| Specification |
Requirement |
| Size |
1024 x 1024 pixels |
| Format |
PNG |
| Color space |
sRGB or P3 |
| Alpha channel |
Not allowed |
| Rounded corners |
Not allowed (system applies automatically) |
| Layers/transparency |
Not allowed |
| Content |
Must be appropriate for 4+ rating regardless of app's actual rating |
App Review Information
| Field |
Required |
Notes |
| Contact First Name |
Yes |
Reviewer contact |
| Contact Last Name |
Yes |
Reviewer contact |
| Contact Email |
Yes |
Must be monitored |
| Contact Phone |
Yes |
Include country code |
| Notes for Review |
No |
Up to 4000 bytes; explain non-obvious features |
| Sign-in Username |
If login required |
Must not expire during review |
| Sign-in Password |
If login required |
Must not expire during review |
| Attachment |
No |
Up to 10 files, max 512 MB total |
Metadata Rules (Guideline 2.3)
- App names must be unique, max 30 characters
- Keywords must not include trademarked terms, popular app names, or pricing terms ("free", "sale")
- Screenshots must show the app in use, not just marketing art
- Icons, screenshots, and previews must be appropriate for a 4+ rating even if the app is rated higher
- "For Kids" and "For Children" are reserved for the Kids category
- No other mobile platform names or imagery in screenshots (no Android phones, Windows logos)
- Metadata must accurately reflect app functionality; misleading metadata is grounds for rejection
Localization Requirements
| Aspect |
Details |
| Minimum |
Primary language required; all other localizations optional |
| Per-locale metadata |
App name, subtitle, description, keywords, What's New, screenshots |
| Promotional Text |
Localizable and editable without new submission |
| Screenshots |
Can differ per locale (show localized UI) |
| App Previews |
Can differ per locale (show localized audio/UI) |
| URL fields |
Support URL and Marketing URL can differ per locale |
When localizing, provide screenshots that match the localized UI. Reviewers check that screenshots accurately represent the app in each locale.
Category Selection
| Primary Category |
Secondary Category |
Rules |
| Required |
Optional |
Choose the category that best describes your app |
| Must be accurate |
Can complement primary |
Inaccurate category is grounds for rejection (2.3.7) |
| Games have subcategories |
— |
Games must also select up to 2 game subcategories |
Available categories: Books, Business, Developer Tools, Education, Entertainment, Finance, Food & Drink, Games, Graphics & Design, Health & Fitness, Lifestyle, Magazines & Newspapers, Medical, Music, Navigation, News, Photo & Video, Productivity, Reference, Shopping, Social Networking, Sports, Travel, Utilities, Weather.
Part 2: Privacy Requirements
Privacy Policy (Guideline 5.1.1(i))
Required in BOTH locations:
- App Store Connect metadata (Privacy Policy URL field)
- Within the app itself (accessible from settings or equivalent)
The privacy policy must identify:
- What data is collected and by what means
- All uses of collected data
- Third-party sharing practices
- Data retention and deletion policies
- How users can revoke consent
Privacy Manifest Schema (PrivacyInfo.xcprivacy)
<!-- Top-level keys -->
NSPrivacyTracking <!-- Boolean: Does app track users? -->
NSPrivacyTrackingDomains <!-- Array<String>: Domains used for tracking -->
NSPrivacyCollectedDataTypes <!-- Array<Dictionary>: Data collected -->
NSPrivacyAccessedAPITypes <!-- Array<Dictionary>: Required Reason APIs -->
NSPrivacyCollectedDataTypes Entry
Each dictionary in the array contains:
| Key |
Type |
Description |
NSPrivacyCollectedDataType |
String |
Category key (e.g., "NSPrivacyCollectedDataTypeName") |
NSPrivacyCollectedDataTypePurposes |
Array<String> |
Purpose keys for this data type |
NSPrivacyCollectedDataTypeLinked |
Boolean |
Is this data linked to user identity? |
NSPrivacyCollectedDataTypeTracking |
Boolean |
Is this data used for tracking? |
NSPrivacyAccessedAPITypes Entry
Each dictionary in the array contains:
| Key |
Type |
Description |
NSPrivacyAccessedAPIType |
String |
API category identifier |
NSPrivacyAccessedAPITypeReasons |
Array<String> |
Approved reason codes for usage |
Complete PrivacyInfo.xcprivacy Example
<?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>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeEmailAddress</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<true/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
</array>
</dict>
</array>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>
API Category Identifiers
| Category |
Identifier String |
| File timestamp |
NSPrivacyAccessedAPICategoryFileTimestamp |
| System boot time |
NSPrivacyAccessedAPICategorySystemBootTime |
| Disk space |
NSPrivacyAccessedAPICategoryDiskSpace |
| Active keyboard |
NSPrivacyAccessedAPICategoryActiveKeyboards |
| User defaults |
NSPrivacyAccessedAPICategoryUserDefaults |
Generating Aggregate Privacy Report
Xcode > Product > Archive > Generate Privacy Report
This produces a PDF summarizing privacy manifests from your app and all embedded frameworks.
Privacy manifest gotchas:
- Custom string values for
NSPrivacyCollectedDataType or NSPrivacyCollectedDataTypePurposes are silently rejected by Xcode — must use Apple's predefined constants
- iOS 17 automatically blocks connections to declared tracking domains when user denies tracking
- IP address collection must be declared (as location, device ID, or diagnostics)
- Web view data collection must be declared
- You are responsible for ALL data collected by third-party SDKs in your app
- Some SDKs default to tracking unless explicitly disabled — creates unintentional tracking
- Fingerprinting is NEVER allowed, regardless of ATT permission
- Since May 1, 2024: missing required-reason API declarations cause automatic rejection (no human review)
Required Reason API Categories
| Category |
APIs Covered |
Common Reasons |
| File timestamp |
NSFileCreationDate, NSFileModificationDate, NSURLContentModificationDateKey |
DDA9.1 (display to user), C617.1 (inside app container) |
| System boot time |
systemUptime, mach_absolute_time |
35F9.1 (measure elapsed time) |
| Disk space |
NSFileSystemFreeSize, NSFileSystemSize, volumeAvailableCapacityKey |
E174.1 (check before writing), 85F4.1 (display to user) |
| Active keyboard |
activeInputModes |
54BD.1 (customize UI for keyboard) |
| User defaults |
UserDefaults (all access requires declaration) |
CA92.1 (access within app group), 1C8F.1 (access within same app) |
App Privacy Details (Nutrition Labels)
Data Type Categories
| Category |
Examples |
| Contact Info |
Name, email address, phone number, physical address |
| Health & Fitness |
Health data, fitness data |
| Financial Info |
Payment info, credit info |
| Location |
Precise location, coarse location |
| Sensitive Info |
Racial or ethnic data, sexual orientation, religion, biometrics |
| Contacts |
Address book contacts |
| User Content |
Photos, videos, audio, gameplay content, customer support messages |
| Browsing History |
Web browsing history |
| Search History |
In-app search history |
| Identifiers |
User ID, device ID |
| Purchases |
Purchase history |
| Usage Data |
Product interaction, advertising data, app launches, taps, scrolls |
| Diagnostics |
Crash data, performance data |
| Surroundings |
Environment scanning (e.g., AR data) |
| Body |
Hands, head (e.g., hand tracking in visionOS) |
Purpose Categories
| Purpose |
Description |
| Third-Party Advertising |
Displaying third-party ads or sharing with ad networks |
| Developer's Advertising/Marketing |
Your own marketing campaigns |
| Analytics |
Understanding user behavior and measuring effectiveness |
| Product Personalization |
Customizing features, content recommendations |
| App Functionality |
Required for app to work (e.g., authentication, data sync) |
| Other |
Any purpose not listed above |
Tracking and Collection Definitions
"Collected" means data is transmitted off-device and accessible beyond what is needed to service the current request. On-device-only processing is NOT collection.
"Tracking" means:
- Linking user/device data from your app with third-party data for advertising or measurement, OR
- Sharing user/device data with a data broker
App Tracking Transparency (ATT)
Required if your app "tracks" per Apple's definition above.
- Add
NSUserTrackingUsageDescription to Info.plist (explains why tracking is needed)
- Call
ATTrackingManager.requestTrackingAuthorization() before tracking
- Respect the result:
.authorized — User granted permission to track
.denied — User denied tracking; do not track
.notDetermined — User has not yet been asked
.restricted — Device-level restriction prevents tracking
Request at a contextually appropriate moment, not at first launch.
Common Purpose Strings (NS*UsageDescription)
These Info.plist keys must be present for each system permission your app requests:
| Permission |
Info.plist Key |
| Camera |
NSCameraUsageDescription |
| Microphone |
NSMicrophoneUsageDescription |
| Photo Library (read) |
NSPhotoLibraryUsageDescription |
| Photo Library (write) |
NSPhotoLibraryAddUsageDescription |
| Location (when in use) |
NSLocationWhenInUseUsageDescription |
| Location (always) |
NSLocationAlwaysAndWhenInUseUsageDescription |
| Contacts |
NSContactsUsageDescription |
| Calendars (full access) |
NSCalendarsFullAccessUsageDescription |
| Reminders (full access) |
NSRemindersFullAccessUsageDescription |
| Health |
NSHealthShareUsageDescription, NSHealthUpdateUsageDescription |
| Motion |
NSMotionUsageDescription |
| Bluetooth |
NSBluetoothAlwaysUsageDescription |
| Face ID |
NSFaceIDUsageDescription |
| Local Network |
NSLocalNetworkUsageDescription |
| Tracking |
NSUserTrackingUsageDescription |
| Speech Recognition |
NSSpeechRecognitionUsageDescription |
| Apple Music |
NSAppleMusicUsageDescription |
Missing purpose strings cause immediate rejection. Purpose string text must clearly explain why the permission is needed in the context of your app's functionality.
Third-Party SDK Privacy Manifests
Apple maintains a list of commonly used SDKs that require privacy manifests. Starting spring 2024, if your app includes these SDKs without privacy manifests, it will be flagged during submission.
Third-party SDKs should include their own PrivacyInfo.xcprivacy in their framework bundle. The aggregate privacy report combines all manifests from your app and embedded frameworks.
If a third-party SDK does not include a privacy manifest, you must declare its data collection in your app's privacy manifest.
Part 3: App Review Guidelines Quick Reference
For the complete guideline index (Sections 1-5), see references/app-review-guidelines.md.
Most Common Rejection Reasons
See references/app-review-guidelines.md for the full top-10 rejection causes table with percentages.
App Review Timeline
| Stage |
Typical Duration |
| Waiting for Review |
Minutes to hours |
| In Review |
Minutes to 24 hours |
| Total (90th percentile) |
Under 24 hours |
| Total (edge cases) |
Up to 7 days |
| Expedited Review |
Same day to 24 hours (if approved) |
Review times increase during holidays and major iOS release periods. Plan submissions accordingly.
Part 4: Age Rating System
Five-Tier Rating System (Updated January 31, 2026)
| Rating |
Triggers |
| 4+ |
No objectionable material |
| 9+ |
Infrequent or mild: profanity, cartoon/fantasy violence, horror/fear themes. Loot boxes present |
| 13+ |
Frequent or intense: profanity or crude humor. Infrequent: alcohol/tobacco/drugs references, sexual content/nudity, realistic violence |
| 16+ |
Unrestricted web access, frequent medical/treatment info, mature/suggestive themes |
| 18+ |
Frequent or intense: alcohol/tobacco/drugs use, sexual content/nudity, realistic violence. Simulated gambling with real-money elements |
| Unrated |
App cannot be published without completing the questionnaire |
Capability Declarations (New, WWDC25)
Apps must declare if they include these capabilities:
| Capability |
When to Declare |
| Messaging/chat |
Any in-app messaging between users |
| User-generated content |
Users can post, share, or upload content visible to others |
| Advertising |
App displays ads from any ad network |
| Parental controls |
App has parental restrictions or family features |
| Age assurance |
App verifies user age for restricted content |
These declarations appear alongside the age rating on the App Store product page, giving parents and users additional transparency.
Regional Variations
Age ratings map differently across regions:
| Apple Rating |
Australia |
Brazil |
Korea |
Germany (USK) |
| 4+ |
4+ |
L (All ages) |
All |
0 |
| 9+ |
9+ |
A10 |
12+ |
6 |
| 13+ |
13+ |
A12 |
15+ |
12 |
| 16+ |
15+ |
A16 |
19+ |
16 |
| 18+ |
R 18+ |
A18 |
19+ |
18 |
The age rating questionnaire automatically generates the appropriate regional ratings based on your answers.
Age Rating Best Practices
- Answer the questionnaire conservatively; under-rating leads to rejection
- If your app accesses unrestricted web content (WebView without content filter), it will be rated 16+ minimum
- UGC apps typically need 13+ minimum due to moderation requirements
- Simulated gambling (even without real money) requires at least 9+
- Realistic violence in gameplay requires at least 13+
Age Rating Questionnaire Topics
The questionnaire covers these content categories:
| Category |
Options |
| Cartoon or Fantasy Violence |
None, Infrequent/Mild, Frequent/Intense |
| Realistic Violence |
None, Infrequent/Mild, Frequent/Intense |
| Profanity or Crude Humor |
None, Infrequent/Mild, Frequent/Intense |
| Mature/Suggestive Themes |
None, Infrequent/Mild, Frequent/Intense |
| Alcohol, Tobacco, or Drug Use or References |
None, Infrequent/Mild, Frequent/Intense |
| Sexual Content and Nudity |
None, Infrequent/Mild, Frequent/Intense |
| Horror/Fear Themes |
None, Infrequent/Mild, Frequent/Intense |
| Simulated Gambling |
None, Infrequent/Mild, Frequent/Intense |
| Medical/Treatment Information |
None, Infrequent/Mild, Frequent/Intense |
| Unrestricted Web Access |
Yes/No |
The system automatically calculates your app's age rating across all regions based on your answers.
Part 5: Export Compliance
Three-Tier Encryption System
| Tier |
Encryption Type |
Documentation Required |
| Exempt |
Apple OS built-in (HTTPS via URLSession, AES data protection, CryptoKit, Keychain, Secure Enclave) |
None — set ITSAppUsesNonExemptEncryption = NO |
| Standard |
Industry-standard algorithms (IEEE, IETF, ISO, ITU, ETSI, 3GPP approved) |
French ANSSI declaration only (if distributing in France) |
| Proprietary |
Custom/unpublished algorithms not adopted by standards bodies |
US CCATS + French declaration (if France) |
Encryption Decision Tree
Does your app use encryption?
├── No → ITSAppUsesNonExemptEncryption = NO → Done
├── Only Apple OS encryption (HTTPS, Keychain, CryptoKit)?
│ ├── Yes → ITSAppUsesNonExemptEncryption = NO → Done
│ │ (May need annual BIS self-classification report)
│ └── No → Industry-standard algorithm (AES, RSA, etc.)?
│ ├── Yes → ITSAppUsesNonExemptEncryption = YES
│ │ French declaration if distributing in France
│ │ Upload docs → receive ITSEncryptionExportComplianceCode
│ └── No (custom/proprietary) →
│ ITSAppUsesNonExemptEncryption = YES
│ US CCATS required (~2 business days)
│ French declaration if France
│ Upload docs → receive ITSEncryptionExportComplianceCode
Info.plist Keys
<!-- Most apps: only Apple OS encryption -->
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<!-- Apps with non-exempt encryption (bypasses questionnaire on future submissions) -->
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<key>ITSEncryptionExportComplianceCode</key>
<string>YOUR_COMPLIANCE_CODE</string>
Setting ITSAppUsesNonExemptEncryption in Info.plist skips the encryption questionnaire on every submission.
Exempt Encryption Uses
No documentation needed:
- HTTPS/TLS (URLSession, Network.framework, WKWebView)
- Secure Enclave, Keychain, biometric auth
- CryptoKit, Security.framework per Apple docs
- Password hashing (bcrypt, scrypt, PBKDF2)
Non-Exempt Encryption Uses
Documentation required:
- Custom encryption algorithms
- OpenSSL, libsodium for non-standard purposes
- End-to-end encrypted messaging
- VPN implementations
- Custom DRM systems
France-Specific
Import/export controlled by ANSSI. Banking and medical apps are exempt. Applies to: secure storage, secure communications, security/antivirus apps.
Part 6: Account and Authentication
Account Deletion (Required Since June 2022)
Apps that support account creation must offer account deletion. Requirements:
| Requirement |
Details |
| Full deletion |
Must fully delete the account, not just deactivate |
| Easy to find |
Must be accessible from app settings; not buried behind support tickets |
| Inform timeline |
Tell user how long deletion takes |
| Confirm completion |
Notify user when deletion is complete |
| Delete shared UGC |
Must handle user-generated content shared with others |
| Revoke SIWA tokens |
Call Apple's revoke token endpoint for Sign in with Apple accounts |
| Handle subscriptions |
Warn about active subscriptions; direct to subscription management |
Sign in with Apple Token Revocation
// Server-side: revoke SIWA tokens when account deleted
// POST https://appleid.apple.com/auth/revoke
// Parameters: client_id, client_secret, token, token_type_hint
Failing to revoke SIWA tokens during account deletion is a common rejection reason.
Sign in with Apple (Guideline 4.8)
Required when: Your app offers ANY third-party or social login option (Google, Facebook, Twitter, email/password via third-party provider).
Exceptions — SIWA not required when
- App is for company employees only (internal enterprise app)
- App is for education or enterprise with existing institutional auth
- App uses government or industry-backed citizen ID systems
- App is a client for a specific third-party service (e.g., Gmail app, Slack)
When SIWA is required, it must be offered as an equally prominent option alongside other sign-in methods. It cannot be hidden or given less visual weight.
Account Deletion Implementation Checklist
| Step |
Details |
| 1. Add UI entry point |
Settings screen, clearly labeled "Delete Account" |
| 2. Explain consequences |
Show what will be deleted (data, subscriptions, purchases) |
| 3. Require confirmation |
User must explicitly confirm deletion |
| 4. Handle active subscriptions |
Direct user to cancel active subscriptions before deletion |
| 5. Process deletion |
Delete all user data from your servers |
| 6. Revoke SIWA tokens |
Call Apple's revoke endpoint if SIWA was used |
| 7. Confirm to user |
Send email or in-app confirmation when deletion is complete |
| 8. Define timeline |
State how long deletion takes (immediately, 30 days, etc.) |
Apple specifically rejects apps that:
- Require users to call a phone number to delete their account
- Require users to send an email to request deletion
- Only offer account deactivation (hiding profile) instead of full deletion
- Don't handle SIWA token revocation
Part 7: Monetization and IAP
IAP Submission Pipeline
In-app purchases have a separate review process from app submissions:
| Scenario |
Behavior |
| First IAP ever |
Must be bundled with a new app version submission |
| Subsequent IAPs |
Can be submitted independently of app updates |
| IAP metadata change |
Submitted for review independently |
| IAP price change |
Takes effect without review |
Required IAP Metadata
| Field |
Required |
Notes |
| Reference Name |
Yes |
Internal name (not visible to users) |
| Product ID |
Yes |
Unique, cannot be reused after deletion |
| Type |
Yes |
Consumable, non-consumable, auto-renewable, non-renewing |
| Price |
Yes |
Select from Apple's price tiers |
| Display Name |
Yes |
Localizable, shown to users |
| Description |
Yes |
Localizable, shown to users |
| Screenshot |
Yes |
One screenshot showing the IAP in context |
| Review Notes |
No |
Explain what the IAP unlocks |
IAP Status Flow
Missing Metadata → Ready to Submit → Waiting for Review → In Review → Approved
→ Rejected
IAP must be in "Ready to Submit" status before it can be included in an app submission.
Subscription Rules (Guideline 3.1.2)
| Rule |
Details |
| Ongoing value |
Subscriptions must provide continuing value over time |
| Minimum duration |
7 days minimum subscription period |
| Cross-device |
Must work across all user's devices where app is available |
| Transparent terms |
Clearly state price, duration, auto-renewal, and cancellation |
| No removing features |
Cannot remove previously paid functionality to force subscription |
| Grace period |
Support billing grace period (user retains access during retry) |
| Upgrade/downgrade |
Must support plan changes within subscription group |
Loot Boxes (Guideline 3.1.1)
Apps offering loot boxes or random item mechanics must disclose the odds of receiving each type of item before purchase.
External Payment Eligibility
| Category |
Guideline |
What's Allowed |
| Reader apps |
3.1.3(a) |
Link to website for previously purchased content (magazines, newspapers, books, audio, music, video) |
| Multiplatform services |
3.1.3(b) |
Cross-platform subscriptions (e.g., Netflix, Spotify) |
| Enterprise services |
3.1.3(c) |
B2B apps for organizations, not individual consumers |
| Person-to-person |
3.1.3(d) |
Real-time one-to-one services (tutoring, consulting, ride-sharing) |
| Physical goods/services |
3.1.3(e) |
Goods consumed outside the app (food delivery, clothing, physical subscriptions) |
Apps in these categories may accept payment outside the IAP system.
Subscription Group Architecture
| Concept |
Details |
| Subscription Group |
Collection of related subscription tiers (e.g., Basic, Pro, Premium) |
| Service Level |
Rank within a group; determines upgrade/downgrade behavior |
| Upgrade |
Moving to higher service level (immediate, prorated) |
| Downgrade |
Moving to lower service level (effective at next renewal) |
| Crossgrade |
Same service level, different duration (monthly ↔ annual) |
| Family Sharing |
Can be enabled per subscription group |
Subscription Pricing
| Feature |
Details |
| Price tiers |
Apple provides 900+ price points across 175+ storefronts |
| Price equalization |
Apple auto-equalizes prices across currencies |
| Custom pricing |
Set custom prices per storefront |
| Introductory offers |
Free trial, pay-as-you-go, pay-up-front |
| Promotional offers |
For existing/lapsed subscribers; requires server-signed JWS |
| Win-back offers |
For lapsed subscribers; displayed by system automatically |
| Offer codes |
Distributable codes for free/discounted access |
Subscription Restore Purchases
All subscription apps must implement Restore Purchases functionality. This is tested during App Review. Implement via:
try await AppStore.sync()
If Restore Purchases is missing or non-functional, the app will be rejected.
Free Trial Best Practices
| Practice |
Details |
| Duration display |
Clearly show trial length before user commits |
| Post-trial pricing |
Show what price will be charged after trial ends |
| Cancellation |
Explain how to cancel before trial ends |
| No dark patterns |
Don't make cancellation difficult or hard to find |
| Reminder |
Consider sending a push notification before trial ends |
Part 8: EU-Specific Compliance
Digital Services Act (DSA) Trader Status
Applies to: ALL apps distributed in the EU (27 member states)
Timeline: Since February 17, 2025, apps without declared trader status are subject to removal from the EU App Store.
What is Trader Status?
A self-assessment: are you acting as a "trader" (selling goods/services to EU consumers) or a non-trader (hobby, open-source, non-commercial)? Apple cannot determine this for you.
Trader Requirements
If you declare as a trader, you must provide:
| Field |
Required |
Verification |
| Legal name |
Yes |
— |
| Address |
Yes |
— |
| Phone number |
Yes |
Verified via 2FA |
| Email address |
Yes |
Verified via 2FA |
| Company registration |
Where applicable |
— |
| VAT ID |
Where applicable |
— |
This contact information is displayed on your EU product page.
Declaring in App Store Connect
App Store Connect > Users and Access > Developer Profile > Trader Status
Select your trader status for each app. If you have both paid and free apps, each app may have a different trader classification.
EU Alternative Distribution
Under the Digital Markets Act (DMA), Apple allows alternative app distribution in the EU:
- Alternative app marketplaces
- Web distribution (notarized apps)
- Alternative payment processing
These require separate business terms (Alternative Terms Addendum) and additional compliance steps. See Apple's EU developer documentation for details.
EU 27 Member States
Apps distributed in any of these territories require DSA compliance:
Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden.
If your app is available in "All Territories" (the default), it is available in the EU and DSA compliance is required.
Part 9: Build Upload and Processing
Upload Methods
| Method |
Best For |
| Xcode (recommended) |
Most developers; integrated with Archive workflow |
| Xcode Cloud |
CI/CD with automatic builds and distribution |
| Transporter |
Standalone macOS app for batch uploads |
| altool (CLI) |
Scripted CI/CD pipelines |
| App Store Connect API |
Fully automated workflows |
Build Identifiers
| Identifier |
Purpose |
Example |
Rules |
| Bundle ID |
Uniquely identifies your app |
com.company.app |
Set once, cannot change |
| Version Number |
User-facing version |
2.1.0 |
Must increment for each release |
| Build String |
Distinguishes builds of same version |
2.1.0.42 |
Must be unique per version per platform |
Build Selection
- Only one build can be selected per version
- Build selection can be changed until the version is submitted for review
- "Missing Compliance" status blocks build selection until export compliance questions are answered
SDK Requirements
| Effective Date |
Requirement |
| April 2025 (current) |
Xcode 16, iOS 18 SDK |
| April 28, 2026 (upcoming) |
Xcode 26, iOS 26 SDK |
Apps built with outdated SDKs will be rejected after the effective date for new submissions. Existing apps on the store are not affected until they submit an update.
Build Processing
After upload, Apple processes your build:
- Upload — Binary transferred to Apple (5-30 minutes depending on size)
- Processing — Apple validates binary, runs automated checks (15-60 minutes)
- Available — Build appears in App Store Connect, ready for TestFlight or submission
- Email notification — Sent when processing completes or fails
Common processing failures:
- Missing required architectures (arm64 required)
- Invalid provisioning profile or signing identity
- Missing privacy manifest for third-party SDKs on Apple's list
- Info.plist missing required keys
- Binary too large (OTA download limit: 200 MB over cellular)
IPv6 Compatibility
All apps must work on IPv6-only networks. Apple's review environment uses IPv6. Common issues:
- Hard-coded IPv4 addresses
- Using low-level socket APIs instead of high-level networking
- Third-party SDKs with IPv4-only code
Use URLSession or Network.framework to ensure IPv6 compatibility automatically.
App Thinning and Bitcode
| Topic |
Status |
| Bitcode |
Deprecated since Xcode 14; no longer accepted |
| App Thinning |
Active; Apple generates device-specific variants |
| On-Demand Resources |
Active; tag resources for download on demand |
| Asset catalogs |
Used for app thinning of images (1x/2x/3x) |
Entitlements and Capabilities
Certain features require entitlements configured in Xcode and provisioning profiles:
| Capability |
Entitlement |
Common Issues |
| Push Notifications |
aps-environment |
Certificate expiry, missing provisioning |
| App Groups |
com.apple.security.application-groups |
Shared container ID mismatch |
| Associated Domains |
com.apple.developer.associated-domains |
AASA file not served correctly |
| HealthKit |
com.apple.developer.healthkit |
Missing required capabilities |
| Background Modes |
UIBackgroundModes |
Using modes without justification |
| Sign in with Apple |
com.apple.developer.applesignin |
Missing from provisioning profile |
| CloudKit |
com.apple.developer.icloud-services |
Container ID mismatch |
| In-App Purchase |
— |
Enabled by default; StoreKit config needed for testing |
TestFlight Submission
| Aspect |
Internal Testing |
External Testing |
| Testers |
Up to 100 ASC users |
Up to 10,000 via email/public link |
| Review required |
No |
Yes (first build per version, full App Review) |
| Review time |
— |
Usually under 24 hours |
| Build expiry |
90 days from upload |
90 days from upload |
| Groups |
Automatic (ASC roles) |
Custom groups with "What to Test" notes |
| Feedback |
Crash reports |
Screenshots, text feedback, crash reports |
| Submission limit |
— |
Max 6 builds per 24-hour period |
TestFlight readiness checklist:
Gotchas:
- Builds uploaded as "TestFlight Internal Only" from Xcode/Xcode Cloud can only go to internal groups
- Managed Apple Accounts (School/Business Manager) cannot be testers
- Public link tester cap is configurable (1-10,000) per link
- Builds remain testable even after the app goes live on the App Store
- Developer can manually expire builds before 90 days
Part 10: WWDC25 Changes
Draft Submissions (WWDC 2025-328)
Group multiple items into a single draft submission:
- App version + new IAPs + product page changes
- Review everything together instead of separate submissions
- Draft state: prepare items over time, submit when ready
Reusable Build Numbers on Failure
When a build is rejected due to metadata issues (not binary issues), you can reuse
…(truncated)
1---2name: axiom-app-store-ref3description: Use when looking up ANY App Store metadata field requirement, privacy manifest schema, age rating tier, export compliance decision, EU DSA trader status, IAP review pipeline, or WWDC25 submission change. Covers character limits, screenshot specs, encryption decision tree, account deletion rules.4---56# App Store Submission Reference78## Overview910Complete reference for every App Store submission requirement:1112- **Part 1** — Required metadata fields (descriptions, screenshots, keywords, App Review info)13- **Part 2** — Privacy requirements (manifest schema, nutrition labels, ATT, Required Reason APIs)14- **Part 3** — App Review Guidelines quick reference (all sections 1-5)15- **Part 4** — Age rating system (5-tier, capabilities, regional variations)16- **Part 5** — Export compliance (encryption decision tree)17- **Part 6** — Account and authentication requirements (deletion, SIWA)18- **Part 7** — Monetization and IAP submission pipeline19- **Part 8** — EU-specific compliance (DSA trader status)20- **Part 9** — Build upload and processing21- **Part 10** — WWDC25 changes (draft submissions, accessibility labels, tags)2223## When to Use This Skill2425#### Use when26- Looking up specific metadata field requirements or character limits27- Checking App Review guideline numbers for a specific topic28- Verifying privacy manifest schema fields or Required Reason API categories29- Understanding age rating tiers and new capability declarations30- Checking EU compliance requirements for DSA trader status31- Understanding IAP submission pipeline and review flow32- Preparing builds for upload (SDK requirements, encryption, signing)3334#### Do NOT use when35- Deciding if your app is ready to submit (use **app-store-submission**)36- Troubleshooting a rejection (use **app-store-diag**)37- Implementing in-app purchases (use **storekit-ref**)38- Writing privacy manifest code (use **privacy-ux**)39- Auditing accessibility compliance (use **accessibility-diag**)4041## Related Skills4243- **app-store-submission** — Discipline skill with pre-flight checklist and workflow44- **app-store-diag** — Rejection troubleshooting and appeal guidance45- **privacy-ux** — Privacy manifest implementation, ATT UX, permission requests46- **storekit-ref** — StoreKit 2 API reference for IAP implementation47- **accessibility-diag** — Accessibility compliance scanning and VoiceOver testing4849## Key Terminology5051| Term | Definition |52|------|-----------|53| **App Store Connect** | Web portal and API for managing app metadata, builds, pricing, TestFlight, and analytics |54| **App Review** | Apple's human review process that evaluates every app update against the App Review Guidelines |55| **Privacy Manifest** | `PrivacyInfo.xcprivacy` file declaring data collection, tracking domains, and Required Reason API usage |56| **Required Reason API** | System APIs (file timestamps, disk space, user defaults, etc.) that require declared usage reasons |57| **Privacy Nutrition Label** | App Store privacy cards showing what data your app collects and how it uses it |58| **DSA Trader Status** | EU Digital Services Act classification determining if you are a "trader" selling to EU consumers |59| **Build String** | Unique identifier for each uploaded build (e.g., "1.2.3.4"), separate from version number |60| **Bundle ID** | Reverse-domain identifier (e.g., "com.company.app") uniquely identifying your app across Apple's ecosystem |6162---6364## Part 1: Required Metadata Fields6566### Immutable Fields (Cannot Change After Creation)6768These fields are locked once set. Choose carefully:69- **Bundle ID** — must match Xcode project exactly70- **SKU** — internal identifier, never shown to users71- **IAP Product ID** — cannot be changed or reused after creation72- **Subscription Duration** — locked after subscription is created7374### App Information7576| Field | Required | Localizable | Max Length | Notes |77|-------|----------|-------------|------------|-------|78| App Name | Yes | Yes | 30 chars | Must be unique on the App Store |79| Subtitle | No | Yes | 30 chars | Appears below app name in search results |80| Description | Yes | Yes | 4000 chars | Plain text, no HTML or rich formatting |81| Promotional Text | No | Yes | 170 chars | Editable without new submission |82| Keywords | Yes | Yes | 100 bytes | Comma-separated, each keyword >2 chars |83| What's New | Yes* | Yes | 4000 chars | *Required for all versions except first |84| Copyright | Yes | No | — | Format: "YYYY Company Name" |85| Support URL | Yes | Yes | — | Must link to actual contact information |86| Marketing URL | No | Yes | — | Optional promotional page |87| Privacy Policy URL | Yes | Yes | — | HTTPS, publicly accessible |8889### Visual Assets9091| Asset | Required | Localizable | Specification |92|-------|----------|-------------|---------------|93| App Icon | Yes | No | 1024x1024 PNG, no alpha, no rounded corners |94| Screenshots | Yes | Yes | Per device size, 2-10 per locale per device |95| App Preview | No | Yes | Up to 3 videos per device size per locale |9697#### Screenshot Requirements9899Format: `.jpeg`, `.jpg`, `.png`. Min 1, max 10 per device size per locale.100101**Fallback**: Provide highest resolution only — App Store auto-scales to smaller sizes. Required: 6.9" or 6.5" for iPhone, 13" for iPad.102103| Device | Portrait | Landscape |104|--------|----------|-----------|105| iPhone 6.9" (Air, 17 Pro Max, 16 Pro Max) | 1260x2736 | 2736x1260 |106| iPhone 6.5" (14 Plus, 13 Pro Max, XS Max) | 1284x2778 or 1242x2688 | 2778x1284 or 2688x1242 |107| iPhone 6.3" (17 Pro, 16 Pro, 16, 15 Pro) | 1179x2556 or 1206x2622 | 2556x1179 or 2622x1206 |108| iPhone 6.1" (17e, 16e, 14, 13, 12) | 1170x2532, 1125x2436, or 1080x2340 | 2532x1170, 2436x1125, or 2340x1080 |109| iPhone 5.5" (8 Plus, 7 Plus) | 1242x2208 | 2208x1242 |110| iPad 13" (Pro M5/M4, Air M4/M3) | 2064x2752 or 2048x2732 | 2752x2064 or 2732x2048 |111| iPad 11" (Pro, Air, mini, 10th gen) | 1488x2266 or 1668x2420 | 2266x1488 or 2420x1668 |112| Mac | 1280x800, 1440x900, 2560x1600, or 2880x1800 | — |113| Apple TV | 1920x1080 or 3840x2160 | — |114| Apple Vision Pro | 3840x2160 | — |115116Screenshots must show the app in actual use. Not permitted: title art alone, login screens, splash screens, or screens from other platforms. Cannot update screenshots on an approved version — must create a new version.117118#### App Preview Video Specifications119120| Spec | Value |121|------|-------|122| Duration | 15-30 seconds |123| Max file size | 500 MB |124| Max frame rate | 30 fps |125| Max per device/locale | 3 |126| H.264 | 10-12 Mbps, `.mov`/`.m4v`/`.mp4`, 256 kbps AAC stereo |127| ProRes 422 HQ | ~220 Mbps VBR, `.mov` only, PCM or 256 kbps AAC stereo |128| Audio sample rate | 44.1 or 48 kHz |129| Orientation | Portrait or landscape (Mac/tvOS/visionOS: landscape only) |130131**Gotchas**: Processing can take up to 24 hours — do not submit for review immediately after uploading previews. All audio tracks must be enabled (disabled tracks cause rejection). Previews always appear before screenshots on the product page.132133#### App Icon Requirements134135| Specification | Requirement |136|---------------|-------------|137| Size | 1024 x 1024 pixels |138| Format | PNG |139| Color space | sRGB or P3 |140| Alpha channel | Not allowed |141| Rounded corners | Not allowed (system applies automatically) |142| Layers/transparency | Not allowed |143| Content | Must be appropriate for 4+ rating regardless of app's actual rating |144145### App Review Information146147| Field | Required | Notes |148|-------|----------|-------|149| Contact First Name | Yes | Reviewer contact |150| Contact Last Name | Yes | Reviewer contact |151| Contact Email | Yes | Must be monitored |152| Contact Phone | Yes | Include country code |153| Notes for Review | No | Up to 4000 bytes; explain non-obvious features |154| Sign-in Username | If login required | Must not expire during review |155| Sign-in Password | If login required | Must not expire during review |156| Attachment | No | Up to 10 files, max 512 MB total |157158### Metadata Rules (Guideline 2.3)159160- App names must be unique, max 30 characters161- Keywords must not include trademarked terms, popular app names, or pricing terms ("free", "sale")162- Screenshots must show the app in use, not just marketing art163- Icons, screenshots, and previews must be appropriate for a 4+ rating even if the app is rated higher164- "For Kids" and "For Children" are reserved for the Kids category165- No other mobile platform names or imagery in screenshots (no Android phones, Windows logos)166- Metadata must accurately reflect app functionality; misleading metadata is grounds for rejection167168### Localization Requirements169170| Aspect | Details |171|--------|---------|172| Minimum | Primary language required; all other localizations optional |173| Per-locale metadata | App name, subtitle, description, keywords, What's New, screenshots |174| Promotional Text | Localizable and editable without new submission |175| Screenshots | Can differ per locale (show localized UI) |176| App Previews | Can differ per locale (show localized audio/UI) |177| URL fields | Support URL and Marketing URL can differ per locale |178179When localizing, provide screenshots that match the localized UI. Reviewers check that screenshots accurately represent the app in each locale.180181### Category Selection182183| Primary Category | Secondary Category | Rules |184|-----------------|-------------------|-------|185| Required | Optional | Choose the category that best describes your app |186| Must be accurate | Can complement primary | Inaccurate category is grounds for rejection (2.3.7) |187| Games have subcategories | — | Games must also select up to 2 game subcategories |188189Available categories: Books, Business, Developer Tools, Education, Entertainment, Finance, Food & Drink, Games, Graphics & Design, Health & Fitness, Lifestyle, Magazines & Newspapers, Medical, Music, Navigation, News, Photo & Video, Productivity, Reference, Shopping, Social Networking, Sports, Travel, Utilities, Weather.190191---192193## Part 2: Privacy Requirements194195### Privacy Policy (Guideline 5.1.1(i))196197Required in BOTH locations:1981. **App Store Connect** metadata (Privacy Policy URL field)1992. **Within the app** itself (accessible from settings or equivalent)200201The privacy policy must identify:202- What data is collected and by what means203- All uses of collected data204- Third-party sharing practices205- Data retention and deletion policies206- How users can revoke consent207208### Privacy Manifest Schema (PrivacyInfo.xcprivacy)209210```xml211<!-- Top-level keys -->212NSPrivacyTracking <!-- Boolean: Does app track users? -->213NSPrivacyTrackingDomains <!-- Array<String>: Domains used for tracking -->214NSPrivacyCollectedDataTypes <!-- Array<Dictionary>: Data collected -->215NSPrivacyAccessedAPITypes <!-- Array<Dictionary>: Required Reason APIs -->216```217218#### NSPrivacyCollectedDataTypes Entry219220Each dictionary in the array contains:221222| Key | Type | Description |223|-----|------|-------------|224| `NSPrivacyCollectedDataType` | String | Category key (e.g., "NSPrivacyCollectedDataTypeName") |225| `NSPrivacyCollectedDataTypePurposes` | Array<String> | Purpose keys for this data type |226| `NSPrivacyCollectedDataTypeLinked` | Boolean | Is this data linked to user identity? |227| `NSPrivacyCollectedDataTypeTracking` | Boolean | Is this data used for tracking? |228229#### NSPrivacyAccessedAPITypes Entry230231Each dictionary in the array contains:232233| Key | Type | Description |234|-----|------|-------------|235| `NSPrivacyAccessedAPIType` | String | API category identifier |236| `NSPrivacyAccessedAPITypeReasons` | Array<String> | Approved reason codes for usage |237238#### Complete PrivacyInfo.xcprivacy Example239240```xml241<?xml version="1.0" encoding="UTF-8"?>242<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"243 "http://www.apple.com/DTDs/PropertyList-1.0.dtd">244<plist version="1.0">245<dict>246 <key>NSPrivacyTracking</key>247 <false/>248 <key>NSPrivacyTrackingDomains</key>249 <array/>250 <key>NSPrivacyCollectedDataTypes</key>251 <array>252 <dict>253 <key>NSPrivacyCollectedDataType</key>254 <string>NSPrivacyCollectedDataTypeEmailAddress</string>255 <key>NSPrivacyCollectedDataTypeLinked</key>256 <true/>257 <key>NSPrivacyCollectedDataTypeTracking</key>258 <false/>259 <key>NSPrivacyCollectedDataTypePurposes</key>260 <array>261 <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>262 </array>263 </dict>264 </array>265 <key>NSPrivacyAccessedAPITypes</key>266 <array>267 <dict>268 <key>NSPrivacyAccessedAPIType</key>269 <string>NSPrivacyAccessedAPICategoryUserDefaults</string>270 <key>NSPrivacyAccessedAPITypeReasons</key>271 <array>272 <string>CA92.1</string>273 </array>274 </dict>275 </array>276</dict>277</plist>278```279280#### API Category Identifiers281282| Category | Identifier String |283|----------|------------------|284| File timestamp | `NSPrivacyAccessedAPICategoryFileTimestamp` |285| System boot time | `NSPrivacyAccessedAPICategorySystemBootTime` |286| Disk space | `NSPrivacyAccessedAPICategoryDiskSpace` |287| Active keyboard | `NSPrivacyAccessedAPICategoryActiveKeyboards` |288| User defaults | `NSPrivacyAccessedAPICategoryUserDefaults` |289290#### Generating Aggregate Privacy Report291292```293Xcode > Product > Archive > Generate Privacy Report294```295296This produces a PDF summarizing privacy manifests from your app and all embedded frameworks.297298**Privacy manifest gotchas**:299- Custom string values for `NSPrivacyCollectedDataType` or `NSPrivacyCollectedDataTypePurposes` are silently rejected by Xcode — must use Apple's predefined constants300- iOS 17 automatically blocks connections to declared tracking domains when user denies tracking301- IP address collection must be declared (as location, device ID, or diagnostics)302- Web view data collection must be declared303- You are responsible for ALL data collected by third-party SDKs in your app304- Some SDKs default to tracking unless explicitly disabled — creates unintentional tracking305- Fingerprinting is NEVER allowed, regardless of ATT permission306- Since May 1, 2024: missing required-reason API declarations cause automatic rejection (no human review)307308### Required Reason API Categories309310| Category | APIs Covered | Common Reasons |311|----------|-------------|----------------|312| File timestamp | `NSFileCreationDate`, `NSFileModificationDate`, `NSURLContentModificationDateKey` | DDA9.1 (display to user), C617.1 (inside app container) |313| System boot time | `systemUptime`, `mach_absolute_time` | 35F9.1 (measure elapsed time) |314| Disk space | `NSFileSystemFreeSize`, `NSFileSystemSize`, `volumeAvailableCapacityKey` | E174.1 (check before writing), 85F4.1 (display to user) |315| Active keyboard | `activeInputModes` | 54BD.1 (customize UI for keyboard) |316| User defaults | `UserDefaults` (all access requires declaration) | CA92.1 (access within app group), 1C8F.1 (access within same app) |317318### App Privacy Details (Nutrition Labels)319320#### Data Type Categories321322| Category | Examples |323|----------|---------|324| Contact Info | Name, email address, phone number, physical address |325| Health & Fitness | Health data, fitness data |326| Financial Info | Payment info, credit info |327| Location | Precise location, coarse location |328| Sensitive Info | Racial or ethnic data, sexual orientation, religion, biometrics |329| Contacts | Address book contacts |330| User Content | Photos, videos, audio, gameplay content, customer support messages |331| Browsing History | Web browsing history |332| Search History | In-app search history |333| Identifiers | User ID, device ID |334| Purchases | Purchase history |335| Usage Data | Product interaction, advertising data, app launches, taps, scrolls |336| Diagnostics | Crash data, performance data |337| Surroundings | Environment scanning (e.g., AR data) |338| Body | Hands, head (e.g., hand tracking in visionOS) |339340#### Purpose Categories341342| Purpose | Description |343|---------|-------------|344| Third-Party Advertising | Displaying third-party ads or sharing with ad networks |345| Developer's Advertising/Marketing | Your own marketing campaigns |346| Analytics | Understanding user behavior and measuring effectiveness |347| Product Personalization | Customizing features, content recommendations |348| App Functionality | Required for app to work (e.g., authentication, data sync) |349| Other | Any purpose not listed above |350351### Tracking and Collection Definitions352353**"Collected"** means data is transmitted off-device and accessible beyond what is needed to service the current request. On-device-only processing is NOT collection.354355**"Tracking"** means:356- Linking user/device data from your app with third-party data for advertising or measurement, OR357- Sharing user/device data with a data broker358359### App Tracking Transparency (ATT)360361Required if your app "tracks" per Apple's definition above.362363- Add `NSUserTrackingUsageDescription` to Info.plist (explains why tracking is needed)364- Call `ATTrackingManager.requestTrackingAuthorization()` before tracking365- Respect the result:366 - `.authorized` — User granted permission to track367 - `.denied` — User denied tracking; do not track368 - `.notDetermined` — User has not yet been asked369 - `.restricted` — Device-level restriction prevents tracking370371Request at a contextually appropriate moment, not at first launch.372373### Common Purpose Strings (NS*UsageDescription)374375These Info.plist keys must be present for each system permission your app requests:376377| Permission | Info.plist Key |378|------------|---------------|379| Camera | `NSCameraUsageDescription` |380| Microphone | `NSMicrophoneUsageDescription` |381| Photo Library (read) | `NSPhotoLibraryUsageDescription` |382| Photo Library (write) | `NSPhotoLibraryAddUsageDescription` |383| Location (when in use) | `NSLocationWhenInUseUsageDescription` |384| Location (always) | `NSLocationAlwaysAndWhenInUseUsageDescription` |385| Contacts | `NSContactsUsageDescription` |386| Calendars (full access) | `NSCalendarsFullAccessUsageDescription` |387| Reminders (full access) | `NSRemindersFullAccessUsageDescription` |388| Health | `NSHealthShareUsageDescription`, `NSHealthUpdateUsageDescription` |389| Motion | `NSMotionUsageDescription` |390| Bluetooth | `NSBluetoothAlwaysUsageDescription` |391| Face ID | `NSFaceIDUsageDescription` |392| Local Network | `NSLocalNetworkUsageDescription` |393| Tracking | `NSUserTrackingUsageDescription` |394| Speech Recognition | `NSSpeechRecognitionUsageDescription` |395| Apple Music | `NSAppleMusicUsageDescription` |396397Missing purpose strings cause immediate rejection. Purpose string text must clearly explain why the permission is needed in the context of your app's functionality.398399### Third-Party SDK Privacy Manifests400401Apple maintains a list of commonly used SDKs that require privacy manifests. Starting spring 2024, if your app includes these SDKs without privacy manifests, it will be flagged during submission.402403Third-party SDKs should include their own `PrivacyInfo.xcprivacy` in their framework bundle. The aggregate privacy report combines all manifests from your app and embedded frameworks.404405If a third-party SDK does not include a privacy manifest, you must declare its data collection in your app's privacy manifest.406407---408409## Part 3: App Review Guidelines Quick Reference410411For the complete guideline index (Sections 1-5), see `references/app-review-guidelines.md`.412413### Most Common Rejection Reasons414415See `references/app-review-guidelines.md` for the full top-10 rejection causes table with percentages.416417### App Review Timeline418419| Stage | Typical Duration |420|-------|-----------------|421| Waiting for Review | Minutes to hours |422| In Review | Minutes to 24 hours |423| Total (90th percentile) | Under 24 hours |424| Total (edge cases) | Up to 7 days |425| Expedited Review | Same day to 24 hours (if approved) |426427Review times increase during holidays and major iOS release periods. Plan submissions accordingly.428429---430431## Part 4: Age Rating System432433### Five-Tier Rating System (Updated January 31, 2026)434435| Rating | Triggers |436|--------|----------|437| **4+** | No objectionable material |438| **9+** | Infrequent or mild: profanity, cartoon/fantasy violence, horror/fear themes. Loot boxes present |439| **13+** | Frequent or intense: profanity or crude humor. Infrequent: alcohol/tobacco/drugs references, sexual content/nudity, realistic violence |440| **16+** | Unrestricted web access, frequent medical/treatment info, mature/suggestive themes |441| **18+** | Frequent or intense: alcohol/tobacco/drugs use, sexual content/nudity, realistic violence. Simulated gambling with real-money elements |442| **Unrated** | App cannot be published without completing the questionnaire |443444### Capability Declarations (New, WWDC25)445446Apps must declare if they include these capabilities:447448| Capability | When to Declare |449|------------|----------------|450| Messaging/chat | Any in-app messaging between users |451| User-generated content | Users can post, share, or upload content visible to others |452| Advertising | App displays ads from any ad network |453| Parental controls | App has parental restrictions or family features |454| Age assurance | App verifies user age for restricted content |455456These declarations appear alongside the age rating on the App Store product page, giving parents and users additional transparency.457458### Regional Variations459460Age ratings map differently across regions:461462| Apple Rating | Australia | Brazil | Korea | Germany (USK) |463|-------------|-----------|--------|-------|----------------|464| 4+ | 4+ | L (All ages) | All | 0 |465| 9+ | 9+ | A10 | 12+ | 6 |466| 13+ | 13+ | A12 | 15+ | 12 |467| 16+ | 15+ | A16 | 19+ | 16 |468| 18+ | R 18+ | A18 | 19+ | 18 |469470The age rating questionnaire automatically generates the appropriate regional ratings based on your answers.471472### Age Rating Best Practices473474- Answer the questionnaire conservatively; under-rating leads to rejection475- If your app accesses unrestricted web content (WebView without content filter), it will be rated 16+ minimum476- UGC apps typically need 13+ minimum due to moderation requirements477- Simulated gambling (even without real money) requires at least 9+478- Realistic violence in gameplay requires at least 13+479480### Age Rating Questionnaire Topics481482The questionnaire covers these content categories:483484| Category | Options |485|----------|---------|486| Cartoon or Fantasy Violence | None, Infrequent/Mild, Frequent/Intense |487| Realistic Violence | None, Infrequent/Mild, Frequent/Intense |488| Profanity or Crude Humor | None, Infrequent/Mild, Frequent/Intense |489| Mature/Suggestive Themes | None, Infrequent/Mild, Frequent/Intense |490| Alcohol, Tobacco, or Drug Use or References | None, Infrequent/Mild, Frequent/Intense |491| Sexual Content and Nudity | None, Infrequent/Mild, Frequent/Intense |492| Horror/Fear Themes | None, Infrequent/Mild, Frequent/Intense |493| Simulated Gambling | None, Infrequent/Mild, Frequent/Intense |494| Medical/Treatment Information | None, Infrequent/Mild, Frequent/Intense |495| Unrestricted Web Access | Yes/No |496497The system automatically calculates your app's age rating across all regions based on your answers.498499---500501## Part 5: Export Compliance502503### Three-Tier Encryption System504505| Tier | Encryption Type | Documentation Required |506|------|----------------|----------------------|507| **Exempt** | Apple OS built-in (HTTPS via URLSession, AES data protection, CryptoKit, Keychain, Secure Enclave) | None — set `ITSAppUsesNonExemptEncryption = NO` |508| **Standard** | Industry-standard algorithms (IEEE, IETF, ISO, ITU, ETSI, 3GPP approved) | French ANSSI declaration only (if distributing in France) |509| **Proprietary** | Custom/unpublished algorithms not adopted by standards bodies | US CCATS + French declaration (if France) |510511### Encryption Decision Tree512513```514Does your app use encryption?515├── No → ITSAppUsesNonExemptEncryption = NO → Done516├── Only Apple OS encryption (HTTPS, Keychain, CryptoKit)?517│ ├── Yes → ITSAppUsesNonExemptEncryption = NO → Done518│ │ (May need annual BIS self-classification report)519│ └── No → Industry-standard algorithm (AES, RSA, etc.)?520│ ├── Yes → ITSAppUsesNonExemptEncryption = YES521│ │ French declaration if distributing in France522│ │ Upload docs → receive ITSEncryptionExportComplianceCode523│ └── No (custom/proprietary) →524│ ITSAppUsesNonExemptEncryption = YES525│ US CCATS required (~2 business days)526│ French declaration if France527│ Upload docs → receive ITSEncryptionExportComplianceCode528```529530### Info.plist Keys531532```xml533<!-- Most apps: only Apple OS encryption -->534<key>ITSAppUsesNonExemptEncryption</key>535<false/>536537<!-- Apps with non-exempt encryption (bypasses questionnaire on future submissions) -->538<key>ITSAppUsesNonExemptEncryption</key>539<true/>540<key>ITSEncryptionExportComplianceCode</key>541<string>YOUR_COMPLIANCE_CODE</string>542```543544Setting `ITSAppUsesNonExemptEncryption` in Info.plist skips the encryption questionnaire on every submission.545546### Exempt Encryption Uses547548No documentation needed:549- HTTPS/TLS (URLSession, Network.framework, WKWebView)550- Secure Enclave, Keychain, biometric auth551- CryptoKit, Security.framework per Apple docs552- Password hashing (bcrypt, scrypt, PBKDF2)553554### Non-Exempt Encryption Uses555556Documentation required:557- Custom encryption algorithms558- OpenSSL, libsodium for non-standard purposes559- End-to-end encrypted messaging560- VPN implementations561- Custom DRM systems562563### France-Specific564565Import/export controlled by ANSSI. Banking and medical apps are exempt. Applies to: secure storage, secure communications, security/antivirus apps.566567---568569## Part 6: Account and Authentication570571### Account Deletion (Required Since June 2022)572573Apps that support account creation must offer account deletion. Requirements:574575| Requirement | Details |576|-------------|---------|577| Full deletion | Must fully delete the account, not just deactivate |578| Easy to find | Must be accessible from app settings; not buried behind support tickets |579| Inform timeline | Tell user how long deletion takes |580| Confirm completion | Notify user when deletion is complete |581| Delete shared UGC | Must handle user-generated content shared with others |582| Revoke SIWA tokens | Call Apple's revoke token endpoint for Sign in with Apple accounts |583| Handle subscriptions | Warn about active subscriptions; direct to subscription management |584585#### Sign in with Apple Token Revocation586587```swift588// Server-side: revoke SIWA tokens when account deleted589// POST https://appleid.apple.com/auth/revoke590// Parameters: client_id, client_secret, token, token_type_hint591```592593Failing to revoke SIWA tokens during account deletion is a common rejection reason.594595### Sign in with Apple (Guideline 4.8)596597**Required when:** Your app offers ANY third-party or social login option (Google, Facebook, Twitter, email/password via third-party provider).598599#### Exceptions — SIWA not required when600- App is for company employees only (internal enterprise app)601- App is for education or enterprise with existing institutional auth602- App uses government or industry-backed citizen ID systems603- App is a client for a specific third-party service (e.g., Gmail app, Slack)604605When SIWA is required, it must be offered as an equally prominent option alongside other sign-in methods. It cannot be hidden or given less visual weight.606607### Account Deletion Implementation Checklist608609| Step | Details |610|------|---------|611| 1. Add UI entry point | Settings screen, clearly labeled "Delete Account" |612| 2. Explain consequences | Show what will be deleted (data, subscriptions, purchases) |613| 3. Require confirmation | User must explicitly confirm deletion |614| 4. Handle active subscriptions | Direct user to cancel active subscriptions before deletion |615| 5. Process deletion | Delete all user data from your servers |616| 6. Revoke SIWA tokens | Call Apple's revoke endpoint if SIWA was used |617| 7. Confirm to user | Send email or in-app confirmation when deletion is complete |618| 8. Define timeline | State how long deletion takes (immediately, 30 days, etc.) |619620Apple specifically rejects apps that:621- Require users to call a phone number to delete their account622- Require users to send an email to request deletion623- Only offer account deactivation (hiding profile) instead of full deletion624- Don't handle SIWA token revocation625626---627628## Part 7: Monetization and IAP629630### IAP Submission Pipeline631632In-app purchases have a separate review process from app submissions:633634| Scenario | Behavior |635|----------|----------|636| First IAP ever | Must be bundled with a new app version submission |637| Subsequent IAPs | Can be submitted independently of app updates |638| IAP metadata change | Submitted for review independently |639| IAP price change | Takes effect without review |640641#### Required IAP Metadata642643| Field | Required | Notes |644|-------|----------|-------|645| Reference Name | Yes | Internal name (not visible to users) |646| Product ID | Yes | Unique, cannot be reused after deletion |647| Type | Yes | Consumable, non-consumable, auto-renewable, non-renewing |648| Price | Yes | Select from Apple's price tiers |649| Display Name | Yes | Localizable, shown to users |650| Description | Yes | Localizable, shown to users |651| Screenshot | Yes | One screenshot showing the IAP in context |652| Review Notes | No | Explain what the IAP unlocks |653654#### IAP Status Flow655656```657Missing Metadata → Ready to Submit → Waiting for Review → In Review → Approved658 → Rejected659```660661IAP must be in "Ready to Submit" status before it can be included in an app submission.662663### Subscription Rules (Guideline 3.1.2)664665| Rule | Details |666|------|---------|667| Ongoing value | Subscriptions must provide continuing value over time |668| Minimum duration | 7 days minimum subscription period |669| Cross-device | Must work across all user's devices where app is available |670| Transparent terms | Clearly state price, duration, auto-renewal, and cancellation |671| No removing features | Cannot remove previously paid functionality to force subscription |672| Grace period | Support billing grace period (user retains access during retry) |673| Upgrade/downgrade | Must support plan changes within subscription group |674675### Loot Boxes (Guideline 3.1.1)676677Apps offering loot boxes or random item mechanics must disclose the odds of receiving each type of item before purchase.678679### External Payment Eligibility680681| Category | Guideline | What's Allowed |682|----------|-----------|----------------|683| Reader apps | 3.1.3(a) | Link to website for previously purchased content (magazines, newspapers, books, audio, music, video) |684| Multiplatform services | 3.1.3(b) | Cross-platform subscriptions (e.g., Netflix, Spotify) |685| Enterprise services | 3.1.3(c) | B2B apps for organizations, not individual consumers |686| Person-to-person | 3.1.3(d) | Real-time one-to-one services (tutoring, consulting, ride-sharing) |687| Physical goods/services | 3.1.3(e) | Goods consumed outside the app (food delivery, clothing, physical subscriptions) |688689Apps in these categories may accept payment outside the IAP system.690691### Subscription Group Architecture692693| Concept | Details |694|---------|---------|695| Subscription Group | Collection of related subscription tiers (e.g., Basic, Pro, Premium) |696| Service Level | Rank within a group; determines upgrade/downgrade behavior |697| Upgrade | Moving to higher service level (immediate, prorated) |698| Downgrade | Moving to lower service level (effective at next renewal) |699| Crossgrade | Same service level, different duration (monthly ↔ annual) |700| Family Sharing | Can be enabled per subscription group |701702#### Subscription Pricing703704| Feature | Details |705|---------|---------|706| Price tiers | Apple provides 900+ price points across 175+ storefronts |707| Price equalization | Apple auto-equalizes prices across currencies |708| Custom pricing | Set custom prices per storefront |709| Introductory offers | Free trial, pay-as-you-go, pay-up-front |710| Promotional offers | For existing/lapsed subscribers; requires server-signed JWS |711| Win-back offers | For lapsed subscribers; displayed by system automatically |712| Offer codes | Distributable codes for free/discounted access |713714#### Subscription Restore Purchases715716All subscription apps must implement Restore Purchases functionality. This is tested during App Review. Implement via:717718```swift719try await AppStore.sync()720```721722If Restore Purchases is missing or non-functional, the app will be rejected.723724### Free Trial Best Practices725726| Practice | Details |727|----------|---------|728| Duration display | Clearly show trial length before user commits |729| Post-trial pricing | Show what price will be charged after trial ends |730| Cancellation | Explain how to cancel before trial ends |731| No dark patterns | Don't make cancellation difficult or hard to find |732| Reminder | Consider sending a push notification before trial ends |733734---735736## Part 8: EU-Specific Compliance737738### Digital Services Act (DSA) Trader Status739740**Applies to:** ALL apps distributed in the EU (27 member states)741742**Timeline:** Since February 17, 2025, apps without declared trader status are subject to removal from the EU App Store.743744#### What is Trader Status?745746A self-assessment: are you acting as a "trader" (selling goods/services to EU consumers) or a non-trader (hobby, open-source, non-commercial)? Apple cannot determine this for you.747748#### Trader Requirements749750If you declare as a trader, you must provide:751752| Field | Required | Verification |753|-------|----------|-------------|754| Legal name | Yes | — |755| Address | Yes | — |756| Phone number | Yes | Verified via 2FA |757| Email address | Yes | Verified via 2FA |758| Company registration | Where applicable | — |759| VAT ID | Where applicable | — |760761This contact information is displayed on your EU product page.762763#### Declaring in App Store Connect764765```766App Store Connect > Users and Access > Developer Profile > Trader Status767```768769Select your trader status for each app. If you have both paid and free apps, each app may have a different trader classification.770771### EU Alternative Distribution772773Under the Digital Markets Act (DMA), Apple allows alternative app distribution in the EU:774- Alternative app marketplaces775- Web distribution (notarized apps)776- Alternative payment processing777778These require separate business terms (Alternative Terms Addendum) and additional compliance steps. See Apple's EU developer documentation for details.779780### EU 27 Member States781782Apps distributed in any of these territories require DSA compliance:783784Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden.785786If your app is available in "All Territories" (the default), it is available in the EU and DSA compliance is required.787788---789790## Part 9: Build Upload and Processing791792### Upload Methods793794| Method | Best For |795|--------|---------|796| **Xcode** (recommended) | Most developers; integrated with Archive workflow |797| **Xcode Cloud** | CI/CD with automatic builds and distribution |798| **Transporter** | Standalone macOS app for batch uploads |799| **altool** (CLI) | Scripted CI/CD pipelines |800| **App Store Connect API** | Fully automated workflows |801802### Build Identifiers803804| Identifier | Purpose | Example | Rules |805|------------|---------|---------|-------|806| Bundle ID | Uniquely identifies your app | `com.company.app` | Set once, cannot change |807| Version Number | User-facing version | `2.1.0` | Must increment for each release |808| Build String | Distinguishes builds of same version | `2.1.0.42` | Must be unique per version per platform |809810### Build Selection811812- Only one build can be selected per version813- Build selection can be changed until the version is submitted for review814- "Missing Compliance" status blocks build selection until export compliance questions are answered815816### SDK Requirements817818| Effective Date | Requirement |819|----------------|-------------|820| April 2025 (current) | Xcode 16, iOS 18 SDK |821| April 28, 2026 (upcoming) | Xcode 26, iOS 26 SDK |822823Apps built with outdated SDKs will be rejected after the effective date for new submissions. Existing apps on the store are not affected until they submit an update.824825### Build Processing826827After upload, Apple processes your build:8288291. **Upload** — Binary transferred to Apple (5-30 minutes depending on size)8302. **Processing** — Apple validates binary, runs automated checks (15-60 minutes)8313. **Available** — Build appears in App Store Connect, ready for TestFlight or submission8324. **Email notification** — Sent when processing completes or fails833834Common processing failures:835- Missing required architectures (arm64 required)836- Invalid provisioning profile or signing identity837- Missing privacy manifest for third-party SDKs on Apple's list838- Info.plist missing required keys839- Binary too large (OTA download limit: 200 MB over cellular)840841### IPv6 Compatibility842843All apps must work on IPv6-only networks. Apple's review environment uses IPv6. Common issues:844- Hard-coded IPv4 addresses845- Using low-level socket APIs instead of high-level networking846- Third-party SDKs with IPv4-only code847848Use `URLSession` or `Network.framework` to ensure IPv6 compatibility automatically.849850### App Thinning and Bitcode851852| Topic | Status |853|-------|--------|854| Bitcode | Deprecated since Xcode 14; no longer accepted |855| App Thinning | Active; Apple generates device-specific variants |856| On-Demand Resources | Active; tag resources for download on demand |857| Asset catalogs | Used for app thinning of images (1x/2x/3x) |858859### Entitlements and Capabilities860861Certain features require entitlements configured in Xcode and provisioning profiles:862863| Capability | Entitlement | Common Issues |864|------------|-------------|---------------|865| Push Notifications | `aps-environment` | Certificate expiry, missing provisioning |866| App Groups | `com.apple.security.application-groups` | Shared container ID mismatch |867| Associated Domains | `com.apple.developer.associated-domains` | AASA file not served correctly |868| HealthKit | `com.apple.developer.healthkit` | Missing required capabilities |869| Background Modes | `UIBackgroundModes` | Using modes without justification |870| Sign in with Apple | `com.apple.developer.applesignin` | Missing from provisioning profile |871| CloudKit | `com.apple.developer.icloud-services` | Container ID mismatch |872| In-App Purchase | — | Enabled by default; StoreKit config needed for testing |873874### TestFlight Submission875876| Aspect | Internal Testing | External Testing |877|--------|-----------------|-----------------|878| Testers | Up to 100 ASC users | Up to 10,000 via email/public link |879| Review required | No | Yes (first build per version, full App Review) |880| Review time | — | Usually under 24 hours |881| Build expiry | 90 days from upload | 90 days from upload |882| Groups | Automatic (ASC roles) | Custom groups with "What to Test" notes |883| Feedback | Crash reports | Screenshots, text feedback, crash reports |884| Submission limit | — | Max 6 builds per 24-hour period |885886**TestFlight readiness checklist**:887- [ ] Internal tester group exists (required before creating external groups)888- [ ] Beta App Description set (can differ from production)889- [ ] Feedback email configured890- [ ] "What to Test" notes written for each external group891- [ ] Export compliance answered (required for beta builds too)892- [ ] Demo credentials included (if login required)893- [ ] First external build: expect full App Review (guideline compliance checked)894895**Gotchas**:896- Builds uploaded as "TestFlight Internal Only" from Xcode/Xcode Cloud can only go to internal groups897- Managed Apple Accounts (School/Business Manager) cannot be testers898- Public link tester cap is configurable (1-10,000) per link899- Builds remain testable even after the app goes live on the App Store900- Developer can manually expire builds before 90 days901902---903904## Part 10: WWDC25 Changes905906### Draft Submissions (WWDC 2025-328)907908Group multiple items into a single draft submission:909- App version + new IAPs + product page changes910- Review everything together instead of separate submissions911- Draft state: prepare items over time, submit when ready912913### Reusable Build Numbers on Failure914915When a build is rejected due to metadata issues (not binary issues), you can reuse 916917…(truncated)