2026 iTMSTransporter Windows IPA Upload and Release Tutorial

To upload an IPA on Windows with Apple’s official iTMSTransporter, the correct command in 2026 looks like this:

1iTMSTransporter -m upload -assetFile App.ipa -assetDescription AppStoreInfo.plist -u dev@example.com -p abcd-efgh-ijkl-mnop

Note the -assetDescription AppStoreInfo.plist in there — it is mandatory on Windows and Linux, and officially this file can only be exported from Xcode. This is exactly where I got stuck, so below I’ll explain how to generate it directly on Windows.

First, understand what changed in 2026

If you follow tutorials from a few years ago, you will most likely fail. Three things have changed:

  1. -f can no longer be used to upload apps. Apple has made it clear: uploading or verifying an app must use -assetFile; -f is retained only for other content types. The old -m upload -f App.ipa style now fails outright.
  2. .itmsp package delivery is deprecated. In the past you had to manually create a <vendor_id>.itmsp directory and drop metadata.xml and the IPA into it; now you just point -assetFile at the IPA. Much simpler.
  3. -assetDescription is required on Windows / Linux. Apple’s official user guide states it plainly: this parameter is “required for Linux and Windows App uploads, but not for macOS App uploads.” On macOS you don’t need it, because Transporter invokes the tools inside Xcode to generate one on the fly; on Windows there is no Xcode, so you have to prepare it yourself and hand it over.

Point 3 is the killer, so we’ll handle it in a dedicated step below.

Step 1: Install iTMSTransporter

Transporter is currently at version 4.2, and the Windows build is a self-extracting installer.

Download URL (official Apple direct link):

https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/resources/download/public/Transporter__Windows/bin

The download is iTMSTransporterToolInstaller_4.2.0.<build>.exe. Double-click it, accept the license agreement, and the default install directory is:

C:\Program Files\itms

After installation, an iTMSTransporter.woa subdirectory is created inside. The command-line entry point lives in the install directory, written in the official docs as .\iTMSTransporter (on Windows it is actually a batch script of the same name). If you’re not sure where it is, search for iTMSTransporter in the install directory.

First verify that it runs:

1cd "C:\Program Files\itms\bin"
2iTMSTransporter -version

If it prints a version number, the installation is fine. To make later commands easier to type, it is recommended to add this bin directory to the system PATH: Settings → System → About → Advanced system settings → Environment Variables → select Path → Edit → New, paste the directory path, then open a new command-line window for it to take effect.

Step 2: Prepare AppStoreInfo.plist (the critical step)

This is where Windows users really get stuck, so let’s first be clear about what it is.

AppStoreInfo.plist is not a configuration file in your project; it is a descriptive manifest of your package: the package type, platform, the structure of each bundle inside, icons, signing information, and so on. Apple relies on it to check the package when it is received. Apple itself wrote a line in the file:

This App Store Information can be used with iTMSTransporter and App Store Connect Developer API.

The problem is that this manifest is normally generated by a tool in the Xcode toolchain, and that tool only runs on macOS. So Windows users hit a dead end: Transporter has a Windows version, yet on Windows it insists that you provide a file that can only be generated on a Mac.

The common workaround online is to find a Mac to generate it and copy it over, or rent a cloud Mac — spinning up an entire machine for a file of a few dozen KB is clearly not worth it.

With the AppUploader command-line tool, you can generate this file directly on Windows, with a single command:

1appuploader-cli info -u dev@example.com App.ipa -o AppStoreInfo.plist
  • appuploader-cli.exe is in the AppUploader install directory; it comes with the main program, so there’s no separate download;
  • -u takes your Apple ID email;
  • the trailing -o specifies the output file name.

When it finishes, it prints a line with the file size and the package’s Bundle ID, so you can check that you’re uploading the package you intended:

asset description written to AppStoreInfo.plist (93613 bytes, xml plist, bundle id com.example.app)

Put the IPA and the plist in the same directory. This is one of the more commonly hit pitfalls in practice: when the two files are scattered across different paths, the upload tends to fail. Keeping them together is the least hassle.

Step 3: Prepare account credentials

iTMSTransporter supports two login methods.

Option 1: Apple ID + app-specific password. Go to https://account.apple.com/account/manage and generate an app-specific password in the form abcd-efgh-ijkl-mnop. It is shown only once, so save it on the spot. Pass it with -u and -p on the command line.

Option 2: App Store Connect API key (recommended). Generate one at https://appstoreconnect.apple.com/access/api, and you get a key ID, an Issuer ID, and a .p8 file. iTMSTransporter is particular about where the .p8 lives: it does not accept a path you pass in; instead it looks for a fixed file name in several fixed directories:

./private_keys/AuthKey_<key ID>.p8

That is, create a private_keys folder in the current directory where you run the command, and put the file in it named AuthKey_<key ID>.p8. Besides the current directory, it also looks in ~/private_keys, ~/.private_keys, and ~/.appstoreconnect/private_keys, in that order, and you can also specify a directory with the API_PRIVATE_KEYS_DIR environment variable.

A side note: Transporter also has a -jwt parameter that takes a token directly, but since late September 2025, -jwt combined with -assetDescription has had server-side rejection issues, reporting No value present. The -apiKey / -apiIssuer pair does not have this problem, so avoid -jwt if you can.

Step 4: Verify first, then upload

Before the real upload, it is advisable to run a verification pass first; it catches problems with the package itself early and saves you from waiting through an upload only to be rejected:

1iTMSTransporter -m verify -assetFile App.ipa -assetDescription AppStoreInfo.plist -u dev@example.com -p abcd-efgh-ijkl-mnop

Once verification passes, upload by changing -m verify to -m upload:

1iTMSTransporter -m upload -assetFile App.ipa -assetDescription AppStoreInfo.plist -u dev@example.com -p abcd-efgh-ijkl-mnop

If you’re using an API key (remember to create the private_keys directory first):

1iTMSTransporter -m upload -assetFile App.ipa -assetDescription AppStoreInfo.plist -apiKey UK29KBAX9X -apiIssuer 69a6de78-4459-47e3-e053-5b8c7c11a4d1

Parameter reference:

Parameter Meaning
-m upload / -m verify Upload / verify only without uploading
-assetFile Path to the IPA or PKG (stop using -f)
-assetDescription The AppStoreInfo.plist generated in the previous step; required on Windows
-u / -p Apple ID and app-specific password
-apiKey / -apiIssuer API key ID and Issuer ID; mutually exclusive with -u -p
-v Log verbosity: off, critical, informational, detailed, eXtreme

When troubleshooting, add -v eXtreme for much more detailed output:

1iTMSTransporter -m upload -v eXtreme -assetFile App.ipa -assetDescription AppStoreInfo.plist -apiKey UK29KBAX9X -apiIssuer 69a6de78-4459-47e3-e053-5b8c7c11a4d1

After the upload, Apple still needs a few minutes to a few tens of minutes to process it, and only then does the build appear in the “Builds” list in App Store Connect; only after that can you select it for review submission. Not seeing it right after uploading is normal.

Common errors

Says -f cannot be used to upload apps

Old syntax. Switch to -assetFile.

Says the asset description is missing, or fails with no message at all

On Windows, -assetDescription is required; check whether you left it out and whether the path is correct. Also make sure the IPA and the plist are in the same directory.

Reports No value present

A known issue when passing a token via -jwt; switch to the -apiKey / -apiIssuer pair.

API key authentication fails, saying the key can’t be found

The .p8 location or file name is wrong. It must be private_keys/AuthKey_<key ID>.p8, placed in the current directory where you run the command, and the key ID in the file name must match the -apiKey parameter exactly.

Duplicate version number or build number

That version number + build number combination has already been uploaded; Apple does not allow overwriting, so change the build number and repackage.

Java-related errors

Transporter bundles its own runtime, so you generally do not need to install Java separately. If you get a Java-related error, it is usually an incomplete installation — uninstall and reinstall.

By the way: you don’t actually have to go through all this

The whole process above — installing Transporter, generating the plist, setting up the private_keys directory, assembling a long string of parameters — if your only goal is “get the IPA uploaded,” there is a shorter path: the same appuploader-cli you used to generate the plist can upload directly:

1appuploader-cli upload -f App.ipa -u dev@example.com -p abcd-efgh-ijkl-mnop

One command does the upload; no AppStoreInfo.plist needed, no Transporter install needed, and on failure the exit code is non-zero, so you can wire it straight into your build script.

When is it still worth using iTMSTransporter: when company process explicitly requires Apple’s official tools, or when your pipeline already has other stages built around Transporter. In those two cases, just use appuploader-cli info to fill in the AppStoreInfo.plist piece and keep the rest as is.

References


The most troublesome part of the whole setup is really the AppStoreInfo.plist step; the rest is just filling in parameters. The plist is generated with the command-line tool bundled with AppUploader, which on Windows can also sign certificates, create Bundle IDs, and generate provisioning profiles.