Public/Invoke-ApiRequest.ps1

function Invoke-APIRequest {
    [CmdletBinding(DefaultParameterSetName = 'None')]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Method,

        [Parameter(Mandatory = $true)]
        [string]$Endpoint,

        [Parameter()]
        $Body,

        [Parameter(ParameterSetName = 'Simple')]
        [string]$Query, # Name of the query parameter

        [Parameter(ParameterSetName = 'Simple')]
        [string]$Filter, # Value for the query parameter

        [Parameter(ParameterSetName = 'Hashtable')]
        [Hashtable]$QueryParameters,  # Hashtable for multiple query parameters

        [Parameter()]
        [ValidateSet('v1', 'v1-beta')]
        [string]$ApiVersion = 'v1'  # API version to use
    )

    try {
        $token = $script:cachedToken

        if (!$token.AccessToken -or $token.Expiry -le (Get-Date)) {
            Write-Warning "Token is missing or expired, retrieving a new one."
            $token = Connect-NMMApi
        }

        $requestHeaders = @{
            'Accept'        = 'application/json'
            'Authorization' = "Bearer $($token.AccessToken)"
        }

        # Initialize URI - support both v1 and v1-beta
        $baseUrl = $token.APIUrl -replace '/rest-api/v1$', ''
        $uri = "$baseUrl/rest-api/$ApiVersion/$Endpoint"

        # Determine how to append query parameters based on method used
        if ($PSCmdlet.ParameterSetName -eq 'Simple' -and $Query -and $Filter) {
            $uri = "$($uri)?$($Query)=$($Filter)"
        }
        elseif ($PSCmdlet.ParameterSetName -eq 'Hashtable' -and $QueryParameters) {
            $queryString = ($QueryParameters.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }) -join "&"
            $uri = "$($uri)?$($queryString)"
        }

        # Execute the API request
        if ($Body) {
            $BodyJSON = $Body | ConvertTo-Json -Depth 10 -ErrorAction Stop
            Write-Verbose "Request body JSON:"
            Write-Verbose $BodyJSON
            $response = Invoke-RestMethod -Uri $uri -Body $BodyJSON -Method $Method -Headers $requestHeaders -ContentType 'application/json'
        }
        else {
            $response = Invoke-RestMethod -Uri $uri -Method $Method -Headers $requestHeaders
        }
        
        return $response

    }
    catch {
        Write-Error "API request failed: $_"
        Write-Verbose "Error details: $($_.Exception.Message)"
        if ($_.Exception.Response) {
            Write-Verbose "Response status code: $($_.Exception.Response.StatusCode)"
            Write-Verbose "Response content: $($_.Exception.Response.Content.ReadAsStringAsync().Result)"
        }
    }
    finally {
        Write-Verbose "Completed API request"
    }
}