How to List App Versions Using IPATool: CLI and Programmatic Guide
IPATool provides a dedicated list-versions command that queries Apple's private App Store API to retrieve all available versions of a specific iOS app using either an Apple-assigned numeric ID or a bundle identifier.
IPATool is an open-source command-line utility for interacting with the App Store programmatically. Whether you need to audit version history, verify available releases for downgrading, or automate app management workflows, understanding how to list app versions using IPATool gives you direct access to Apple's version metadata through both terminal commands and Go library interfaces.
Understanding the list-versions Command Structure
The list-versions command is defined in cmd/list_versions.go and serves as the primary interface for version discovery. According to the majd/ipatool source code, the command accepts two mutually exclusive identification methods for targeting the desired application.
Required Parameters
You must provide exactly one of the following flags:
--app-id– The numeric Apple-assigned application identifier (e.g.,123456789)--bundle-identifier– The human-readable bundle ID string (e.g.,com.example.myapp)
When you supply a bundle identifier, the command automatically performs an app lookup via AppStore.Lookup in pkg/appstore/app.go to resolve it to the internal numeric ID before proceeding with the version query.
Authentication Flow and Automatic Retry Logic
Before executing the version request, the command fetches stored account information through dependencies.AppStore.AccountInfo(). If the authentication token has expired, the system automatically initiates a fresh login via dependencies.AppStore.Login.
The entire operation is wrapped in a retry block utilizing github.com/avast/retry-go. If the API returns ErrPasswordTokenExpired or a "sign-in required" error—as defined in pkg/appstore/error.go—the client automatically re-authenticates and retries the request once, ensuring seamless execution without manual token refresh.
Internal Implementation of Version Retrieval
The core version retrieval logic resides in pkg/appstore/appstore_list_versions.go. When you execute the command, the following sequence occurs:
-
Machine Identification – The system retrieves the host's MAC address via
machine.MacAddress()and converts it to an uppercase, colon-less GUID string for device identification. -
Request Construction – The
listVersionsRequestfunction builds a POST request targeting Apple's private API endpoint (https://<pod-prefix>itunes.apple.com/...). -
Payload Assembly – The request body includes:
- The generated GUID
- The app's
salableAdamId(Apple's internal app identifier) - A dummy serial number for device verification
-
API Communication – The HTTP client defined in
pkg/http/client.gotransmits the authenticated request and parses the response. -
Result Extraction – Upon success, the command extracts
ExternalVersionIdentifiers(the complete array of version IDs) andLatestExternalVersionID(the most current release).
Practical Usage Examples
CLI Usage
Execute version lookups directly from your terminal using the following patterns:
# List versions by Apple-assigned app ID
ipatool list-versions --app-id 123456789
# List versions by bundle identifier (overrides --app-id if both provided)
ipatool list-versions --bundle-identifier com.example.myapp
Programmatic Usage with Go
You can integrate version listing directly into Go applications by importing the appstore package:
import (
"fmt"
"github.com/majd/ipatool/v2/pkg/appstore"
"github.com/majd/ipatool/v2/pkg/util/must"
)
func listAppVersions(acc appstore.Account, appID int64) {
// Build the input struct with account and app details
input := appstore.ListVersionsInput{
Account: acc,
App: appstore.App{ID: appID},
}
// Execute the version query
out, err := appstore.New().ListVersions(input)
must.NoError(err)
// Access version data from the output struct
fmt.Println("Available versions:", out.ExternalVersionIdentifiers)
fmt.Println("Latest version:", out.LatestExternalVersionID)
}
Key Source Files and Architecture
Understanding the following files helps when customizing or debugging version retrieval:
cmd/list_versions.go– Cobra command definition, flag parsing, and retry orchestrationpkg/appstore/appstore_list_versions.go– Core implementation handling request construction and API communicationpkg/appstore/app.go–Appstruct definition used for passing application identifierspkg/appstore/account.go– Account credentials and App Store pod information managementpkg/appstore/error.go– Error type definitions includingErrPasswordTokenExpiredpkg/http/client.go– HTTP client implementation for authenticated requests
Summary
- Use the
list-versionscommand with either--app-id(numeric) or--bundle-identifier(string) to target specific applications - Authentication is handled automatically with built-in retry logic that refreshes expired tokens via
github.com/avast/retry-go - The core API interaction is implemented in
pkg/appstore/appstore_list_versions.go, which constructs authenticated POST requests to Apple's private endpoints - Successful execution returns
ExternalVersionIdentifiers(all available versions) andLatestExternalVersionID(current release) - The tool converts your machine's MAC address into a GUID for device identification during API requests
Frequently Asked Questions
What is the difference between --app-id and --bundle-identifier?
The --app-id flag accepts the numeric identifier assigned by Apple (visible in App Store URLs), while --bundle-identifier accepts the reverse-domain string (e.g., com.company.appname). If you provide both flags, the bundle identifier takes precedence and the system performs an intermediate lookup to resolve the numeric ID.
How does IPATool handle expired authentication tokens?
The command implements automatic retry logic that catches ErrPasswordTokenExpired errors from pkg/appstore/error.go. When detected, the system performs a fresh login using stored credentials and retries the version request once without requiring manual intervention.
Can I use IPATool as a Go library instead of CLI?
Yes. Import github.com/majd/ipatool/v2/pkg/appstore and construct a ListVersionsInput struct containing your Account and App objects. Call appstore.New().ListVersions(input) to receive a struct containing ExternalVersionIdentifiers and LatestExternalVersionID.
What information does the list-versions command return?
The command returns an array of ExternalVersionIdentifiers representing all historical version IDs available for the application, plus LatestExternalVersionID indicating the most current version number assigned by Apple.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →