LimitedRound 2 is open. Get your first month free, no extra charge.Join the waitlist ›
Fix and resubmit

Guideline 2.5.1 private API usage rejection: how to fix it

TL;DR. Guideline 2.5.1 requires apps to use only public APIs and to run on the current OS. A rejection here means Apple detected a private or non-public API, or a public API used in an unapproved way. The fix is to find the flagged symbol, which is often inside a third-party SDK, and replace it with a public API or remove the dependency. Apple reviews every resubmission, so the build has to be clean.

What App Store Guideline 2.5.1 says

Guideline 2.5.1 states that apps may only use public APIs and must run on the currently shipping OS. It tells you to keep apps up to date and to phase out deprecated features, frameworks, and technologies that will not be supported in future OS versions. It also says apps should use APIs and frameworks for their intended purposes, and gives examples: HomeKit should provide home automation, and HealthKit should be used for health and fitness and integrate with the Health app.

There are two failure modes. One is calling a private, non-public API that is not in Apple's published set. The other is using a public API in an unapproved manner, outside the purpose it was designed for. The official text lives on the App Store Review Guidelines page.

Why apps get rejected under 2.5.1

Common triggers:

  • The binary references a private framework, selector, or symbol that is not part of the public Apple developer documentation.
  • A third-party SDK calls a private API, putting the symbol in your app even though your code does not.
  • A public API is used for a purpose it was not designed for, such as repurposing a framework outside its intended use.
  • The app relies on a deprecated technology that is no longer supported.
  • Code uses runtime tricks, like dynamic lookups, to reach methods that are not public.

The thread is that the binary touches something outside Apple's supported, public surface, which is what 2.5.1 prohibits.

How to fix it

  1. Read the rejection. Apple's message often names the symbol or selector it detected. Note it exactly.
  2. Search your code and dependencies. Look for the named symbol across your source and your libraries, since the match is frequently in a dependency.
  3. Replace with a public API. Where your own code uses a non-public call, switch to a supported public API that achieves the same result.
  4. Update or remove the SDK. For a private symbol inside a third-party SDK, move to a compliant version, or remove the library if it has not been fixed.
  5. Use APIs as intended. If the issue is unapproved use of a public API, change the implementation so the framework is used for its documented purpose, then re-archive and re-upload.

Remember that submitted is not approved. A clean resubmission still goes back through review, and Apple inspects the binary again.

How AppFlight helps

AppFlight builds native iOS apps in Swift and SwiftUI against public Apple frameworks, so the generated code targets the supported API surface rather than reaching for private calls. Because AppFlight manages the dependencies it wires in and keeps them on current versions, it reduces the chance that an outdated SDK drags a private symbol into the binary. When Apple returns a 2.5.1 rejection, AppFlight reads the rejection reason, works on the flagged symbol or the offending dependency, and resubmits the build. AppFlight does not guarantee approval. The binary still has to use only public APIs, and Apple reviews every app and every resubmission.

FAQ

What does Guideline 2.5.1 mean by private APIs?

Apple publishes a set of public APIs that apps are allowed to use. Anything outside that set is a private or non-public API. Guideline 2.5.1 says apps may only use public APIs, because private ones can change without notice and are not supported for App Store apps.

How do I find which API was flagged?

Apple's rejection message often names the symbol or selector it detected. You can search your code and dependencies for that symbol. Because Apple inspects the whole binary, the match is frequently inside a third-party SDK rather than your own code.

Can a third-party SDK cause a 2.5.1 rejection?

Yes, and it is a common cause. An SDK that calls a private API puts that symbol in your binary. Update the SDK to a compliant version, or remove it, since the private symbol triggers the rejection even though you did not write it.

Sources

Build this app without opening Xcode.

AppFlight turns a plain-English prompt into a real native iOS app and ships it to the App Store. Round 2 is open: free for your first month.

Join the waitlist