# How to List Purchased Apps Using IPATool: A Complete Guide to the `list-purchases` Command

> Easily list your purchased apps with IPATool's list-purchases command. Query Apple's private purchase-history DAAP endpoint and get a paginated list of your owned apps.

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

---

**IPATool implements the `list-purchases` command to query Apple's private purchase-history DAAP endpoint, returning a paginated list of apps owned by your authenticated Apple ID.**

IPATool is a command-line utility that lets you interact with the App Store programmatically. One of its most useful features is the ability to list purchased apps using IPATool's `list-purchases` command, which retrieves your complete app ownership history directly from Apple's servers. This guide explains the internal architecture, command-line usage, and source code implementation based on the majd/ipatool repository.


## How the `list-purchases` Command Works

The command follows a layered architecture that separates CLI handling from core App Store communication. When you execute `ipatool list-purchases`, the tool orchestrates dependencies, validates flags, and initiates a secure session with Apple's servers.

### CLI Bootstrap and Dependencies

Execution begins in `initWithCommand` within [[`cmd/common.go`](https://github.com/majd/ipatool/blob/main/cmd/common.go)](https://github.com/majd/ipatool/blob/main/cmd/common.go). This function initializes the required infrastructure:

- **Logger**: Handles output formatting (JSON or plain-text)
- **OS detector**: Identifies the host operating system
- **Machine helper**: Retrieves hardware identifiers
- **Cookie jar**: Manages session persistence
- **Keychain**: Stores and retrieves authentication tokens
- **AppStore client**: The high-level interface for App Store operations

This dependency injection pattern ensures that `list-purchases` has access to authentication state and hardware identifiers required by Apple's servers.

### Command Definition and Flag Handling

The command definition resides in `listPurchasesCmd` inside [[`cmd/purchases.go`](https://github.com/majd/ipatool/blob/main/cmd/purchases.go)](https://github.com/majd/ipatool/blob/main/cmd/purchases.go). This function registers two key flags:

- `--page` or `-p`: Specifies which page of results to retrieve (default: 1)
- `--max-results` or `-l`: Controls the number of apps per page (default: 10)

After validating these parameters, the command invokes `AppStore.OwnedApps`, triggering the core retrieval workflow implemented in the appstore package.


## The Owned Apps Retrieval Workflow

The heavy lifting occurs in `OwnedApps` within [[`pkg/appstore/appstore_owned_apps.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go)](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go). This method implements the complete protocol for extracting your purchase history from Apple's private APIs.

### Authentication and Session Management

The workflow begins by normalizing input parameters (page number and limit). It then performs several cryptographic and networking steps:

1. **Hardware identification**: Retrieves the machine's MAC address and derives the **GUID** and **machine ID** required by Apple's authentication protocol
2. **SAP configuration**: Obtains a "bag" containing SAP (Secure Audio Protocol) configuration data
3. **Action signing**: Creates an SAP action signer to cryptographically sign requests
4. **Session establishment**: Opens a purchase-history session via `ownedAppsLoginRequest`
5. **Session update**: Refreshes the session context using `ownedAppsUpdateRequest`
6. **Data retrieval**: Fetches the actual app items through `ownedAppsItemsRequest`

This multi-step handshake ensures that requests appear to originate from legitimate Apple devices and can access the private DAAP (Digital Audio Access Protocol) endpoints that store purchase history.

### DMAP Response Parsing and Pagination

Once Apple returns the raw **DMAP** (Digital Media Access Protocol) response, the tool processes it through several functions:

- `parseOwnedApps` and `parseOwnedApp` extract structured data including:
  - App ID (numerical identifier)
  - Bundle ID (e.g., `com.example.myapp`)
  - App name
  - Version string
  - Purchase date (ISO 8601 format)

The results then undergo post-processing:

- **Sorting**: `ownedAppsSortedByPurchaseDate` orders apps chronologically by purchase date
- **Pagination**: `ownedAppsPage` slices the complete dataset according to your `--page` and `--max-results` parameters

The command automatically retries once if Apple's password token has expired, performing a fresh login via [[`pkg/appstore/appstore_login.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go)](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go) before re-issuing the request.


## Running the Command

You can list purchased apps using IPATool through straightforward CLI invocations that support both interactive plain-text output and structured JSON for scripting.

### Basic Usage

Retrieve the first page of your purchased apps (default 10 items per page):

```bash
ipatool list-purchases

```

Navigate large libraries using pagination controls:

```bash

# Show up to 25 apps per page, starting from page 2

ipatool list-purchases --max-results 25 --page 2

# Short flag version

ipatool list-purchases -l 25 -p 2

```

### Understanding the Output Format

When using `--format json`, the command returns structured data suitable for automation:

```json
{
  "count": 10,
  "totalCount": 42,
  "page": 1,
  "apps": [
    {
      "id": 123456789,
      "bundleID": "com.example.myapp",
      "name": "My App",
      "version": "1.2.3",
      "purchaseDate": "2023-07-15T12:34:56Z"
    }
  ]
}

```

The `totalCount` field indicates the complete size of your purchase history, while `count` reflects the current page size. The `bundleID` serves as the unique identifier for automation scripts that need to reference specific apps.


## Architecture and Key Source Files

Understanding the codebase structure helps when debugging or extending functionality:

- **[[`cmd/purchases.go`](https://github.com/majd/ipatool/blob/main/cmd/purchases.go)](https://github.com/majd/ipatool/blob/main/cmd/purchases.go)**: Defines the `list-purchases` command, handles flag validation (`--page`, `--max-results`), implements retry logic for expired tokens, and formats the final output using the configured logger.

- **[[`pkg/appstore/appstore_owned_apps.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go)](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go)**: Implements the core retrieval workflow including request construction, SAP action signing, DMAP response parsing, purchase-date sorting, and result pagination.

- **[[`cmd/common.go`](https://github.com/majd/ipatool/blob/main/cmd/common.go)](https://github.com/majd/ipatool/blob/main/cmd/common.go)**: Sets up shared dependencies including the logger, machine helper for hardware ID generation, keychain for credential storage, and the AppStore client interface.

- **[[`pkg/appstore/appstore.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore.go)](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore.go)**: Provides the high-level `AppStore` interface that exposes the `OwnedApps` method used by the CLI command.

- **[[`pkg/appstore/appstore_login.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go)](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go)**: Handles authentication flows, invoked automatically when the password token expires during a list-purchases operation.


## Summary

- IPATool's **`list-purchases`** command queries Apple's private DAAP endpoint to enumerate your App Store purchase history.
- The command supports **pagination** via `--page` and `--max-results` flags to handle large libraries efficiently.
- The architecture in [[`pkg/appstore/appstore_owned_apps.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go)](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go) handles complex authentication including MAC address retrieval, SAP signing, and DMAP parsing.
- **Automatic retry logic** refreshes expired tokens without manual intervention according to the implementation in [[`cmd/purchases.go`](https://github.com/majd/ipatool/blob/main/cmd/purchases.go)](https://github.com/majd/ipatool/blob/main/cmd/purchases.go).
- Output is available in both **plain-text** and **JSON** formats, with JSON providing structured fields like `bundleID`, `purchaseDate`, and `totalCount` for scripting.


## Frequently Asked Questions

### What authentication is required to list purchased apps?

You must authenticate with a valid Apple ID using `ipatool auth login` before running `list-purchases`. The command uses stored credentials from the system keychain, and automatically refreshes expired password tokens by performing a fresh login via [[`pkg/appstore/appstore_login.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go)](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go).

### How does IPATool handle pagination for large app libraries?

The tool retrieves your complete purchase history from Apple, then applies client-side pagination using `ownedAppsPage` in [[`pkg/appstore/appstore_owned_apps.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go)](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go). The `--page` and `--max-results` flags control which slice of the sorted results to display, with the JSON output including `totalCount` to help scripts calculate total pages.

### What happens if my Apple ID password token expires during the request?

The command implements transparent retry logic in [[`cmd/purchases.go`](https://github.com/majd/ipatool/blob/main/cmd/purchases.go)](https://github.com/majd/ipatool/blob/main/cmd/purchases.go). If the initial request fails due to an expired token, IPATool automatically performs a fresh authentication and re-issues the purchase history request once, ensuring uninterrupted operation without manual credential re-entry.

### Can I export the list of purchased apps to a file?

Yes, by combining the JSON output flag with shell redirection. Execute `ipatool list-purchases --format json > purchased_apps.json` to capture the complete structured output including app IDs, bundle identifiers, names, versions, and purchase dates. For multi-page exports, script multiple calls incrementing the `--page` parameter until the returned count equals `totalCount`.