# How IPATool Searches for visionOS Apps: Technical Implementation Guide

> Discover how IPATool searches for visionOS apps. This technical guide explains its HTML-scraping pipeline, JSON extraction, and iTunes Lookup API integration for complete app metadata.

- Repository: [Majd/ipatool](https://github.com/majd/ipatool)
- Tags: deep-dive
- Published: 2026-08-31

---

**IPATool uses a dedicated HTML-scraping pipeline that queries the Apple Vision Pro storefront directly, extracts app identifiers from embedded serialized JSON, and hydrates them through the iTunes Lookup API to deliver complete app metadata.**

IPATool is an open-source command-line utility developed by `majd` for downloading IPA files from Apple's App Store. While standard iOS and macOS searches utilize Apple's public JSON Search API, the platform requires a specialized workflow to search for visionOS apps because Apple does not expose a public search endpoint for the Vision Pro ecosystem.

## The visionOS Search Architecture

The implementation diverges from standard platform searches through a five-stage pipeline defined in [`pkg/appstore/appstore_search.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_search.go) and [`pkg/appstore/appstore_storefront.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_storefront.go).

### Platform Detection and Routing

When the `Search` method receives a request, it inspects the `Platform` field of the `SearchInput` struct. If the value equals `PlatformVisionOS`—defined in [`pkg/appstore/platform.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/platform.go) as the literal string `"visionos"`—the execution diverts from the standard JSON API path to the visionOS-specific routine.

```go
// Simplified logic from appstore_search.go L32-L34
if input.Platform == PlatformVisionOS {
    return a.searchVisionOS(ctx, input)
}

```

### Scraping the Vision Pro Storefront

Instead of calling the iTunes Search API, IPATool issues a raw HTTP GET request against the visionOS storefront URL. The `visionSearchURL` function constructs the endpoint using the country code and search term, targeting URLs like `https://apps.apple.com/us/vision/search?term=photo+editor`.

Unlike other platforms that return structured JSON, the visionOS storefront responds with **raw HTML**, requiring IPATool to parse the page content to extract application data.

### Extracting App Data from HTML

The HTML response contains a `<script id="serialized-server-data">` tag that embeds a JSON blob with the search results. The `storefrontVisionApps` function in [`pkg/appstore/appstore_storefront.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_storefront.go) (lines 69-75) performs three critical operations:

1. **HTML Parsing**: The `serializedServerData` function locates the script tag by ID and extracts its inner JSON content.
2. **Vision-Specific Filtering**: The `containsVisionPurchaseConfiguration` helper walks the JSON structure, identifying items that carry a `purchaseConfiguration` object with `metricsPlatformDisplayStyle: "vision"` and a valid `appExtVrsId`.
3. **Result Limiting**: The constant `maxVisionOSSearchResults = 12` caps the number of apps processed, preventing oversized pages from overwhelming the CLI interface.

### Metadata Hydration via Lookup API

The storefront extraction yields only minimal app identifiers. To populate complete metadata—including pricing, version numbers, and bundle IDs—the collected app IDs are sent to the standard iTunes Lookup API through the `lookupIDsRequest` method.

This request explicitly uses the `PlatformVisionOS` entity type to ensure the API returns visionOS-compatible app information. The full `App` structs returned replace the minimal stub entries extracted from the HTML, creating the final `SearchOutput` containing the count and fully-hydrated `Results` slice.

## Implementation Details

### Platform Constants and URL Construction

The `PlatformVisionOS` constant is defined in [`pkg/appstore/platform.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/platform.go), mapping the `"visionos"` string to a typed platform value. When constructing requests, the `visionSearchURL` function (lines 43-48 of [`appstore_storefront.go`](https://github.com/majd/ipatool/blob/main/appstore_storefront.go)) formats the storefront URL with the appropriate country code and URL-encoded search terms.

### HTML Parsing and JSON Extraction

The `serializedServerData` function implements defensive parsing logic to handle Apple's server-side rendering. It searches the HTML document for the specific script tag ID, extracts the raw JSON text, and returns trimmed bytes ready for unmarshaling into Go structs.

### Vision-Specific Filtering Logic

Not all items in the storefront HTML represent visionOS applications. The `containsVisionPurchaseConfiguration` function performs deep inspection of each JSON node, specifically looking for:
- A `purchaseConfiguration` object
- A `metricsPlatformDisplayStyle` field set to `"vision"`
- A valid `appExtVrsId` field

Only entries meeting all criteria are included in the final result set.

## Practical Usage Examples

### Searching via CLI

To search for visionOS applications from the command line, specify the `visionos` platform flag:

```bash

# Search the Vision Pro App Store for "photo editor", limiting results to 5

ipatool search --term "photo editor" --platform visionos --limit 5

```

The CLI parses the platform flag into `PlatformVisionOS`, triggers the HTML-scraping workflow, and outputs a formatted table containing the app name, bundle ID, App Store ID, and price.

### Programmatic Search in Go

Developers integrating IPATool as a library can invoke the search programmatically:

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

func main() {
    input := appstore.SearchInput{
        Account:  myAccount,
        Term:     "photo editor",
        Limit:    5,
        Platform: appstore.PlatformVisionOS,
    }

    client := appstore.New()
    out, err := client.Search(input)
    if err != nil {
        log.Fatalf("search failed: %v", err)
    }

    for _, app := range out.Results {
        fmt.Printf("%s (%s) – ID:%d\n", app.Name, app.BundleID, app.ID)
    }
}

```

This snippet executes the same raw-HTML fetch, JSON extraction, and metadata lookup described above, returning a slice of fully-populated `appstore.App` structs ready for further processing.

## Summary

- **Platform Branching**: IPATool detects visionOS requests via the `PlatformVisionOS` constant and routes to a specialized handler in [`appstore_search.go`](https://github.com/majd/ipatool/blob/main/appstore_search.go).
- **HTML Scraping**: The tool queries `apps.apple.com` vision storefronts directly and parses the HTML response instead of using JSON APIs.
- **JSON Extraction**: App identifiers are extracted from the `serialized-server-data` script tag, with filtering logic that validates visionOS compatibility through purchase configuration metadata.
- **Result Hydration**: Raw app IDs are enriched using the standard iTunes Lookup API with visionOS entity parameters to provide complete metadata.
- **Safety Limits**: The search caps results at 12 applications via `maxVisionOSSearchResults` to ensure CLI responsiveness.

## Frequently Asked Questions

### Why does IPATool use HTML scraping for visionOS instead of the standard Search API?

Apple does not expose a public JSON Search API endpoint for visionOS equivalent to the iOS or macOS interfaces. According to the `majd/ipatool` source code, the visionOS App Store storefront only returns server-rendered HTML containing embedded JSON data, necessitating the `storefrontVisionApps` parsing logic in [`pkg/appstore/appstore_storefront.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_storefront.go).

### How does IPATool distinguish between visionOS apps and other platforms in the search results?

The implementation uses the `containsVisionPurchaseConfiguration` function to inspect each candidate's JSON structure. It specifically checks for a `purchaseConfiguration` object containing `metricsPlatformDisplayStyle: "vision"` and a valid `appExtVrsId`, ensuring only applications explicitly configured for Apple Vision Pro are included in the final output.

### What is the maximum number of visionOS apps IPATool can return in a single search?

The codebase defines `maxVisionOSSearchResults = 12` in [`pkg/appstore/appstore_storefront.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_storefront.go). This constant limits the parser to process only the first 12 valid visionOS applications found in the storefront HTML, preventing memory overhead and maintaining CLI performance when handling large result pages.

### Can I use IPATool to download visionOS apps after searching?

Yes. Once the search returns valid `App` structs containing bundle IDs and App Store identifiers, you can use IPATool's standard download command with the `--platform visionos` flag. The search ensures the apps are compatible with visionOS by verifying the purchase configuration metadata before the download process begins.