Hey mtwsf,
good question. I had problems with this as well. Since Customer.io is using JSON to store data, I am pretty sure you will have to use downcase in order to tell Customer.io that it is a boolean input:
https://customer.io/docs/journeys/getting-started-with-json/#simple
Automatically changed values like the “unsubscribed” attribute also uses downcase “true” and “false” btw.
If your API calls are using a different way, e.g. “TRUE” I would consider to change that tbh.
Hope that helps,
Felix
Hmm, seems there may be an issue or bug with either the CIO API or how it is displaying data back. I am sending true as a boolean via API but it’s turning it into a string. Should this be a bug report?
POST API request through Data Pipelines to: https://cdp.customer.io/v1/identify
{
"userId": "email address went here, redacted",
"traits": {
"bool_test": true
}
}
ATTRIBUTE CHANGE LOG IN CIO
{
"bool_test":"true"
}
Update: I tested this by sending attributes both through the CIO dashboard and the API now (API as definitely a boolean value), and also view the attributes in both dashboard and via API through https://api.customer.io/v1/customers/{id}/attributes and both are returning string values, not boolean. I think this may be a bug
Just tested it the events via the manuell Dashboard input. It shows me the boolean. But looks like you acutally found a bug…
Nevertheless I think you should still be able to use the value in segments without problems.
@Felix thanks for the help! Any idea the proper way to escalate this to a bug report / support question? I’m a newbie here in the forums and didn’t want to create anything duplicative.
Hey mtwsf,
you can write an email to win@customer.io. But the segmentation works either way in my opinion as long as it is downcase.
Felix
Hey all,
Thanks for assisting here Felix.
Jumping in here to share a note that most values are stored as strings within Customer.io Journeys on the backend, but they are still treated like the object type they were received as. So even though the change log shows ”true”
that value behaves just like true
when it comes to segmentation, messaging, etc. For this reason, we do not consider this to be a bug.
Another important note here, looking at what was shared above, it looks like the data that was sent to the Customer.io Data Pipeline Source was a boolean value, and that value or value type is not modified in any way when sent to any Destinations; it will be sent as a boolean. Only when the data is received by Customer.io Journeys does our backend service normalize the data for storage.
@Jordan, thanks for the clarification! I noticed, though, that when I use the CIO Journeys app API through https://api.customer.io/v1/customers/{id}/attributes, it returns the value as a string instead of a boolean. Since you mentioned that data passed through the Data Pipeline Source retains its true value downstream, does that only apply if done through the Data Pipelines → another source? It would seem it should also be the real value when accessing it via the Journeys app API.
If not, is there a way to retrieve the original boolean values? This inconsistency could lead to issues when setting up a real-time sync, where it's crucial to correctly identify the data type. It might be challenging to ensure each field is interpreted correctly if they’re returned as strings.
What are your thoughts? Thanks!
On the backend, booleans do become strings in Customer.io Journeys. In fact I forgot to mention that even integers are normalized as strings when stored in Customer.io Journeys even though they are presented as integers in the UI — so I don’t believe there are any other data types in the Customer.io Journeys backend. I’m not sure if any other platform does this, so that is something to be aware of when querying the App API.
To clarify, when I say that the data is not altered in Customer.io Data Pipelines, I’m speaking of the other part of our platform that is used for receiving and send out requests where you want them (e.g. Webhooks, other platforms, etc). Once the request is received by Customer.io Journeys it is transformed to strings.
If you’re querying the App API, you might want to try coercing the data, e.g.
const customer = {id:"abc",boolean_value:"true"}
console.log(typeof customer.boolean_value, customer.boolean_value); // string true
const coerced = Boolean(customer.boolean_value);
console.log(typeof coerced,coerced); // boolean true
Here’s two examples:
So you could either coerce boolean_attribute
to a Boolean value, or you could JSON.parse
the nested_boolean
variable and retrieve the example property value which would be a Boolean.
So yes, it will add some complexity when querying the App API to interpret the customer attributes as other value types. If you were to export the data from Customer.io using this endpoint the exported data is presented more in-line with how the UI interprets what has been stored. So boolean_attribute
is returned as true
.
We agree that it may all be a bit confusing, but it’s the way the Engineering team decided to store data and as it works well for the intended use of Customer.io Journeys.
@Jordan
Thanks for your detailed response! I'm trying to build a simple real-time custom reverse ETL system. Specifically, when someone takes an action in our app, we need to check that against what's in our CIO system. We're on the Essentials plan, so we don't have access to the premium pipeline integrations, and even if we did, they wouldn't be ideal due to sync delays.
Do you have any advice, resources, or examples that could help us figure out the best approach for our situation? I started this thread because I tried using the Journeys App API to get profile info, but I ran into data mismatches without custom handling every time. If that's the only way to do it, I'll go with that, but I wanted to leave no stone unturned to see if there was another solution or conceptual way to look at it first.
Thanks again!