Get a Unity build onto phones without a store

Unity already gives you everything a tester needs — an installable .apk on Android, and an Xcode project that exports an .ipa on iOS. Neither has to go near a store. Upload the file to BetaDrop and you get an install link and QR code; testers install from the phone's browser with no tester account, no review queue, and no cables. A guest upload doesn't even need a BetaDrop account.

Unity developers get stuck in exactly two places: an Android checkbox that silently produces the wrong file format, and an iOS signing rule that predates Unity entirely. Both take a minute to fix once you know where they are.

Android: build an APK, not an App Bundle

  1. Switch the build target to Android. In Unity, open File → Build Settings (File → Build Profiles in Unity 6), select Android, and click Switch Platform if it is not already active.
  2. Turn off Build App Bundle. Make sure 'Build App Bundle (Google Play)' is unchecked. Testers sideload an APK; an .aab is a Play publishing format that a phone cannot install directly.
  3. Sign with a keystore. In Player Settings → Publishing Settings, create or select a keystore with the Keystore Manager. Use the same keystore for every tester build so a new version installs over the old one instead of demanding an uninstall.
  4. Build and upload the .apk. Click Build, then upload the .apk to BetaDrop. You get an install link and QR code; testers open it in their phone's browser, allow installs from that browser once, and tap install.

The checkbox that breaks tester installs

“Build App Bundle (Google Play)” outputs an .aab, which is a Play publishing format — the store repackages it into APKs at download time, and a phone cannot install the bundle itself. Leave it off for tester builds and only turn it on for the actual Play upload. Curious what's inside one? The AAB inspector will show you.

One more Android note: if a tester says an update “won't install” over the previous version, the two builds were almost certainly signed with different keys — typically two machines' debug keystores. Run each APK through the APK signature checker and compare the SHA-256 certificate fingerprints it reports, then standardize on one keystore.

iOS: Unity hands you an Xcode project, not an IPA

  1. Build the Xcode project from Unity. Select iOS in Build Settings and click Build. Unity does not produce an .ipa directly — it generates an Xcode project you finish on a Mac.
  2. Open it in Xcode and set your team. Open Unity-iPhone.xcodeproj (or the .xcworkspace if your project pulls in CocoaPods), select the Unity-iPhone target, and pick your signing team under Signing & Capabilities.
  3. Archive with an ad-hoc profile. Run Product → Archive, then Distribute App → Ad Hoc (called Release Testing in Xcode 15 and later). The provisioning profile must list the UDID of every tester device — an ad-hoc build refuses to install on a device that is not in it.
  4. Upload the .ipa. Upload the exported .ipa to BetaDrop. It generates the itms-services manifest automatically, so testers install over the air from Safari — no cable, no TestFlight.

The UDID caveat is the part that surprises Unity developers most, because it has nothing to do with Unity. Apple's ad-hoc distribution only installs on devices whose UDIDs were baked into the provisioning profile at signing time. Before you archive, collect each tester's UDID — the UDID checker reads it from their device in a couple of taps — add the devices in the Apple Developer portal, and regenerate the profile. If an install fails anyway, drop the .ipa into the IPA inspector to see the profile type and how many devices it covers; to read the actual UDID list, pull Payload/YourApp.app/embedded.mobileprovision out of the bundle and open it in the provisioning profile decoder.

BetaDrop generates the itms-services manifest that makes the over-the-air install work, but it never touches signing — your build installs on precisely the devices Apple's rules say it can, and your signing keys stay on your Mac.

Unity builds run large — here's the ceiling

Even a fresh template project produces a build in the tens of megabytes, and a real game with textures, audio, and addressable content grows quickly. Free uploads on BetaDrop take files up to 500 MB each, which comfortably covers the overwhelming majority of Unity tester builds; Studio raises the per-file cap to 1 GB. A free account also holds 1 GB of builds in total, and at Unity sizes that total is the one you meet first — delete or let old tester builds expire as you go.

If you're over the line, trim the player before touching assets: IL2CPP with ARM64 as the only target architecture plus “Strip Engine Code” cuts the native side dramatically, and “Split APKs by target architecture” keeps each APK to a single ABI.

Publishing from CI

Game CI setups vary too much for one recipe — GameCI containers on GitHub Actions, Unity Build Automation, a Mac mini running Jenkins for the Xcode half. The good news is that the publish step doesn't care: any runner with Node can install the BetaDrop CLI and print an install link. In GitHub Actions it looks like this; the same two commands drop into any other runner's script step.

- name: Publish to BetaDrop
  id: betadrop
  run: |
    npm install -g @betadrop/cli
    url="$(betadrop publish build/Android/*.apk --ci)"
    echo "install-url=$url" >> "$GITHUB_OUTPUT"
  env:
    BETADROP_TOKEN: ${{ secrets.BETADROP_TOKEN }}

Create the token under Settings → Developer → API tokens on betadrop.app and store it as the BETADROP_TOKEN secret — the CLI reads it from the environment in CI. The --ci flag prints only the install URL, so the output above can be posted straight to a pull request or Slack. Point the glob at wherever your build lands (for the iOS half, at the exported .ipa). It must match exactly one file — if you turned on “Split APKs by target architecture” above, name the ABI you want, e.g. build/Android/*-arm64-v8a.apk, and add a step per ABI. A packaged one-step GitHub Action is being prepared for the GitHub Marketplace; this CLI step is what it wraps, and it works today.

When Play Internal Testing or TestFlight is the better choice

Use Play's internal testing track when your release artifact is an .aab and you need to test exactly what Play delivers — per-device splits, Play Feature Delivery, or Google Play billing flows. If you're already uploading to the Play Console for release, its internal track is one click away and tests the store's own packaging.

Use TestFlight when your iOS tester pool outgrows ad-hoc's 100-devices-per-type-per-year registration cap, when you can't collect UDIDs at all, or when you're validating StoreKit purchases in a build headed for review.

BetaDrop's lane is the moment before either of those: the build you made five minutes ago, going to a handful of phones, with no track setup, no review wait, and no tester onboarding. Many Unity teams use both — BetaDrop for daily tester builds, the store tracks for release candidates.

Ship the build you just made

Drag the .apk or .ipa in, send the link, and your testers are playing the build before the editor finishes reimporting.

Frequently asked questions

Why can't testers install my Unity .aab?

An .aab (Android App Bundle) is a publishing format, not an installable one. Google Play repackages it into device-specific APKs at download time; Android itself has no installer for the bundle. For tester builds, uncheck Build App Bundle in Unity's Build Settings so the output is an .apk, which any Android phone can sideload. BetaDrop distributes .apk files and does not accept .aab uploads.

Do I need a release keystore for a Unity test APK?

Not strictly — Unity signs with a debug keystore by default, and a debug-signed APK sideloads fine. The catch is updates: Android only installs a new build over an old one when both are signed with the same key, so a build signed on a different machine's debug key forces testers to uninstall first. Create one keystore in Player Settings → Publishing Settings and use it for every tester build.

Why won't my Unity iOS build install on a tester's iPhone?

Almost always the provisioning profile. An ad-hoc build installs only on devices whose UDID is listed in the profile it was signed with. Collect the tester's UDID, add it in the Apple Developer portal, regenerate the profile, and archive again in Xcode. BetaDrop generates the itms-services manifest for the over-the-air install, but it cannot change what Apple's signing allows.

How big can a Unity build be on the free tier?

Free uploads take files up to 500 MB each, which covers nearly every Unity tester build, and a free account holds 1 GB of builds in total — with Unity-sized builds that total is usually the limit you meet first, so let old tester builds expire or delete them. If a single build is over the per-file cap, the fastest trims are on the player side: IL2CPP with ARM64 as the only target architecture, Strip Engine Code enabled, and stronger texture compression.

Do testers need an account or a store to install a Unity build?

No. A tester opens the link — or scans the QR code — in the phone's browser and installs from there. There is no Play Store or App Store listing, no TestFlight invite, and no tester account. Android asks once for permission to install apps from that browser; on iOS the device must be covered by the build's provisioning profile.

iMobile Designs
Developed by iMobile Designs
Made with
in India