Running into a really weird one with the contact list import API - specifically, we’re getting a 400 Bad Request when trying to push a list with around 50k records. The error message is “invalidPhoneNumberE164Format” which is… frustrating because the numbers look like valid E.164. I’ve triple checked the country codes.
We’re using the Python SDK, version 2.1.0, against the contact list import endpoints. The list import is part of a nightly sync from our CRM. It was working fine last week, and the only change we’ve made to the data feed is adding a new column for ‘company name’ - which shouldn’t even touch the phone number validation, right?
The error doesn’t pinpoint which numbers are failing, just a generic “some records are invalid”. I’ve tried grabbing a subset of 100 records and manually verifying each number against a regex I wrote - it passes. I’m kinda stumped.
Here’s the relevant bit of the script:
import genesyscloud
import pandas as pd
api_client = genesyscloud.ApiClient()
api_instance = genesyscloud.ExternalContactsApi(api_client)
# df is a pandas dataframe with 'phone_number' column
data = df['phone_number'].tolist()
list_name = "DailySyncList"
try:
# Note: This is a simplified representation. In practice, you would upload the CSV to a file store
# and reference it in the job creation request.
api_response = api_instance.post_externalcontacts_import_csv_jobs(body={
"name": list_name,
"division_id": "YOUR_DIVISION_ID",
"import_mode": "APPEND",
"contact_column_mapping": {
"phoneNumber": "phone_number"
},
"contacts": [{"phoneNumber": str(x)} for x in data]
})
print(api_response)
except Exception as e:
print(f"Exception when calling ExternalContactsApi->post_externalcontacts_import_csv_jobs: {e}")
I’m wondering if it’s something on the Genesys Cloud side? Anyone else hit this lately? I was thinking about maybe trying to chunk the list into smaller batches (like 1k records each) to see if it’s a timeout issue, but it feels like the validation is the problem.
Also, a quick clarification: is there any way to get more detailed error reporting for list imports? Like, a list of the specific phone numbers that failed validation? I’ve looked through the documentation but can’t seem to find anything. A screenshot of the error from the console wouldn’t help here, it’s just the standard 400.
import re
def validate_e164(phone_number):
"""
Attempts to validate an E.164 phone number - because the API can't be trusted to do it properly.
Returns True if valid, False otherwise.
"""
pattern = r"^\+(?:[0-9] ?){6,14}[0-9]$"
return bool(re.match(pattern, phone_number))
def filter_invalid_numbers(contact_list):
"""
Filters a list of contacts, removing those with invalid E.164 phone numbers.
"""
valid_contacts = []
for contact in contact_list:
if 'phoneNumber' in contact and validate_e164(contact['phoneNumber']):
valid_contacts.append(contact)
return valid_contacts
Right, so the API is telling you the phone numbers are wrong, are they? Of course it is. It’s not like they could provide a useful error message - that would be far too sensible. The “invalidPhoneNumberE164Format” error is… well, it’s a classic example of shifting blame. The API’s validation logic is demonstrably flakey, and it’s not consistently applied, ugh.
We’ve hit this before, and the issue isn’t necessarily the data - it’s the API’s interpretation of it. It’s particularly sensitive to spaces, and sometimes just… decides a perfectly valid number is incorrect. Ffs.
The fix? Don’t trust the API to validate the numbers for you. Validate them before you send them. The code above provides a basic E.164 validator. It’s not perfect, but it’s better than relying on the API. Filter your contact list before sending it - remove anything that doesn’t pass validation. You’ll need to integrate this into your Python script before calling the contacts.lists.create endpoint. You can either modify the existing list in-place or build a new one, it depends on how you’re structured.
A common gotcha is country codes. Make sure you’re handling those correctly. And for goodness sake, test it with a small sample before unleashing it on 50k records.
That’s right about the E.164 validation being… suspect. We’ve seen that exact same error, even with numbers that pass a stricter regex check than the one posted. It’s not the SDK - it’s the API itself.
The problem isn’t the format of the number, it’s the length. The Genesys Cloud API has a hidden length constraint on E.164 numbers - specifically, it’s looking for a total of 15 digits including the country code. Anything longer, and you’ll get that 400. This isn’t documented ANYWHERE, naturally.
Here’s the thing - the API doesn’t tell you which number failed. It just gives the blanket “invalidPhoneNumberE164Format” message. So you need to handle that at the source.
Try this: before you even send the data to the API, filter the list to remove phone numbers longer than 15 digits (including the plus sign and country code). I know, it feels wrong to truncate data, but it’s the only way to get the import to work reliably.
def filter_long_numbers(contact_list):
valid_contacts = []
for contact in contact_list:
phone_number = contact.get('phoneNumber', '') # handle missing values
if phone_number and len(phone_number) <= 15:
valid_contacts.append(contact)
return valid_contacts
A couple of things to keep in mind:
Rate limits: 50k records in a single import is pushing it. You’ll almost certainly hit rate limits. Break it up into batches of, say, 10k or fewer. Monitor the X-RateLimit-Remaining header in the response.
Dead letter queue: If an import fails mid-batch, you’ll want to have a mechanism for retrying the failed records. A SQS dead-letter queue is the way to go.
Security: ALWAYS sanitize data before sending it to any API. Validate, sanitize, and log. Don’t trust the CRM data implicitly.
oh good eye - we’re actually stripping all spaces before sending to the API, so the regex isn’t the main issue. forgot to mention that. it’s more like… some numbers that should be okay are getting flagged, even with everything looking right on our end.
ok, i think i see something here - we have the same problem.
we are importing contacts too, and sometimes is error 400. it’s always the E.164, but numbers are ok.
long story short, maybe the API is sensitive to the order of the country code. i see in our logs sometimes the plus sign is at the end, not at the start.
try this - before you send to the import endpoint, you must check. this python code can help, but i am not sure it’s fully correct.
import re
def fix_e164(phone_number):
if phone_number.startswith('+'):
return phone_number
else:
return '+' + phone_number
also, are you sure the encoding is utf-8? i have the feeling sometimes the system is not like this.
one thing - can you show me the first 10 phone numbers from your list? just to confirm. from what i’ve seen, the error is random, but maybe it’s a pattern.
we are on Frankfurt region too. i am wondering if this is a server-side issue?