How IPATool Handles Different Response Formats from the App Store
IPATool uses a dual-path parsing strategy that handles both direct JSON responses from standard App Store API endpoints and HTML-embedded JSON payloads from Vision OS storefront pages.
IPATool retrieves app metadata and download links by communicating with Apple's App Store infrastructure. Because Apple serves data through two distinct mechanisms—RESTful JSON endpoints for classic API calls and server-rendered HTML pages for Vision OS search—IPATool implements specialized parsers for each format.
The Two Response Formats IPATool Supports
When interacting with the App Store, IPATool encounters two primary data formats that require different parsing approaches.
Direct JSON Responses (Standard API Endpoints)
Standard App Store operations such as app lookup, version listing, and downloading return pure JSON payloads. Endpoints like /lookup, /listVersions, and /download send responses with Content-Type: application/json that map directly to Go structs.
Embedded JSON in HTML (Vision OS Storefront)
Vision OS search queries return HTML pages containing a serialized JSON script tag. When querying Visual App Store URLs (e.g., https://apps.apple.com/<cc>/vision/search), the response body contains a <script id="serialized-server-data" type="application/json"> element that holds the actual application data. IPATool must extract and parse this embedded JSON before processing.
Parsing Pure JSON Responses from the App Store
For standard API interactions, IPATool unmarshals response bodies directly into strongly-typed Go structures. Each endpoint defines dedicated output structs that mirror Apple's JSON schema:
LookupOutputinpkg/appstore/appstore_lookup.gohandles/lookupresponsesListVersionsOutputinpkg/appstore/appstore_list_versions.gohandles/listVersionsresponsesDownloadOutputinpkg/appstore/appstore_download.gohandles/downloadresponses
The HTTP client wrapper reads the response body and decodes it using Go's standard json package:
var out appstore.LookupOutput
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return err
}
This approach requires no HTML parsing or string manipulation—the JSON maps directly to the struct fields.
Extracting Data from HTML-Wrapped JSON (Vision OS)
Vision OS storefront queries require a specialized extraction pipeline implemented in pkg/appstore/appstore_storefront.go. The process follows four distinct stages:
1. Isolate the Script Tag
The serializedServerData function scans the raw HTML response for the id="serialized-server-data" marker. It locates the opening <script> tag, slices the content between the closing > and </script>, and trims whitespace to isolate the JSON payload.
2. Unmarshal to Internal Structure
The extracted byte slice unmarshals into a storefrontSearchPage struct. This internal structure represents the server-rendered state tree containing shelves, items, and app metadata.
3. Walk the Tree
storefrontVisionApps recursively iterates through page.Data → Shelves → Items, filtering for nodes where the type equals "AppSearchResult" and the object contains a Vision-specific purchase configuration (containsVisionPurchaseConfiguration).
4. Deduplicate and Limit
A map of seen AdamIDs eliminates duplicate applications, and the final result set caps at maxVisionOSSearchResults (12 items) to match App Store behavior.
For specific version identifier lookups, visionExternalVersionID calls the same extractor, then delegates to findVisionExternalVersionID and externalVersionIDFromVisionConfiguration to locate the externalVersionId field within the nested JSON tree.
// Example: Search Vision OS storefront and retrieve up to 5 apps
func FindVisionApps(term, country string) ([]ipatool.App, error) {
// Build the Vision OS search URL
url := visionSearchURL(term, country) // see appstore_storefront.go:43-48
// Perform the GET request (using the shared HTTP client)
body, err := httpGet(url) // abstracted elsewhere
if err != nil {
return nil, err
}
// Parse the embedded JSON and return App structs
return storefrontVisionApps(body, 5) // appstore_storefront.go:69-31
}
Summary
- IPATool handles two distinct response formats from the App Store: direct JSON for standard APIs and HTML-embedded JSON for Vision OS storefronts.
- Pure JSON endpoints (
/lookup,/download,/listVersions) unmarshal directly into structs likeLookupOutputandDownloadOutput. - Vision OS HTML pages require extraction via
serializedServerDatainpkg/appstore/appstore_storefront.gobefore JSON parsing. - The
storefrontVisionAppsfunction walks the decoded tree to filter Vision-compatible apps and deduplicate results byAdamID. - Both parsing paths ultimately populate the shared
Appmodel defined inpkg/appstore/app.go.
Frequently Asked Questions
How does IPATool detect which response format to parse?
IPATool determines the response format based on the endpoint URL and the presence of the serialized-server-data script tag. Standard API calls expect JSON directly, while Vision OS storefront queries explicitly invoke the HTML extraction logic in serializedServerData located at lines 39-66 of pkg/appstore/appstore_storefront.go.
What is the Vision OS storefront format?
The Vision OS storefront returns server-rendered HTML containing a <script id="serialized-server-data" type="application/json"> element. This script tag encapsulates the entire application state as a JSON object, requiring IPATool to extract the inner text before unmarshaling into the storefrontSearchPage structure.
Which Go structs handle App Store JSON responses?
IPATool defines specific output structs for each endpoint: LookupOutput handles app metadata queries, ListVersionsOutput manages version history, and DownloadOutput processes download URL responses. These structs reside in appstore_lookup.go, appstore_list_versions.go, and appstore_download.go respectively.
Why doesn't IPATool always use the JSON API for Vision OS?
Apple serves Vision OS search results exclusively through the Visual App Store web interface, which returns HTML rather than a dedicated JSON endpoint. IPATool must scrape and parse the embedded JSON to access Vision-specific search functionality that isn't exposed through the standard App Store API.
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 →