itms-services Explained: The Protocol Behind "Install This App on My iPhone"
Every over-the-air iOS install link — from Diawi, TestFlight-style services, enterprise portals — runs on the same quiet protocol. Here's what it actually does.
The two pieces
An OTA install is a chain of two URLs:
itms-services://?action=download-manifest&url=https://your-server.com/manifest.plist
- The scheme.
itms-servicesis a private iOS URL scheme. Opening it tells iOS "download a manifest and install what it points to." It only works in Safari (or a WebView) on iOS — not Chrome, not Android. - The manifest. A small plist that iOS fetches and parses. It contains the metadata (bundle identifier, version, display name) and, critically, the
software-packageasset: a direct HTTPS URL to the .ipa itself.
What a manifest plist looks like
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>https://your-server.com/app.ipa</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>com.example.app</string>
<key>bundle-version</key>
<string>1.2.3</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>Example App</string>
</dict>
</dict>
</array>
</dict>
</plist>
- The manifest must be served over HTTPS — iOS refuses plain HTTP manifests (and the IPA URL should be HTTPS too).
- The IPA must be signed for the installing device: ad-hoc with its UDID, or enterprise. An unsigned IPA installs and immediately crashes, or iOS blocks it outright.
- Any web server can host this. That's why "install link" services exist at all — the plumbing is public.
Why you don't want to hand-write it
The manifest has to match the IPA exactly — one wrong bundle identifier and iOS says "Unable to Download App." The common failure chain: re-exported build → stale manifest → testers get errors → someone burns an hour. A distribution service generates the manifest from the uploaded IPA's Info.plist, so the two can never drift.
That's the entire job Build Installer does: upload the IPA, we read the metadata, generate the manifest, and hand you the itms-services link plus a QR code. Try it with a real build:
FAQ
Does itms-services work in Chrome or other browsers?
No. The scheme only fires in Safari on iOS. On other browsers, testers need the direct IPA download plus a manual install path.
Can I host the manifest myself?
Yes — any HTTPS server. But you maintain the manifest, the IPA URL and the signing correctness yourself. Services exist to remove exactly that maintenance.
What's the difference between itms-services and TestFlight?
itms-services is the raw protocol — any signed build, any host. TestFlight is Apple's managed beta service built on top of their own infrastructure with 90-day build expiry. See the full TestFlight comparison.