<!-- llms-explorer concept facts · https://llms-explorer.com/tree/guideline-2-5-public-apis-and-bundled-interpreter-and-private-api-string-scan-itms-90338/ · pack 2026-10-02 · ~869 tokens -->

# Guideline 2.5 public APIs and bundled interpreter and private-API string scan (ITMS-90338)

> Source-anchored research for Guideline 2.5 public APIs and bundled interpreter and private-API string scan (ITMS-90338). Run status: COMPLETED.

Parent: [Mac App Store App Review Guidelines for Sandboxed Utilities](https://llms-explorer.com/tree/apple-app-review-mac-utility-guidelines/) · 3 facets · 7 facts · page: https://llms-explorer.com/tree/guideline-2-5-public-apis-and-bundled-interpreter-and-private-api-string-scan-itms-90338/

## How it works

- ITMS-90338 'Non-public API usage' is an automated check that matches symbols referenced by any Mach-O in the bundle (including third-party frameworks and static libs) against Apple's private-symbol list. Apple's remedy text: rename source methods that collide with listed private APIs, or remove static libraries containing them; the cause is often a bundled third-party framework that needs updating. (medium confidence) — [source](https://developer.apple.com/forums/thread/733322)

## Problems, failure modes and limitations

- Removing an unneeded extension module from the bundle (e.g. _tkinter .so) cleared a non-public-API rejection for a Mac app embedding Python; Apple's reply stated non-public or deprecated APIs are not permitted and offered appeal to the App Review Board. (low confidence) — [source](https://developer.apple.com/forums/thread/758567)

## Facts and statements

- Guideline 2.5.1 says apps may only use public APIs and must run on the currently shipping OS; 2.5.2 says apps must be self-contained in their bundles, may not read/write outside the container, and may not download, install, or execute code that introduces or changes features. Educational code-teaching apps get a narrow exception. (medium confidence) (verified as of 2026-10-02) — [source](https://developer.apple.com/app-store/review/guidelines/)
- Embedded Python has been rejected for symbols the author never called: Python 3.9 libformw/libpanelw (ncurses) and posix_spawn symbols cited under Guideline 2.5.1 (March 2021, later validated without comment after the developer raised it), and Tcl.framework symbols via _tkinter.cpython-39-darwin.so (July 2024). (medium confidence) — [source](https://bugs.python.org/issue43374)
- Python 3.12 added the literal string 'itms-services' to Lib/urllib/parse.py (and its .pyc); Apple's scan flagged it under Guideline 2.5.2 ('installed or launched executable code'). CPython added a --with-app-store-compliance configure option (issue opened 2024-06-14) to patch it out; removing the string from a bundled copy let an update pass. (medium confidence) (verified as of 2024-06-14) — [source](https://github.com/python/cpython/issues/120522)
- Tkinter remains unshippable on the Mac App Store in CPython 3.9-3.14: libtk8.6.dylib references _NSWindowDidOrderOnScreenNotification; no fix as of the issue opened 2025-01-23. A menu-bar utility without Tk should exclude tkinter/Tcl/Tk from the py2app bundle. (low confidence) (verified as of 2025-01-23) — [source](https://github.com/python/cpython/issues/129247)
- Embedding Python and shipping to the Mac App Store has worked in practice: an embedded, signed interpreter keeps the sandbox and hardened runtime; old py2app versions produced invalid Python.framework bundles, and py2app 0.26 replaced a private symbol in its stub executable with a public API. (low confidence) — [source](https://github.com/davidfstr/Python-in-Mac-App-Store)
