# How the ipatool Download Command Handles License Requirements: Detection and Acceptance Flow

> Learn how the ipatool download command detects and accepts license requirements, with options for interactive prompts or direct acceptance via --accept-license.

- Repository: [Majd/ipatool](https://github.com/majd/ipatool)
- Tags: internals
- Published: 2026-09-06

---

**The ipatool download command detects license requirements by inspecting Apple App Store API responses for specific error codes, then either prompts the user to accept the license interactively or allows explicit acceptance via the `--accept-license` flag.**

The `download` command in the **majd/ipatool** repository automates IPA downloads from the Apple App Store while ensuring compliance with mandatory license agreements. When Apple's servers require explicit license acceptance before delivering an application bundle, the command implements a structured three-step flow—detection, user notification, and header-based acceptance—to handle the requirement gracefully without silent failures.

## License Detection in the macOS Adapter

The core detection logic resides in [`pkg/appstore/appstore_download_macos_adapter.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download_macos_adapter.go). When the download adapter communicates with Apple's servers, it inspects HTTP responses for status codes and JSON payloads indicating a license requirement.

### Identifying License-Required Responses

The `doRequest` method checks for HTTP 403 (Forbidden) responses and parses the JSON body for an `errorCode` field. If this field contains `LICENSE_REQUIRED`, the adapter returns `appstore.ErrLicenseRequired` to signal that user intervention is necessary before the download can proceed.

```go
// pkg/appstore/appstore_download_macos_adapter.go – licence detection
func (d *macOSDownloader) doRequest(req *http.Request) error {
    // …perform HTTP request…
    if resp.StatusCode == http.StatusForbidden {
        var respBody struct {
            ErrorCode string `json:"errorCode"`
        }
        json.NewDecoder(resp.Body).Decode(&respBody)
        if respBody.ErrorCode == "LICENSE_REQUIRED" {
            return fmt.Errorf("%w: license agreement needed", appstore.ErrLicenseRequired)
        }
    }
    // …normal processing…
    return nil
}

```

## Error Handling in the Command Layer

The [`cmd/download.go`](https://github.com/majd/ipatool/blob/main/cmd/download.go) file implements the user-facing logic that catches license errors and provides actionable remediation steps. This ensures users understand why a download failed and how to fix it.

### Interactive Prompting and User Instructions

When the `RunE` handler catches `ErrLicenseRequired`, it writes a descriptive message to stderr explaining that the application requires license acceptance. The user can then either open the App Store application to accept the agreement interactively, or re-run the command with the `--accept-license` flag for non-interactive workflows.

```go
// cmd/download.go – simplified flow
func runDownload(cmd *cobra.Command, args []string) error {
    // …parse flags, create download options…
    opts := []appstore.DownloadOption{
        appstore.WithAppID(appID),
    }
    if acceptLicense {
        opts = append(opts, appstore.WithAcceptLicense())
    }

    err := appstore.Download(ctx, opts...)
    if err != nil {
        if errors.Is(err, appstore.ErrLicenseRequired) {
            fmt.Fprintln(cmd.ErrOrStderr(),
                "This app requires you to accept a license agreement. "+
                "Run the command again with '--accept-license' or open the App Store UI to accept it.")
            return err
        }
        return err
    }
    fmt.Fprintln(cmd.OutOrStdout(), "Download completed successfully.")
    return nil
}

```

## Explicit License Acceptance Mechanism

When the user provides the `--accept-license` flag, the command enables the `AcceptLicense` option in the download configuration. This signals the adapter to include a specific header that satisfies Apple's license acceptance protocol.

### The X-Apple-Store-Licence-Accepted Header

According to the implementation in [`pkg/appstore/appstore_download_macos_adapter.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download_macos_adapter.go), setting the `AcceptLicense` option causes the adapter to add the `X-Apple-Store-Licence-Accepted: 1` HTTP header to the request. This header indicates to Apple's servers that the user has explicitly agreed to the license terms, allowing the download to complete successfully without further user interaction.

## Key Implementation Files

The license handling flow spans four critical files in the repository:

- **[`cmd/download.go`](https://github.com/majd/ipatool/blob/main/cmd/download.go)**: Implements the CLI command, parses the `--accept-license` flag, and handles `ErrLicenseRequired` with user-facing error messages.
- **[`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go)**: Defines the high-level `Download` function and provides the `WithAcceptLicense` option for configuring license acceptance.
- **[`pkg/appstore/appstore_download_macos_adapter.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download_macos_adapter.go)**: Contains the platform-specific logic for detecting license errors via HTTP response inspection and injecting the acceptance header.
- **[`pkg/appstore/appstore_download_macos.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download_macos.go)**: Acts as a wrapper that instantiates the macOS-specific adapter for the download operation.

## Summary

- **Detection**: The macOS adapter in [`appstore_download_macos_adapter.go`](https://github.com/majd/ipatool/blob/main/appstore_download_macos_adapter.go) parses HTTP 403 responses and JSON `errorCode` fields to identify `LICENSE_REQUIRED` errors.
- **Notification**: The command layer catches these errors and prints explicit instructions to stderr, preventing silent failures.
- **Acceptance**: Users can accept licenses interactively through the App Store UI or non-interactively using the `--accept-license` flag, which triggers the `X-Apple-Store-Licence-Accepted: 1` header.
- **Architecture**: The implementation separates concerns between API interaction (adapter), orchestration (appstore package), and CLI handling (command layer).

## Frequently Asked Questions

### What happens if I run the download command without the `--accept-license` flag when a license is required?

The command will detect the requirement via the macOS adapter, print an error message to stderr explaining that you must accept the license agreement, and exit with a non-zero status. The IPA will not download until you either open the App Store application to manually accept the license, or re-run the command with the `--accept-license` flag.

### Does ipatool automatically accept licenses on my behalf?

No. The source code in [`cmd/download.go`](https://github.com/majd/ipatool/blob/main/cmd/download.go) explicitly checks for `appstore.ErrLicenseRequired` and requires explicit user action. The tool never silently accepts licenses; it will always prompt you or require the explicit `--accept-license` flag to proceed, ensuring you consciously agree to the terms.

### Which specific error code triggers the license requirement handler?

The handler triggers when the JSON response body from Apple's servers contains `"errorCode": "LICENSE_REQUIRED"`. This string is checked in the `doRequest` method of [`pkg/appstore/appstore_download_macos_adapter.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download_macos_adapter.go) when processing HTTP 403 responses.

### Is the license acceptance flow available on all operating systems?

The license detection and acceptance logic is specific to the macOS implementation found in [`pkg/appstore/appstore_download_macos_adapter.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download_macos_adapter.go). The `X-Apple-Store-Licence-Accepted` header and the associated error parsing are part of the macOS-specific adapter, as ipatool is designed primarily for interacting with the macOS App Store infrastructure.