# How IPATool Handles Different Response Formats from the App Store

> Discover how IPATool adeptly parses diverse App Store response formats including direct JSON and HTML-embedded JSON from Vision OS storefronts. Optimize your app data retrieval.

- Repository: [Majd/ipatool](https://github.com/majd/ipatool)
- Tags: internals
- Published: 2026-09-06

---

**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:

- `LookupOutput` in [`pkg/appstore/appstore_lookup.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_lookup.go) handles `/lookup` responses
- `ListVersionsOutput` in [`pkg/appstore/appstore_list_versions.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_list_versions.go) handles `/listVersions` responses  
- `DownloadOutput` in [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go) handles `/download` responses

The HTTP client wrapper reads the response body and decodes it using Go's standard `json` package:

```go
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`](https://github.com/majd/ipatool/blob/main/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 `AdamID`s 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.

```go
// 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 like `LookupOutput` and `DownloadOutput`.
- **Vision OS HTML pages** require extraction via `serializedServerData` in [`pkg/appstore/appstore_storefront.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_storefront.go) before JSON parsing.
- The `storefrontVisionApps` function walks the decoded tree to filter Vision-compatible apps and deduplicate results by `AdamID`.
- Both parsing paths ultimately populate the shared `App` model defined in [`pkg/appstore/app.go`](https://github.com/majd/ipatool/blob/main/pkg/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`](https://github.com/majd/ipatool/blob/main/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`](https://github.com/majd/ipatool/blob/main/appstore_lookup.go), [`appstore_list_versions.go`](https://github.com/majd/ipatool/blob/main/appstore_list_versions.go), and [`appstore_download.go`](https://github.com/majd/ipatool/blob/main/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.