POST /api/v2/outbound/contactlists throws 400 INVALID_VALUE for valid CSV format

POST /api/v2/outbound/contactlists

Status: 400 Bad Request

{
“code”: “invalid_value”,
“message”: “Invalid input”,
“details”: [
{
“code”: “invalid_value”,
“message”: “Column ‘email_address’ is required but not found in the provided data”,
“path”:
}
]
}

I’ve been staring at this response for an hour. The error claims email_address is missing, but the JSON body I’m sending explicitly includes it. I’m using the Kotlin khttp library to make the request from our backend service. The header setup looks standard: Content-Type: application/json, Accept: application/json, and a valid OAuth bearer token. I’ve verified the token works fine with GET requests to /api/v2/outbound/contactlists.

Here’s the request body:

{
 "name": "Test_List_001",
 "description": "Automated import test",
 "contactListType": "CUSTOM",
 "data": {
 "email_address": "john.doe@example.com",
 "first_name": "John",
 "last_name": "Doe"
 },
 "dataFormat": "JSON"
}

I’ve tried switching dataFormat to CSV and formatting the data field as a string with headers, but the same invalid_value error persists. The docs for the Contact Lists API are a bit sparse on the exact structure expected for the data object when creating a list via API versus uploading a file. I assumed inline JSON data would work since the endpoint accepts it, but maybe the data field needs to be a URL to a file instead? Or perhaps the column mapping in the name field needs to match specific internal identifiers?

I’ve checked the contactListType and it’s set to CUSTOM as required. I’ve also tried removing the description field just in case, no change. The email_address key matches the example in the developer docs exactly. I’m wondering if there’s a validation step happening server-side that’s failing silently or if I’m missing a required nested object for column definitions. Anyone hit this specific invalid_value on contact list creation recently?

The API is strict about the exact column header mapping for email_address. You can’t just use “Email” or “email” in your CSV headers. It has to match the schema definition exactly. Here’s a minimal valid payload structure using the import action which handles the CSV data correctly:

{
 "name": "Test List",
 "description": "Testing email validation",
 "contactLists": [],
 "import": {
 "contactListName": "Test List",
 "delimiter": ",",
 "encoding": "UTF-8",
 "headerRow": true,
 "data": "first_name,last_name,email_address\nJohn,Doe,john.doe@example.com"
 }
}

Make sure the data field contains the raw CSV string with email_address as the third header. If you’re uploading a file instead, ensure the file itself has that exact header. The 400 error isn’t about the CSV format being broken, it’s about the schema validation failing on that specific key. Check your file encoding too, sometimes BOM characters at the start of UTF-8 files trip up the parser.