Over-the-Air (OTA) App Installation Explained: manifest.plist & itms-services (2026)

Over-the-Air (OTA) App Installation Explained: manifest.plist & itms-services (2026)

Jan Thalheim
Jan Thalheim
7 min read

Over-the-air (OTA) installation lets a device install an app directly from a link or QR code, without the App Store. On iOS it works through the itms-services:// URL scheme: the link points to a manifest.plist file that tells iOS where to download the signed .ipa and how to identify the app. Everything must be served over HTTPS, and for ad hoc builds the signature must match the device's registered UDID.

Understanding the mechanism helps you debug failed installs — and explains why most teams let a tool handle it rather than hosting it themselves.

The iOS OTA mechanism

An OTA install link looks like this:

itms-services://?action=download-manifest&url=https://example.com/app/manifest.plist

When a user taps it in Safari, iOS fetches the manifest.plist, reads where the .ipa lives, and installs it. Three things must all be true:

  1. The manifest and .ipa are served over HTTPS with a valid TLS 1.2+ certificate.
  2. The .ipa is properly signed — for ad hoc, the device's UDID must be in the provisioning profile.
  3. The manifest correctly describes the app (bundle identifier, version, URLs).

The manifest.plist

The manifest is a property-list file describing the download and the app:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<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://example.com/app/MyApp.ipa</string>
        </dict>
        <dict>
          <key>kind</key><string>display-image</string>
          <key>url</key><string>https://example.com/app/icon-57.png</string>
        </dict>
        <dict>
          <key>kind</key><string>full-size-image</string>
          <key>url</key><string>https://example.com/app/icon-512.png</string>
        </dict>
      </array>
      <key>metadata</key>
      <dict>
        <key>bundle-identifier</key><string>com.example.myapp</string>
        <key>bundle-version</key><string>1.0.0</string>
        <key>kind</key><string>software</string>
        <key>title</key><string>My App</string>
      </dict>
    </dict>
  </array>
</dict>
</plist>

Get any URL, the bundle identifier or the HTTPS certificate wrong and the install fails — often silently.

Android OTA

Android is simpler: there's no manifest protocol. You host the APK, the user taps the download link, allows installation from the source once, and installs directly. See distributing an Android app without the Play Store.

Why you probably shouldn't host this yourself

Hosting OTA by hand means running HTTPS with valid certs, generating a correct manifest.plist per build, keeping icons and URLs in sync, tracking which build is current, and — for iOS — managing UDIDs and ad hoc signing. It's a lot of moving parts to get an app onto a phone.

Tools automate all of it. Appisto generates the manifest, hosts everything over HTTPS, collects UDIDs automatically, and manages build history — you upload an .ipa or .apk and share one link. That's the same OTA mechanism described above, without you owning the plumbing. It's also how quick-link tools like Diawi work under the hood, minus the team layer.

Troubleshooting

  • Nothing happens on tap: check the HTTPS certificate and that the manifest URL is reachable.
  • "Untrusted Developer": expected for ad hoc — trust the profile.
  • "Unable to Install": the device UDID likely isn't in the profile — register it and rebuild.

Frequently asked questions

What is itms-services? The URL scheme iOS uses to install apps OTA — itms-services://?action=download-manifest&url=... points Safari at a manifest.plist that iOS uses to download and install the .ipa.

What is a manifest.plist file? A property-list file telling iOS where the .ipa is and describing the app (bundle identifier, version, title, icons). The OTA link references it.

Why does OTA install require HTTPS? iOS requires the manifest and .ipa over HTTPS with a valid TLS 1.2+ certificate; without it the install silently fails.

Key takeaways

  • iOS OTA uses itms-services:// → a manifest.plist → the signed .ipa, all over HTTPS.
  • The .ipa must be signed for the device's UDID (ad hoc).
  • Android OTA is just a hosted APK plus an unknown-sources allow.
  • Self-hosting is fiddly; Appisto automates the manifest, HTTPS, UDIDs and build history. See how to install an .ipa.

Ready to streamline your internal app distribution?

Start sharing your app builds with your team and clients today.
No app store reviews, no waiting times.