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
  1. The scheme. itms-services is 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.
  2. The manifest. A small plist that iOS fetches and parses. It contains the metadata (bundle identifier, version, display name) and, critically, the software-package asset: 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.