400 error when using API to create purchase orders

I am sure this is going to be something simple but I can’t seem to put my finger on it. I am trying to import a list of purchase orders using a powershell script but I keep running into a 400 error. I am not sure if this is due to my formatting or my JSON. Any ideas or help would be greatly appreciated.

$poApiuri = "https://blah.freshservice.com/api/v2/purchase_orders"
$vendorApiUri = "https://blah.freshservice.com/api/v2/vendors"
$vendorApiUriPagination = "page="

$apiKeyFreshservice = "<APIKEY>"
$EncodedCredentials = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $apiKeyFreshservice,$apiKeyFreshservices)))
$HTTPHeaders = @{}
$HTTPHeaders.Add('Authorization', ("Basic {0}" -f $EncodedCredentials))
$HTTPHeaders.Add('Content-Type', 'application/json')

$vendorApiPageNumber = 1
$vendorApiPageSize = "?per_page=50&"

do 
{
    $vendorApiHttpContent = Invoke-WebRequest -Uri ($vendorApiUri + $vendorApiPageSize + $vendorApiUriPagination + $vendorApiPageNumber) -Headers $HTTPHeaders -Method Get
    $allFreshServiceVendors += ($vendorApiHttpContent.Content | ConvertFrom-Json).vendors
    $vendorApiPageNumber++
    if (([int]$vendorApiHttpContent.Headers.'X-Ratelimit-Remaining' -lt 3) -and ($vendorApiHttpContent -notmatch "empty"))
    {
        Write-Output "Rate limite reached: " [int]$httpResponse.Headers.'X-Ratelimit-Remaining' " waiting about 60 seconds..."
        sleep 63
    }
    
} while ($vendorApiHttpContent.Headers.Link -ne $null)

$PoCsv = Import-Csv -Path S:\Path\to\POs.csv

foreach ($record in $PoCsv)
{
    $record.ExpectedDeliveryDate = $record.ExpectedDeliveryDate.Replace("/","-")

    if ($record.VendorEmail -contains "")
    {
        $record.VendorEmail = "No Email"
    }

    $poPrefix = "PO-"
    $poSuffix = 14
    $poNumber = $poPrefix + $poSuffix

    $vendorInfo = $allFreshServiceVendors | where -Property custom_fields -Match $record.VendorNumber
    if ($vendorInfo.custom_fields.munis_vendor_id -notmatch $record.VendorNumber)
    {
        Write-Host "We did not find vendor: " $record.VendorName
        continue
    }

    $record.DiscountPercentage = 0
    $record.ShippingCost = 0

    $PurchaseItems = @{}
    $PurchaseItems.Add('item_type','1') #Mandatory Field
    $PurchaseItems.Add('item_name',$record.ItemName) #Mandatory Field
    $PurchaseItems.Add('description',$record.ItemDescription)
    $PurchaseItems.Add('cost',$record.ItemCost) #Mandatory Field
    $PurchaseItems.Add('quantity',[int]$record.ItemQuantity) #Mandatory Field
    $PurchaseItems.Add('tax_percentage',[int]$record.ItemTaxPercentage) #Mandatory Field

    $Attributes = @{}
    $Attributes.Add('po_number',$poNumber) #Mandatory Field
    $Attributes.Add('vendor_id',$vendorInfo.Id) #Mandatory Field,
    $Attributes.Add('name',$record.OrderName) #Mandatory Field
    $Attributes.Add('vendor_details',$vendorInfo.Name) #Mandatory Field
    $Attributes.Add('shipping_address',$record.ShippingAddress) #Mandatory Field
    $Attributes.Add('billing_address',$record.BillingAddress) #Mandatory Field
    $Attributes.Add('currency_code',$record.CurrencyCode) #Mandatory Field
    $Attributes.Add('work_po_number',$record.WorkPONumber)
    $Attributes.Add('po_link',$record.OrderURL)
    $Attributes.Add('expected_delivery_date',$record.ExpectedDeliveryDate)
    $Attributes.Add('discount_percentage',[int]$record.DiscountPercentage)
    $Attributes.Add('shipping_cost',[decimal]$record.ShippingCost)
    $Attributes.Add('tax_percentage',[int]$record.itemTaxPercentage)
    $Attributes.Add('purchase_items',$PurchaseItems) #An array of objects defined. #Mandatory Field
    $JSON = $Attributes | ConvertTo-Json

    $httpResponse = "empty"
    Invoke-RestMethod -Uri $poApiuri -Headers $HTTPHeaders -Method Post -Body $JSON

    $poSuffix++

    if (([int]$httpResponse.Headers.'X-Ratelimit-Remaining' -lt 3) -and ($httpResponse -notmatch "empty"))
    {
        Write-Output "Rate limite reached: " [int]$httpResponse.Headers.'X-Ratelimit-Remaining' " waiting about 60 seconds..."
        sleep 63 
    }
}

Here is the error message:

Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At S:\path\to\po.csv
Scripts\Freshservice\POImport.ps1.ps1:84 char:5Invoke-RestMethod -Uri $poApiuri -Headers $HTTPHeaders -Method Po …
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Here is a link to a more desirable image of the code:

**EDIT
Also, here is my JSON for uploading

{
    "vendor_id":  919928819,
    "billing_address":  "<Obligatory Address",
    "name":  "Portable vacuums and ladder",
    "discount_percentage":  0,
    "expected_delivery_date":  "2022-12-31",
    "shipping_cost":  0,
    "po_link":  "https://somewebsite.com",
    "po_number":  "PO-14",
    "shipping_address":  "<Obligatory Address>",
    "currency_code":  "1",
    "vendor_details":  "AMAZON MKTPLACE PMTS",
    "tax_percentage":  0,
    "po_number":  "888281",
    "purchase_items":  {
                           "item_name":  "ITEM:  Stealth Multifunction Telescoping Ladder , Aluminum Extension Ladder with 2 Flexible Wheels 17 FT Max , Step Ladder for Working Indoor/Outdoor USAEM4X4L1",
                           "description":  "ITEM:  Stealth Multifunction Telescoping Ladder , Aluminum Extension Ladder with 2 Flexible Wheels 17 FT Max",
                           "cost":  "280",
                           "quantity":  "1",
                           "tax_percentage":  "0",
                           "item_type":  "1"
                       }
}

Thank you in advance!
Zach

Apologies for the delayed response and thanks for your patience.

From code I could see you are trying to create a purchase order. By import you mean creating a new purchase order in Freshservice using Freshservice Purchase order API. In this case the request should be a POST call but in code I can see -Headers $HTTPHeaders -Method Get.

I hope that is the right observation. If so, then changing the header method to Post should resolve the issue.

Regards,
Thakur

I appreciate the response Thakur.

In this particular piece of the code, I am gathering my vendors from FreshService so I can get their vendor ID so I think the get works in this spot.

I appreciate you taking a look!

Turns out my payload was incorrect as there is a field that is required that is not in the api documentation. More specifically, the Item_id.

Also, my payload did not have square brackets around the curly braces. Not sure I have seen that but it works now.

I appreciate everyone looking.