Would love it if Rest V2 had an createWithDupeCheck (upsert) functionality so I didn’t have to bother with v1.
When retrieve a contact via V1 endpoint, I get the following for a billing address: [ “line1” => “542 S. MAIN CT”, “line2” => “”, “locality” => “Anaheim”, “region” => “CA”, “field” => “BILLING”, “postal_code” => “92808”, “zip_code” => “92808”, “zip_four” => null, “country_code” => “USA”, ]
I want to create (or update) a related contact at the same address. So I create the contact payload, and keep the address the same, and make my PUT request to /v1/contacts with:
This results in a 400 Bad Request with the response: {“message”:“BILLING Region is invalid”}
I am returning the EXACT region that was provided. No modifications.
When I use the V2 endpoint to create a new contact, I can use the exact same data and it works just fine. But now I am making two calls: #1 check if a contact exists, #2 create the contact OR #2 update the contact.
Ah. I will have to test it out then. Strange that the contacts end point return a value that is not accept on a post request. I feel like the GET shouldn’t return “CA” and “USA” if it isn’t allowed on a POST/PUT.
@OmarAlmonte If the expected behavior for that endpoint is to validate the input against a list of acceptable values, is it also expected behavior that a GET request for the same object would return an invalid value for that property?
Classic UI and XML-RPC allow free-text regions with no standardization, so you can retrieve a region value that isn’t actually valid per V1’s supported region list. When you later do a PUT /v1/contacts, V1 enforces validation and rejects it with “BILLING Region is invalid”, even if you’re sending back the exact same value.
If the address was originally created via the REST APIs or the new UI, the region would have been validated up front and you could safely reuse the value returned by GET in POST/PUT/PATCH.
@OmarAlmonte Additionally, the Keap UI doesn’t enforce these validation rules (e.g. in the UI, State/Region is an input that accepts any arbitrary string). I can appreciate the situation with XML, but the inconsistency across “current” contact update/create mechanisms is a problem that should be addressed. And even if this weren’t the case and the UI enforced a consistent set of rules, being unable to trust the values returned from the GET endpoint in a subsequent create/update is problematic and should receive scrutiny at Keap.
@Todd_Stoker@Timothy_Withers That’s the classic UI, and like I mentioned, if a contact was originally created via XML-RPC or in the Classic UI, there’s no field validation. In the new UI and REST APIs, field validation does exist. I can bring this up to the team so they can take a look, but mapping these values on our end can be tricky since those fields could contain any string. for example, we can’t automatically map “The moon” (like in your example) to a real region.
Sorry, I missed the detail regarding the Classic UI. This detail adds additional complexity. And third-party developers also cannot automatically map “The moon” to a real region. It’s a problem because actual, real-world customer data includes variations of real states/regions (like misspellings and abbreviations).
Ok, we might be off in our tests, because we were getting inconsistent behavior and perhaps we weren’t tracking classic vs new…anyway, I’d like to make sure I’ve grokked this so we can validate:
No validation for region/state and country:
Classic UI
XML, any operation
Validates region/state and country:
New UI
v1/contacts PUT, POST, PATCH
v2/contacts POST, PATCH (and PUT if/when available?)
Hey Omar, sorry to keep harping on this. We spent the better part of a few hours testing V1 and V2 addresses. Here are our findings we would like you to validate:
v1 GET contact:
Address contains keys country_code and region
country_code is either
the ISO 3166-1 alpha 3 code (“USA” for “United States”, “MEX” for “Mexico”, etc)
empty
region is either:
the proper name for the state/region (“Arizona”, “California”, etc)
some random string that was saved in the contact record
region is never returned as the ISO 3166-2 code
v1 POST/PATCH contact:
country_code must be a valid ISO 3166-1 alpha 3 code
If invalid, error is thrown.
region must be a valid ISO 3166-2 code that matches the country_code OR the proper name for the state/region.
If I use the 3166-2 code (“US-CA”), it will show the proper name in app (“California”)
If invalid, error is thrown.
If contact doesn’t have a country_code, error is thrown
V2 GET contact:
Address contains keys 1 or more of the following:
region
region_code
country
country_code
country_code and region_code are only shown when they are valid ISO 3166 representations (“USA”, “US-AZ”)
country is the proper country name, and is only shown when country_code is present
region could be anything
If region_code is set, then it is the proper name of the region
If region_code is not set, then it will be whatever is entered
V2 POST/PATCH contact:
If country_code is passed, it must be a valid ISO 3166-1 alpha 3 code
If country_code is invalid, and error is thrown
If country and country_code is passed, country is ignored as long as the country_code is valid.
country is updated to the proper country name.
If country alone is passed, country_code and country are deleted from the contact record.
No error is thrown.
If region_code is passed, it must be a valid region_code belonging to a valid country_code
If invalid, an error is thrown
If region_code and region is passed, region is ignored as long as the region_code is valid.
region is updated to the proper region name.
If region alone is passed:
If country_code is set and valid:
If region is a proper region name (“Arizona”)
region_code is updated to the correct ISO-3166-2 code (“US-AZ”)
If region is a valid ISO 3166-2 code
region is set to the proper region name
region_code is set to the ISO 3166-2 code
If region is not a proper region name, and region is not a valid ISO 3166-2 code:
region is set to the value entered
region_code is deleted (if it was set)
If country_code is not set, region is set to whatever value is entered
V2 feels a bit more lenient as far as regions go. But it is worrisome that any update to country without country_code deletes the country code and country entirely, rather than simply ignoring it or throwing an error.
The takeaway that I am sensing is that country_code will always be a valid/safe ISO 3166-1 alpha 3 code if it is set, where as region is a bag of mysteries.
Thanks for the detailed breakdown. As long as valid ISO codes are used, everything will remain consistent. I see your concern with countries being removed if country_code isn’t provided, I’ll circle this back with the team and get back to you.
@OmarAlmonte For clarity about why this is problematic: we’re trying to migrate production applications, so weird behavior like this is extremely painful – it takes hours to troubleshoot and diagnose. All the while, users of our applications suffer. Stuff like this might seem small, but it has an enormous impact on a production application.