This article explains different values and data types for fields and events in Iterable and examples of what those types of data would look like as they are passed into Iterable.
NOTES
- The character limit for user profile field values is approximately 32k characters, regardless of data type.
- Nested fields count towards the project’s limit for user profile fields (1000).
- All user profile fields are case-sensitive and space-sensitive.
In this article
Overview
A field's data type determines the kind of data that the field can store.
Data types are important because they help you manage your data schema and ensure that your data is accurate and consistent. When you create a field with a specific data type, Iterable expects the field to contain data that matches that type. When Iterable receives data that doesn't match the field's data type, it rejects the data.
Determining a field's data type
When you create a new field in Iterable, you set its type. After a field's type has been set, it cannot be changed.
To create fields and set types, you can use the Data Schema Management screen or Iterable's API.
-
Data Schema Management
When using the Data Schema Management screen, you can make these data types: Boolean, date, double, geo_location, long, object, and string.
-
API
Iterable's API automatically sets a new field's data type to the type of the first value you provide for it.
Creating array and nested data types
Notably, array and nested data types aren’t available in the data type drop-down during field creation.
-
Array
To create a field that contains an array, select the data type associated with the values you'll store in the array. Iterable's data is flexible, so you can store arrays of any data type. However, if you need to index arrays of objects and maintain the independence of each object in the array, use the nested data type instead.
-
Nested
To create a nested data type, which contains an indexed array of objects, contact your customer success manager or Iterable support.
Choosing between the object or nested data type
Consider how you need to segment your data when deciding between creating an object or nested data type.
- Object – Use an object when you want to store a group of related fields that are not indexed by their relationship to each other.
-
Nested – Use a nested data type when you want to store a group of related
fields that are indexed by their relationship to each other.
There are key differences between the object data type, nested data type, and nested fields:
- An object data type contains a collection of related fields.
- A nested data type contains multiple objects.
- Nested fields are fields within either the object data type or the nested data type.
When you send data to Iterable, it's indexed and stored for later access. Indexing is important because it speeds up the process of finding and retrieving data, and because it impacts how data is retrieved.
Normally, objects are flattened when they're indexed. When there is only one object to reference, this is fine.
When you have multiple objects to reference, you might want to use nested objects to index them independently so that their data fields are grouped rather than flattened.
If you need to segment or personalize content by referencing multiple fields within an object, use the nested data type instead of the object data type.
To understand the differences between these data types, here is an example of
JSON data that contains multiple items, called cats
:
{ "email": "user@example.com", "dataFields": { "cats": [ { "name": "Snowball", "color": "White", "age": 4, "favoriteToy": "Fluffy stick" }, { "name": "Whiskers", "color": "Orange", "age": 2, "favoriteToy": "Laser pointer" } ] } }
In this example, cats
contains two objects, each with the same set of fields.
When cats
is created as an object data type in Iterable, the above JSON data
would be indexed like this:
{ "cat.name" : [ "Snowball", "Whiskers" ], "cat.color" : [ "White", "Orange" ] }
This means that any search or segmentation based on the cats
object would not
associate the name
, color
, age
, and favoriteToy
fields with each other.
Instead, they would be indexed as separate fields, each containing an array of
values. You could segment users with white
cats, or orange
cats, but you
cannot segment users who specifically have a white
cat named Snowball
. You
can find users who would have a white
cat and also have a cat named
Snowball
, but the data returned is not necessarily for the same cat.
Here is an example of how Iterable indexes this same set of fields when it has a nested data type:
{ "query": { "bool": { "must": [ { "match": { "cat.name": "Snowball" }}, { "match": { "cat.color": "White" }} ] } } }
With this index, now you can segment users who have a White
cat named
Snowball
.
Data types and segmentation
Different types of data can be segmented differently in Iterable, so its important to consider the values you would like each field to store before you cast that data type in Iterable.
For instance, you can create age
as a field and cast it as a string the
first time the field is sent to Iterable. The data type of a field is listed
underneath each field in Audience > Segmentation.
In this case, the segmentation tool would treat the field as a string:
If a user wanted to use segmentation options given to a numeric field, like the image below (such as Less Than or Greater Than), it wouldn't be possible since the field has already been cast as a string.
User field data types can also be found in Settings > Data Schema Management.
WARNING
Once set, an event or user profile field's data type (string, Boolean, double, etc.) cannot be changed. When creating fields in Iterable, it's important to set the right data type the first time.
API calls (POST /api/users/update
and POST /api/events/track
)
that attempt to set or update an existing field with a value that cannot be
coerced into the appropriate type will fail.
Data types in Iterable
Below is a description of each value type and an example of how a field of
that type would look in a sample payload as it is passed into Iterable using
the POST /api/users/update
or POST /api/commerce/updateCart
API endpoint.
String
If the field is not already cast, CSV imports will automatically cast all fields as strings. Strings can contain both characters and numbers. If the field already exists in the environment, then the CSV import will match the data type of the user profile field.
When setting a string value with Iterable's API, surround its value in quotes.
The following request body for the POST /api/users/update
endpoint sets the user's first name to Justin
:
{ "email": "user@example.com", "dataFields": { "firstName": "Justin" } }
String data types need certain characters encoded in specific ways. These include:
-
Double quotes - If you need to include double quotes inside the value of
a string, use
\"
to escape them. -
Line breaks - Use
\n
or</br>
to represent a line break.
Date
A date field is a specific type of string in Iterable. Fields that are dates have many uses for segmentation in Iterable, like relative dates and date ranges. Iterable has a specific date format that must be used to segment a field by date.
Acceptable date formats include:
-
yyyy-MM-dd HH:mm:ss ZZ (
2000-01-01 00:00:00 -04:00
) -
yyyy-MM-dd HH:mm:ss (
2000-01-01 00:00:00
) -
yyyy-MM-ddTHH:mm:ss.SSSZZ (
2000-01-01T00:00:00.000-04:00
) -
yyyy-MM-dd (
2000-01-01
)
The following request body for the POST /api/users/update
endpoint sets the date for the lastCartUpdateDate
field:
{ "email": "user@example.com", "dataFields": { "lastCartUpdateDate": "2015-02-03 01:20:55 +00:00" } }
Long
Longs are numbers that do not have decimal points.
The following request body for the POST /api/users/update
endpoint sets the user profile's age
field:
{ "email": "user@example.com", "dataFields": { "age": 26 } }
Boolean
True or false. Acceptable Boolean values include true
and false
.
The following request body for the POST /api/users/update
endpoint sets the user profile's hasCat
field:
{ "email": "user@example.com", "dataFields": { "hasCat": false } }
Double
Doubles are numbers that have decimal points.
The following request body for the POST /api/commerce/updateCart
endpoint sets an item's price
field to a double:
{ "user": { "email": "user@example.com" }, "items": [ { "id": "123", "sku": "123", "name": "XL Pizza", "description": "Piping hot and delicious", "categories": [ "food", "pizza" ], "price": 24.99, "quantity": 1 } ] }
Geo_location
A geo_location field stores a location's latitude and longitude.
The name of any field that stores a geo_location value must have a
_geo_location
suffix. Example: address_geo_location
.
The geo_location object may only contain two fields: lat
(the latitude)
and lon
(the longitude). Do not put other fields in this object.
For example, the following request body for the POST /api/users/update
endpoint creates a work_geo_location
field on the user's profile:
{ "email": "user@example.com", "dataFields": { "work_geo_location": { "lat": 41.505493, "lon": -81.681290 } } }
NOTES
- Iterable's segmentation tool cannot perform geolocation queries (proximity, etc.). However, catalog items can contain geo_location values, and collections can use geolocation queries to compare them to the values stored on a user's profile.
- When defining a geo_location field on a catalog item, there is no need to
use the
_geo_location
suffix. The suffix only applies to geo_location values stored on user profiles and custom events.
Object
Objects are collections of related fields. For example, to represent the various attributes of a cat, use an object.
The following request body for the POST /api/users/update
endpoint creates a cat
object on a user's profile:
{ "email": "user@example.com", "dataFields": { "cat": { "name": "Snowball", "color": "White", "age": 4, "favoriteToy": "Fluffy stick" } } }
Iterable's segmentation tool displays objects with a period between the name
of the object and the name of the field being referenced. For example, the
tool would represent the field for the above cat's name as cat.name
.
NOTE
Objects can be edited with API calls (not CSV uploads).
Nested
NOTES
- Nested fields count toward the project’s limit for user profile fields (1000).
- To create a new nested field, contact your customer success manager or Iterable support.
- Nested fields can be edited with API calls (not CSV uploads, and not in the Settings > Data Schema Management screen).
A nested data type contains an array of objects and allows each field to be indexed in the context of their object group, rather than as independent field values.
To understand the differences between the object data type, nested data type, and nested fields, read Choosing between the object or nested data type.
Here is an example of a nested data type that contains multiple items, called
cats
:
{ "email": "user@example.com", "dataFields": { "cats": [ { "name": "Snowball", "color": "White", "age": 4, "favoriteToy": "Fluffy stick" }, { "name": "Whiskers", "color": "Orange", "age": 2, "favoriteToy": "Laser pointer" } ] } }
Array
Arrays are lists of values. Arrays can contain objects, and arrays can belong to objects. For example, to represent a user's list of favorite foods, use an array.
Additionally, Iterable can store arrays within any given data type. For example, you can store an array of strings within a string data type.
The following request body for the POST /api/users/update
endpoint creates a favoriteFoods
array on a user's profile:
{ "email": "user@example.com", "dataFields": { "favoriteFoods": [ "Pizza", "Bánh mì", "Ramen" ] } }
NOTE
Arrays can be edited with API calls, but not CSV uploads.
Want to learn more?
For more information about some of the topics in this article, check out this Iterable Academy course. Iterable Academy is open to everyone — you don't need to be an Iterable customer!