To import a batch file into Sitecore CDP using the Batch API, these are the steps
  1. Create a batch file following the correct format
      1. No "Insert" is support, only "Upsert"!
    1. The file itself is not a valid JSON! It's multiple JSON in a single file, each JSON content are on a single line!
  2. "gzip" the batch file
    1. On Windows, can just use 7zip
    2. Or the PowerShell scripts below
  3. Get MD5 checksum and the file size in byte
    1. Use the PowerShell scripts below
  4. Batch API call: Create the batch and get the AWS upload URL using the Batch API
    1. PUT method
    2. Generate a new UUID for identifying your import and use this UUID on your API call: https://api.boxever.com/v2/batches/[[Your UUID]]
    3. Use your api key and secret in basic authentication as username and password
    4. MD5 checksum value should be lower case!
  5. Get base64 string of the MD5 checksum from HEX value
    1. Use the PowerShell scripts below
  6. AWS API call: Upload the gzip file to AWS upload URL
    1. Headers:
      1. Content-Md5: use the value from the previous step
      2. x-amz-server-side-encryption: AES256
  7. Batch API call: Check the status of the batch import process
  8. View error logs if the import failed
    1. Open the link in browser, it downloads as "gz" file. Unzip and can check individual errors
    2. Common Errors
      1. {"ref":"1e20d1e1-07f0-4863-92f1-4d2e15c86a59","code":"400","message":"Not enough identifying information"}
        1. Enough fields must be provided so the customer can be identified
      2. {"ref":"null","code":"400","message":"Failed to parse import line"}
        1. Ensure that one JSON is flatted out in a single line, do not beautify the JSON!
      3. If the batch status says corrupted, ensure that MD5 checksum is correct and lower case!

Below is a PowerShell Scripts that
  1. Generates a new UUID
  2. "gzip" the batch file
  3. Outputs the file size of the gzip file in bytes
  4. Outputs the lower case version of the MD5 checksum of the gzip file
  5. Outputs the base64 value from the HEX value of the MD5 checksum

[CmdletBinding()]
param (
    [string]
    $filePath
)
Function Gzip-File([ValidateScript({ Test-Path $_ })][string]$File) {
    $srcFile = Get-Item -Path $File
    $newFileName = "$($srcFile.FullName).gz"
    try {
        $srcFileStream = New-Object System.IO.FileStream($srcFile.FullName, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read))
        $dstFileStream = New-Object System.IO.FileStream($newFileName, ([IO.FileMode]::Create), ([IO.FileAccess]::Write), ([IO.FileShare]::None))
        $gzip = New-Object System.IO.Compression.GZipStream($dstFileStream, [System.IO.Compression.CompressionMode]::Compress)
        $srcFileStream.CopyTo($gzip)
    } 
    catch {
        Write-Host "$_.Exception.Message" -ForegroundColor Red
    }
    finally {
        $gzip.Dispose()
        $srcFileStream.Dispose()
        $dstFileStream.Dispose()
    }
}
Write-Host "UUID: " -ForegroundColor Green
(New-Guid).Guid
Gzip-File $filePath
$gfilePath = $filePath + ".gz"
Write-Host "File Size: " -ForegroundColor Green
(Get-Item $gfilePath ).length
$md5 = Get-FileHash -Path $gfilePath -Algorithm MD5
$hash = $md5.Hash.ToLower()
Write-Host "MD5 Hash: " -ForegroundColor Green
$hash
$bytes = [byte[]] -split ($hash -replace '..', '0x$& ')
Write-Host "Content-Md5: " -ForegroundColor Green
[System.Convert]::ToBase64String($bytes)

Save above as PrepBatch.ps1 and invoke like:
.\PrepBatch.ps1 .\input.batch

With the values generated, you can use them with tools like Postman to send all requests.