Private/Invoke-StoreAPI.ps1

function Invoke-StoreAPI {
    <#
    .SYNOPSIS
        Posts a request to the store.rg-adguard.net API and returns raw HTML.
    .PARAMETER Type
        The lookup type: URL, ProductId, PackageFamilyName, or CategoryID.
    .PARAMETER Data
        The value to look up (a URL, product ID, package family name, or category ID).
    .PARAMETER Channel
        The release ring: Retail, RP (Release Preview), WIS (Slow), or WIF (Fast).
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)]
        [ValidateSet('URL', 'ProductId', 'PackageFamilyName', 'CategoryID')]
        [string]$Type,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Data,

        [Parameter(Mandatory)]
        [ValidateSet('Retail', 'RP', 'WIS', 'WIF')]
        [string]$Channel
    )

    $apiUrl = 'https://store.rg-adguard.net/api/GetFiles'

    # Build form body manually for 5.1 compatibility (-Form doesn't exist on 5.1).
    $body = "type=$Type&url=$([System.Uri]::EscapeDataString($Data))&ring=$Channel&lang=en-US"

    $headers = @{
        'User-Agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36'
        'Origin'     = 'https://store.rg-adguard.net'
        'Referer'    = 'https://store.rg-adguard.net/'
    }

    $requestParams = @{
        Uri             = $apiUrl
        Method          = 'Post'
        ContentType     = 'application/x-www-form-urlencoded'
        Headers         = $headers
        Body            = $body
        UseBasicParsing = $true
        TimeoutSec      = 30
        ErrorAction     = 'Stop'
    }

    try {
        Write-Verbose "POST $apiUrl | type=$Type url=$Data ring=$Channel"
        $response = Invoke-WebRequest @requestParams
    } catch [System.Net.WebException] {
        $status = $null
        if ($_.Exception.Response) {
            $status = [int]$_.Exception.Response.StatusCode
        }
        $msg = "Network error calling store API"
        if ($status) { $msg += " (HTTP $status)" }
        $msg += ": $($_.Exception.Message)"
        throw [System.InvalidOperationException]::new($msg, $_.Exception)
    } catch [Microsoft.PowerShell.Commands.HttpResponseException] {
        $status = [int]$_.Exception.Response.StatusCode
        throw [System.InvalidOperationException]::new(
            "Store API returned HTTP ${status}: $($_.Exception.Message)",
            $_.Exception
        )
    } catch {
        throw [System.InvalidOperationException]::new(
            "Unexpected error calling store API: $($_.Exception.Message)",
            $_.Exception
        )
    }

    $html = $response.Content

    if ([string]::IsNullOrWhiteSpace($html)) {
        throw [System.InvalidOperationException]::new(
            'Store API returned an empty response body.'
        )
    }

    # The API returns errors as HTML content, not HTTP status codes.
    if ($html -match '<p[^>]*>\s*The links were not found') {
        throw [System.InvalidOperationException]::new(
            "No packages found for $Type '$Data' on the $Channel ring."
        )
    }

    if ($html -match '<p[^>]*>\s*An error occurred') {
        throw [System.InvalidOperationException]::new(
            "The store API returned an error for $Type '$Data'. The service may be temporarily unavailable."
        )
    }

    return $html
}