# How to List Owned Purchases Using IPATool: CLI and Go Guide

> Learn how to list owned purchases using IPATool CLI and Go. This guide explains how to query private DAAP endpoints to retrieve paginated app lists for your account.

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

---

**IPATool stores Apple App Store credentials in a local keychain and exposes a `list-purchases` command that queries private DAAP endpoints to retrieve paginated lists of apps owned by the authenticated account.**

The `majd/ipatool` repository provides a command-line interface for interacting with the Apple App Store. After authenticating with `ipatool auth login`, you can list owned purchases using IPATool to view all apps associated with your Apple ID. This functionality abstracts the complex DAAP protocol and SAP signing process behind a simple interface.

## Understanding the list-purchases Implementation

### Command Layer in cmd/purchases.go

According to the source code in [`cmd/purchases.go`](https://github.com/majd/ipatool/blob/main/cmd/purchases.go), the `list-purchases` command implements a five-step workflow. First, it **validates flags** to ensure the requested page number and maximum results per page fall within the allowed range (≥ 1 and ≤ `appstore.MaxOwnedAppsLimit` of 100).

The command then calls `AppStore.AccountInfo()` to retrieve the current Apple ID, password token, and other required authentication fields. If the stored password token has expired, the implementation automatically re-authenticates using the stored email and password before proceeding.

### Core Logic in appstore_owned_apps.go

The actual data retrieval occurs in [`pkg/appstore/appstore_owned_apps.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go) through the `AppStore.OwnedApps()` method. This function communicates with private "purchase" DAAP endpoints, signs requests using a **SAP action signer**, parses the **DMAP response**, and returns a paginated slice of `App` objects sorted by purchase date. Each `App` object contains the ID, bundle ID, name, version, and purchase date.

## How to List Owned Purchases Using the IPATool CLI

Before retrieving your purchase history, authenticate once per machine:

```bash
ipatool auth login

```

Execute the list-purchases command with optional pagination controls:

```bash

# Default: first page with 10 results per page

ipatool list-purchases

# Request a specific page with custom page size (max 100)

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

# Output structured JSON for scripting

ipatool list-purchases --format json

```

The CLI validates that your `--max-results` value does not exceed 100 and logs the total count, page information, and app details (ID, bundle ID, name, version, purchase date) through the built-in logger.

## Programmatic Usage in Go

You can also list owned purchases using IPATool as a Go library. Import the `appstore` package and use the `OwnedAppsInput` struct to configure pagination:

```go
import (
    "github.com/majd/ipatool/v2/pkg/appstore"
)

func example() error {
    // Assume you have a configured *appstore.AppStore instance
    client := /* obtain client */

    // Retrieve account info (may trigger automatic re-authentication)
    info, err := client.AccountInfo()
    if err != nil {
        return err
    }

    // List owned apps with pagination parameters
    out, err := client.OwnedApps(appstore.OwnedAppsInput{
        Account: info.Account,
        Page:    1,
        Limit:   10,
    })
    if err != nil {
        return err
    }

    for _, app := range out.Results {
        fmt.Printf("%d – %s (%s) purchased on %s\n",
            app.ID, app.Name, app.BundleID, app.PurchaseDate.Format(time.RFC3339))
    }
    return nil
}

```

## Summary

- IPATool stores Apple App Store credentials locally in the system keychain and handles the DAAP protocol complexity internally
- The `list-purchases` command validates pagination parameters against `appstore.MaxOwnedAppsLimit` (100) before querying
- Source files [`cmd/purchases.go`](https://github.com/majd/ipatool/blob/main/cmd/purchases.go) and [`pkg/appstore/appstore_owned_apps.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go) handle the CLI interface and core retrieval logic respectively
- Automatic token refresh occurs when stored credentials expire during the `AccountInfo()` retrieval phase
- Both CLI and Go API return structured data including app ID, bundle ID, name, version, and purchase date sorted chronologically

## Frequently Asked Questions

### What authentication is required before listing owned purchases?

You must run `ipatool auth login` at least once to store your Apple ID credentials in the local keychain. When you subsequently run `list-purchases`, the command retrieves these credentials automatically via `AppStore.AccountInfo()` and handles token refresh if the password token has expired.

### What is the maximum number of owned apps I can retrieve per request?

According to the source code constant `appstore.MaxOwnedAppsLimit`, the maximum is 100 results per page. The CLI in [`cmd/purchases.go`](https://github.com/majd/ipatool/blob/main/cmd/purchases.go) validates that your `--max-results` flag falls between 1 and 100 before executing the query.

### How does IPATool communicate with Apple's servers to fetch purchase history?

The tool uses the `AppStore.OwnedApps()` method which communicates with private "purchase" DAAP endpoints. It signs requests using a SAP action signer, parses DMAP responses, and returns sorted `App` objects containing metadata like bundle ID and purchase date.

### Can I use IPATool as a library in my own Go applications?

Yes. Import `github.com/majd/ipatool/v2/pkg/appstore` and create an `OwnedAppsInput` struct with your account details, page number, and limit. Call `client.OwnedApps()` to receive paginated results without manually managing the DAAP protocol or SAP request signing.