# How to Download Encrypted .ipa Packages with IPATool

> Learn to download encrypted ipa packages using IPATool by leveraging Apple's private App Store API for authenticated requests and generating valid ipa files.

- Repository: [Majd/ipatool](https://github.com/majd/ipatool)
- Tags: how-to-guide
- Published: 2026-09-01

---

**IPATool downloads encrypted iOS app packages by authenticating with Apple's private App Store API, constructing a device-specific download request, and patching the resulting ZIP with metadata to produce a valid .ipa file.**

IPATool is an open-source command-line utility that enables developers to retrieve encrypted iOS, iPadOS, tvOS, and visionOS app packages directly from Apple's servers. Understanding how to download encrypted .ipa packages with IPATool requires insight into its multi-stage architecture, which handles authentication, license acquisition, resumable file transfers, and post-download metadata injection. The implementation spans several packages in the `majd/ipatool` repository, with the core orchestration logic residing in [`cmd/download.go`](https://github.com/majd/ipatool/blob/main/cmd/download.go) and the download mechanics implemented in [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go).

## Prerequisites and Authentication Flow

Before any download begins, IPATool establishes a valid authenticated session with Apple's services. The `download` command in [`cmd/download.go`](https://github.com/majd/ipatool/blob/main/cmd/download.go) initiates this flow by invoking `AppStore.AccountInfo()` to retrieve stored credentials from the system keychain.

If the session token has expired, the tool automatically re-authenticates using `AppStore.Login()` with the stored Apple ID credentials. This ensures that the subsequent download request includes a valid authentication token without requiring manual re-entry of passwords.

### Handling License Requirements

When an application requires a purchase that the Apple ID has not previously acquired, IPATool returns `ErrLicenseRequired`. If the user supplies the `--purchase` flag, the command automatically invokes `AppStore.Purchase()` from [`pkg/appstore/appstore_purchase.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_purchase.go) to acquire the license before proceeding with the download.

## Locating the Target Application

IPATool accepts either a numeric **App ID** or a **Bundle Identifier** to locate the target package. When a bundle identifier is provided via the `--bundle-identifier` flag, the command calls `AppStore.Lookup()` from [`pkg/appstore/appstore_lookup.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_lookup.go) to resolve the corresponding numeric App ID. This lookup occurs in [`cmd/download.go`](https://github.com/majd/ipatool/blob/main/cmd/download.go) before the download request is constructed, ensuring the correct asset is targeted.

## Constructing and Executing the Download Request

The core download logic resides in [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go). The `AppStore.Download()` method builds a POST request containing the device GUID, the numeric App ID, and optionally an **external version ID** (required for tvOS and visionOS platforms). This request is sent to Apple's private `download` endpoint.

### Handling API Errors

The response handler monitors for specific failure conditions defined in the App Store package. If the server returns `ErrPasswordTokenExpired`, the command bubbles this error up to the retry logic in [`cmd/download.go`](https://github.com/majd/ipatool/blob/main/cmd/download.go), triggering a re-authentication cycle. Similarly, `ErrLicenseRequired` prompts an automatic purchase attempt when the appropriate flag is set.

## Streaming and Resumable Downloads

IPATool implements robust file handling to support large packages and interrupted connections. The `downloadFile()` function in [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go) manages this process through the following steps:

1. Creates a temporary file named `<destination>.tmp` to store incoming data.
2. Checks the existing file size to support resumption.
3. Issues an HTTP GET request with a `Range` header specifying the byte offset to continue from.
4. Streams the response body to both the temporary file and an optional progress bar.

If a download is interrupted, rerunning the same command detects the partial file and resumes from the last received byte rather than starting over.

## Post-Processing and Platform Validation

After the raw encrypted ZIP downloads successfully, IPATool performs critical post-processing to ensure the package is usable with iTunes or Xcode.

### Metadata Injection

The `applyPatches()` function in [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go) rewrites the downloaded ZIP archive while replicating all original entries. During this process, it injects an `iTunesMetadata.plist` file containing the Apple ID of the downloader. This metadata is essential for the resulting `.ipa` file to be recognized by Apple's deployment tools.

### Platform-Specific Verification

For tvOS and visionOS packages, the tool performs additional validation through `validatePackagePlatform()`. This function extracts the top-level `Info.plist` from the downloaded archive and inspects the `CFBundleSupportedPlatforms` array to verify that the binary explicitly declares support for the requested platform (e.g., `AppleTVOS` or `visionOS`). If the platform check fails, the download is rejected and the temporary file is removed.

## Command-Line Usage Examples

The following examples demonstrate practical usage of the `download` subcommand:

```bash

# Basic download using the numeric App ID

ipatool download --app-id 1234567890 --output MyApp.ipa

# Download by bundle identifier (overrides App ID)

ipatool download --bundle-identifier com.example.myapp --output MyApp.ipa

# Download a specific tvOS version (requires external version ID)

ipatool download \
  --app-id 1234567890 \
  --platform appletv \
  --external-version-id 2.3.4 \
  --output MyApp_tvOS.ipa

# Automatically purchase the app if a license is missing

ipatool download --app-id 1234567890 --purchase --output MyApp.ipa

```

### Key Flags Reference

- `--app-id` / `-i`: Numeric App Store identifier (required if `--bundle-identifier` is not supplied).
- `--bundle-identifier` / `-b`: Bundle ID string that overrides the App ID.
- `--output` / `-o`: Destination path for the downloaded `.ipa`.
- `--external-version-id`: Specific version identifier for tvOS/visionOS packages.
- `--platform`: Target platform (`iphone`, `ipad`, `appletv`, or `visionos`).
- `--purchase`: Automatically acquires the license if the app is not already owned.

## Summary

- **Authentication is automatic**: IPATool retrieves stored credentials via `AppStore.AccountInfo()` and refreshes sessions using `AppStore.Login()` before initiating downloads.
- **Resumable downloads supported**: The `downloadFile()` function uses HTTP `Range` headers to resume interrupted transfers, writing to temporary `.tmp` files before finalizing.
- **Metadata injection is mandatory**: The `applyPatches()` function ensures downloaded packages contain a valid `iTunesMetadata.plist` with the downloader's Apple ID.
- **Platform validation built-in**: For tvOS and visionOS, `validatePackagePlatform()` verifies `CFBundleSupportedPlatforms` in `Info.plist` before accepting the download.
- **License handling is integrated**: The tool can automatically purchase apps via `AppStore.Purchase()` when the `--purchase` flag is provided.

## Frequently Asked Questions

### What authentication methods does IPATool use to download encrypted .ipa files?

IPATool authenticates using Apple ID credentials stored securely in the operating system keychain. The tool retrieves these credentials through `AppStore.AccountInfo()` and validates or refreshes the session token via `AppStore.Login()` as implemented in [`pkg/appstore/appstore_login.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go). This process occurs automatically before any download request is sent to Apple's servers.

### Can IPATool resume interrupted downloads?

Yes. IPATool supports resumable downloads through HTTP `Range` requests. The `downloadFile()` implementation in [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go) checks the size of the existing temporary file and sends a `Range` header with the appropriate byte offset. This allows the download to continue from where it left off rather than restarting, which is essential for large iOS packages.

### Why does IPATool inject iTunesMetadata.plist into downloaded packages?

The `applyPatches()` function injects `iTunesMetadata.plist` because the raw encrypted ZIP returned by Apple's download endpoint lacks the metadata required by iTunes and Xcode to recognize and process the package. This plist file contains the downloader's Apple ID and other purchase information, making the `.ipa` file valid for sideloading and archival purposes.

### How does IPATool handle platform-specific packages like tvOS or visionOS?

For tvOS and visionOS downloads, IPATool requires the `--platform` flag (set to `appletv` or `visionos`) and optionally the `--external-version-id` flag. After downloading, `validatePackagePlatform()` extracts the `Info.plist` and verifies that the `CFBundleSupportedPlatforms` array includes the target platform. This prevents downloading iOS versions of apps when a specific tvOS or visionOS binary is required.