How Does ipatool list-versions and get-version-metadata Expose Version History?

The ipatool commands retrieve an app's complete version history from the Apple App Store by calling two distinct private endpoints—/listVersions for enumerating all releases and /lookup for drilling into specific version details—then presenting the data as formatted tables or structured JSON/YAML output.

Version history inspection is essential for security researchers, QA engineers, and developers who need to compare app builds, audit release timelines, or obtain historic IPAs for regression testing. The majd/ipatool open-source project implements this through a clean separation between CLI handling in cmd/ and App Store communication in pkg/appstore/. Below is a complete technical breakdown of how both commands function end-to-end.

Architecture Overview

ipatool delegates version history retrieval to four cooperating components:

Component Source File Responsibility
list-versions CLI command /cmd/list_versions.go Parses arguments, invokes client, renders output
listVersions client method /pkg/appstore/appstore_list_versions.go HTTP request to /listVersions endpoint
get-version-metadata CLI command /cmd/get_version_metadata.go Accepts version identifier, invokes detailed lookup
getVersionMetadata client method /pkg/appstore/appstore_get_version_metadata.go HTTP request to /lookup endpoint with version parameter

Both commands share common infrastructure for authentication, storefront selection, and output formatting defined in /pkg/appstore/appstore.go and /cmd/common.go.

How list-versions Enumerates All Releases

Request Construction and Authentication

When you execute ipatool list-versions, the command handler in /cmd/list_versions.go validates the --app flag (bundle identifier) and retrieves stored credentials. It then calls listVersionsRequest(account, app, guid) from /pkg/appstore/appstore_list_versions.go.

This helper constructs an HTTP request to Apple's private /listVersions endpoint with the following elements:

  • Authentication token — Retrieved from the persistent login session and injected into request headers
  • Storefront ID — Determined by the user's country/region to ensure correct regional catalog data
  • Device GUID — A generated identifier consistent with Apple's expected client fingerprinting

Response Parsing and Data Model

The endpoint returns a JSON payload that ipatool unmarshals into a slice of VersionInfo structs. Each element contains:

Field Description
VersionString Semantic version (e.g., "2.3.1")
ReleaseDate ISO 8601 timestamp of App Store publication
BuildNumber Internal build identifier

The CLI then passes this slice to the shared output formatter in /cmd/common.go, which respects the --output flag (table, json, or yaml).


# Default table output showing all versions

ipatool list-versions --app com.example.myapp

# Machine-readable output for scripting

ipatool list-versions --app com.example.myapp --output json

How get-version-metadata Retrieves Detailed Information

Targeted Lookup by Version Identifier

The get-version-metadata command serves a different purpose: obtaining comprehensive metadata for a specific release. Located in /cmd/get_version_metadata.go, this handler requires both --app and --version flags.

The underlying getVersionMetadataRequest(acc, app, guid, version) function in /pkg/appstore/appstore_get_version_metadata.go targets the /lookup endpoint with an additional version query parameter. This endpoint returns richer information than the list endpoint, including binary size, code signing details, and localized release notes.

Extended Metadata Structure

The response unmarshals into a VersionMetadata struct with these representative fields:

Field Category Examples
Identification VersionString, BuildNumber, BundleID
Timing ReleaseDate, CurrentVersionReleaseDate
Binary properties FileSizeBytes, MinimumOSVersion
Distribution DownloadURL (when available), Signature
Localization ReleaseNotes (per-language)

Command Usage


# Full metadata dump as formatted table

ipatool get-version-metadata --app com.example.myapp --version 2.3.1

# Parseable output for CI pipelines

ipatool get-version-metadata --app com.example.myapp \
    --version 2.3.1 --output json

Shared Infrastructure and Error Handling

Both commands rely on common patterns implemented across the codebase:

  • Authentication flow — If no valid session exists, both commands will fail with a clear error directing the user to run ipatool login first
  • Storefront resolution — Automatically derived from system locale, overridable via flags in /pkg/appstore/appstore.go
  • Request signing — Apple's private APIs require specific header combinations that the client handles transparently
  • Pagination handling — The listVersions implementation manages large version histories through automatic pagination requests

Error conditions handled explicitly include:

  • App not found (invalid bundle identifier)
  • Version not found (requested version never released for that app/region)
  • Authentication expired (401 responses trigger re-login prompts)
  • Regional availability (versions may differ by storefront)

Summary

Frequently Asked Questions

What versions are available for inspection?

Any version that was publicly released to the App Store for the specified storefront (country/region). Delisted or pulled versions may still appear in historical data depending on Apple's retention policies.

Can I download old versions directly with these commands?

No. The list-versions and get-version-metadata commands are read-only inspection tools. Actual IPA download requires separate ipatool commands that must negotiate download entitlements with Apple's servers.

Why does the same app show different versions in different regions?

Apple permits phased rollouts and regional staggered releases. The storefront ID sent with each request filters the catalog to that region's currently available history, as implemented in the shared client infrastructure in /pkg/appstore/appstore.go.

How does ipatool authenticate without exposing passwords?

Credentials are collected once via ipatool login, exchanged for a time-limited authentication token with Apple ID servers, then stored in the system keychain. Subsequent commands retrieve this token transparently, never handling raw passwords.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →