A 2.5.1 rejection usually means one of two things: your app touched an API Apple does not allow, or it used an allowed API in a way Apple does not approve. The frustrating part is that the offending call often comes from a third-party SDK you did not write, so the rejection points at your binary for code a dependency pulled in. Guideline 2.5.1, Software Requirements, is about using only public APIs, for their intended purpose, on a current OS. Here is what triggers the rejection and how to find the actual cause.
Short answer
Guideline 2.5.1 requires that apps use only public APIs, run on the currently shipping OS, phase out deprecated technologies, and use frameworks for their intended purpose. Per Apple's software requirements guideline, a 2.5.1 rejection most often means your app references a non-public (private) API, or uses a public API in an unapproved way, such as a framework for a purpose other than its documented one. The reference frequently comes from a third-party SDK rather than your own code. To fix it, identify which symbol or SDK triggered the flag, update or replace that dependency, and remove any private API usage so the build relies only on documented APIs.
What you should know
- Public APIs only: apps may not reference non-public, private APIs.
- Intended purpose matters: use frameworks for what they are documented to do.
- Current OS and no deprecated tech: keep up to date and phase out old frameworks.
- SDKs are a common cause: a dependency can pull in the flagged symbol.
- Detection is automated: static analysis flags private API references in the binary.
What does Guideline 2.5.1 require?
That your app stays inside Apple's supported, documented surface. The rule has a few parts: use only public APIs, run on the currently shipping operating system, keep up to date by phasing out deprecated features and frameworks, and use APIs and frameworks for their intended purposes, indicating that use in your description. So HealthKit is for health and fitness, HomeKit is for home automation, and using a public API to do something it was not meant for, like importing arbitrary media into a hidden vault, can be an unapproved use even though the API itself is public. The throughline is that Apple wants apps built on documented behavior it can support, not on private symbols or off-label framework use.
What are the common causes of a 2.5.1 rejection?
A handful of patterns account for most of them. The table lists them with the fix.
| Cause | What it looks like | Fix |
|---|---|---|
| Private API reference | A symbol matching a non-public selector in the binary | Find and remove it, often by updating the SDK that uses it |
| Outdated third-party SDK | An old SDK calling APIs that are now private or removed | Update to a current version or replace the SDK |
| Unapproved use of a public API | Using a framework for a purpose other than documented | Align the usage with the framework's intended purpose |
| Deprecated technology | Reliance on a framework Apple is removing | Migrate to the supported replacement |
The most common in practice is a private API reference dragged in by a dependency, since Apple's automated analysis scans the binary for symbols that match private selectors, and a single outdated SDK can include one without your knowledge.
How do you fix a 2.5.1 rejection?
Find the specific trigger, then eliminate it at the source. Start by reading the rejection message, which sometimes names the symbol or API; if it does, search your code and your dependencies for it. Because the call usually lives in a third-party SDK, audit your dependencies, update each to its current version, and replace any that are unmaintained or known to use private APIs. For an unapproved-use rejection, change how you call the framework so it matches the documented purpose, and make your description reflect that use. After changes, rebuild and rescan the binary so you are confident the private reference is gone before you resubmit, since guessing and resubmitting blindly wastes a review cycle.
What to watch out for
The first trap is assuming the problem is in your own code when it is almost always a dependency, so audit your SDKs first. The second is updating one SDK while another still carries the private symbol, so check all of them. The third is treating an unapproved-use rejection as a private API issue when it is about purpose, which needs a usage change, not a symbol removal. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled IPA against OWASP MASVS and surfaces the SDKs and symbols in your build, which helps you locate a private API reference and the dependency that introduced it before review flags it. That turns a blind resubmit into a targeted fix.
What to take away
- Guideline 2.5.1 requires public APIs only, a current OS, no deprecated tech, and frameworks used for their intended purpose.
- A 2.5.1 rejection usually means a private API reference, often from a third-party SDK, or an unapproved use of a public API.
- Fix it by finding the specific symbol or SDK, updating or replacing the dependency, and aligning framework use with its documented purpose.
- Use a pre-submission scan such as PTKD.com to locate the private reference and the SDK that introduced it before you resubmit.


