Schemas
Schemas are used by multiple endpoints to define the structure of profiles, events, and the source and destination schemas for applications, databases, and files.
Below is an example of a profile schema with the properties: email, date_of_birth, and ip_addresses.
{
"kind": "object",
"properties": [
{
"name": "email",
"type": {
"kind": "string",
"semantics": "email",
"maxLength": 120
},
"readOptional": true,
"displayName": "Email"
},
{
"name": "date_of_birth",
"type": { "kind": "date" },
"readOptional": true,
"displayName": "Date of birth"
},
{
"name": "ip_addresses",
"type": {
"kind": "array",
"elementType": { "kind": "ip" }
},
"readOptional": true,
"displayName": "IP address"
}
]
}
Note that a schema has the same representation as an object type.
Data types
Below are the data types and their representations in JSON format:
- string - string
- boolean - boolean
- int - signed integer
- float - floating point number
- decimal - decimal number
- datetime - date and time
- date - date
- time - time
- year - year
- uuid - UUID
- json - JSON
- ip - IPv4 or IPv6 address
- array - array
- object - object
- map - map
string
Represents UTF-8 encoded string.
{
"kind": "string"
}
Strings can use one of the following semantics: country, email, phone, or URL.
Strings can be constrained by a list of allowed values, a regular expression, or maximum lengths in characters and bytes. These constraints cannot be combined with country or phone semantics.
For example a string limited to specific values:
{
"kind": "string",
"values": [ "Hearts", "Diamonds", "Clubs", "Spades" ]
}
If "values" is present:
- it must contain at least one value
- the empty string is allowed
- values must not include the NUL character
For example a string matching a pattern:
{
"kind": "string",
"pattern": "\\d+"
}
Pattern syntax is the same as the Go syntax.
For example a string with a maximum length of 2 characters:
{
"kind": "string",
"maxLength": 2
}
For example a string with a maximum length of 1000 bytes:
{
"kind": "string",
"maxBytes": 1000
}
You can combine maximum character and bytes lengths. For example a string with a maximum of 20 characters and 25 bytes:
{
"kind": "string",
"maxLength": 20,
"maxBytes": 25
}
Examples of values are "Everett Hayes", "(555) 123-4567".
boolean
Represents a boolean value.
{
"kind": "boolean"
}
Values are true and false.
int
An integer with a specific bit size. The size can be 8, 16, 24, 32, or 64
{
"kind": "int",
"bitSize": 32
}
Integers can use one of the following semantics: duration or measurement.
You can limit integers to a minimum and maximum range, for example the following defines an 8-bit integer with range [-20, 20]:
{
"kind": "int",
"bitSize": 8,
"minimum": -20,
"maximum": 20
}
You can also mark the integer as unsigned, which limits it to non-negative values. The example below defines a 32-bit unsigned integer:
{
"kind": "int",
"bitSize": 32,
"unsigned": true
}
Examples of values are 12, -470, 7308561.
float
A floating-point number with a specific bit size, according to the IEEE 754 standard. The available sizes are 32 or 64 bits.
{
"kind": "float",
"bitSize": 64
}
A float with real set to true can use one of the following semantics: duration or measurement.
Floats can have a minimum and maximum value and exclude special values such as NaN, Infinity, and -Infinity. For example a 32-bit float with range [-20.5, 8]:
{
"kind": "float",
"bitSize": 32,
"minimum": -20.5,
"maximum": 8
}
For example a 64-bit float with range [-0, 56.481782]:
{
"kind": "float",
"bitSize": 64,
"minimum": 0,
"maximum": 56.481782
}
For example, a 64-bit float excluding special values such as NaN, Infinity, and -Infinity:
{
"kind": "float",
"bitSize": 64,
"real": true
}
Examples of values are 1.6892, -0.002516, 441.015, "NaN", "Infinity", "-Infinity".
decimal
A decimal number with a precision and a scale, where precision ranges from 1 to 76, scale from 0 to 37, and scale is less than or equal to precision.
{
"kind": "decimal",
"precision": 10,
"scale": 2
}
Decimals can use one of the following semantics: duration, measurement, money, or percentage.
Decimals can also have a minimum and maximum value range, for example the following is a decimal with precision 5 and scale 2, range [-10.5, 8.25].
{
"kind": "decimal",
"precision": 5,
"scale": 2,
"minimum": -10.5,
"maximum": 8.25
}
Examples of values are 5.12, 893, 1258.068.
datetime
Represents a date and time within the range of years [1, 9999] with nanosecond precision and UTC timezone.
{
"kind": "datetime"
}
Values are presented in ISO 8601 format. When passing a datetime value to the API endpoints, you can use any ISO 8601 format with any timezone; it will be automatically converted to UTC.
Examples include "2024-12-23T09:05:47Z", "2025-02-11T16:19:14.3392Z", "1975-12-05T09:55:12.048522068Z".
date
Represents a date within the range of years [1, 9999].
{
"kind": "date"
}
Values are presented in ISO 8601 format. When passing a date value to the API endpoints, you can use the ISO 8601 format yyyy-mm-dd.
Examples of values are "2025-02-11", "1975-12-05".
time
Represents a time of day with nanosecond precision and no timezone. Values are presented in ISO 8601 format.
{
"kind": "time"
}
Values are presented in ISO 8601 format. When passing a time value to the API endpoints, you can use the ISO 8601 formats HH:mm:ss and HH:mm:ss.sssssssss, with up to 9 decimal digits.
Examples of values are "16:19:14", "20:06:58.921", "09:55:12.048522068".
year
Represents a year within the range [1, 9999].
{
"kind": "year"
}
Examples of values are 2025, 1975.
uuid
Represents a UUID.
{
"kind": "uuid"
}
Examples of values are "ae3a0552-eff9-4456-8a2e-b94c64d03359", "bbe0eda7-b672-4cfb-9285-1128681e00cd".
json
Represents a JSON value.
{
"kind": "json"
}
Examples of values are "null", "5" "\"hello"\", "{\"name\":\"John\"}", "true", "[34,12,0,6]".
ip
Represents an IPv4 or IPv6 address.
{
"kind": "ip"
}
IPv4-mapped IPv6 addresses are included in their normalized IPv4 form, e.g. "::ffff:192.0.2.1" is represented as "192.0.2.1".
Examples of values are "192.0.2.1", "2001:db8::1".
array
Represents an array of elements of the same type. For example an array of string:
{
"kind": "array",
"elementType": { "kind": "string" }
}
Arrays can be limited in the minimum and maximum number of elements. For example an array of 32-bit unsigned integers with at least 1 element:
{
"kind": "array",
"elementType": {
"kind": "int",
"bitSize": 32
},
"minElements": 1
}
For example an array with a maximum of 10 decimal values:
{
"kind": "array",
"elementType": {
"kind": "decimal",
"precision": 10,
"scale": 2
},
"maxElements": 10
}
For example an array with 5 to 15 string values.
{
"kind": "array",
"elementType": { "kind": "string" },
"minElements": 5,
"maxElements": 15
}
Arrays can also be constrained to have unique values for their elements, except for arrays of json, array, map, and object.
For example an array of 64-bit unsigned integers with unique values:
{
"kind": "array",
"elementType": {
"kind": "int",
"bitSize": 64,
"unsigned": true
},
"uniqueElements": true
}
For example an array of UUIDs with unique values:
{
"kind": "array",
"elementType": { "kind": "uuid" },
"uniqueElements": true
}
Examples of values are [8498, 204, 7531], [{"name": "John"}, {"name": "Emily"}].
object
Represents an object with specified properties. For example:
{
"kind": "object",
"properties": [
{
"name": "first_name",
"type": {
"kind": "string",
"maxLength": 30
},
"displayName": "First name"
},
{
"name": "last_name",
"type": {
"kind": "string",
"maxLength": 30
},
"displayName": "Last name"
},
{
"name": "birth_date",
"type": { "kind": "date" },
"displayName": "Birth date"
}
]
}
Examples of values are {"first_name": "John", "last_name": "Hollis", "age": 34, active: true}, {"city": "New York", "street": "5th Avenue", "zip": 10001}.
Properties
An object property has the following keys:
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
name |
String |
The name of the property. It must start with a letter [A-Za-z_] and can only contain alphanumeric characters and underscores [A-Za-z0-9_] after that. |
||
prefilled |
Number |
"" |
This is the value that appears pre-filled when a destination pipeline is configured on events. It suggests the expression linked to the property, so it doesn't have to be entered manually. It must not include the NUL character. | |
type |
Object |
The type of the property, which can be any data type. | ||
createRequired |
Boolean |
false |
Indicates whether the property is required during creation, i.e., whether a value for the property is required at the time of creation. | |
updateRequired |
Boolean |
false |
Indicates whether the property is required for updating, i.e., whether a value for the property is mandatory when updating an existing record. | |
readOptional |
Boolean |
false |
Indicates whether the property may not be present when reading, i.e., whether the property is optional and may not be included in the data when retrieved. | |
nullable |
Boolean |
false |
Indicates whether the property can be null. |
|
displayName |
String |
"" |
A human-readable name for the property, shown in user interfaces. It must not include the NUL character. | |
description |
String |
"" |
A description providing additional information about the property's usage. It must not include the NUL character. |
map
Represents a map with string keys and values of the same type. For example a map of string:
{
"kind": "map",
"elementType": { "kind": "string" }
}
For example a map with 64-bit signed integers as values:
{
"kind": "map",
"elementType": {
"kind": "int",
"bitSize": 64
}
}
For example a map with arrays of strings as values:
{
"kind": "map",
"elementType": {
"kind": "array",
"elementType": { "kind": "string" }
}
}
Examples of values are {"score": "6205", "player": "Everett Hayes"}, {"width": 1920, "height": 1080}.
Semantics
The semantics property describes what a value represents, such as an email address, a duration, or a monetary amount. Supported semantics are available only for specific data types, as described below.
Country
Country semantics represent uppercase country codes in ISO 3166-1 alpha-2 or alpha-3 format. They can only be used with the string type and cannot be combined with allowed values, a regular expression, or maximum lengths in characters or bytes. Their value set includes both currently and formerly assigned country codes. The required format property identifies which format is used.
For example, a country code in ISO 3166-1 alpha-2 format:
{
"kind": "string",
"semantics": "country",
"format": "alpha-2"
}
Examples of values are "US" and "IT" for alpha-2, or "USA" and "ITA" for alpha-3.
Duration
Duration semantics represent numeric durations measured in one of the following units: millisecond, second, minute, hour, day, or week. The unit property is required. They can be used with int and decimal types, or with float types that have real set to true.
For example, a duration expressed in seconds:
{
"kind": "decimal",
"semantics": "duration",
"unit": "second",
"precision": 7,
"scale": 3
}
Examples of values are 5, 3027.306, -891.
Email semantics identify a string as an email address but add no email-address format constraint.
For example, an email address:
{
"kind": "string",
"semantics": "email"
}
Examples of values are "info@acme.com", "john@example.com".
Measurement
Measurement semantics represent measurements expressed in one of the following units. The unit property is required.
g: gramkg: kilogrammm: millimetercm: centimeterm: meterkm: kilometermL: milliliterL: literB: bytekB: kilobyteMB: megabyteGB: gigabyte°C: degree Celsius°F: degree Fahrenheitoz: ouncelb: poundin: inchft: footyd: yardmi: mile
It can be used with int and decimal types, or with float types that have real set to true.
For example, a measurement expressed in kilograms:
{
"kind": "float",
"semantics": "measurement",
"unit": "kg",
"bitSize": 64,
"real": true
}
Examples of values are 68, -250, 23.09.
Money
Money semantics represent monetary amounts. They can only be used with the decimal type, with any supported precision and scale. The optional currency property identifies the monetary unit with an ISO 4217 currency code.
For example, a monetary value in US dollars:
{
"kind": "decimal",
"semantics": "money",
"currency": "USD",
"precision": 12,
"scale": 4
}
Examples of values are 22.57, 1600, -515.3104.
Percentage
Percentage semantics represent percentages in decimal form. For example, 0.9 represents 90%, and 21 represents 2,100%. They can only be used with the decimal type, with any supported precision and scale.
For example, a percentage:
{
"kind": "decimal",
"semantics": "percentage",
"precision": 4,
"scale": 2
}
Examples of values are 0.25 (25%), -0.50 (-50%), 13.0 (1,300%).
Phone
Phone semantics describe phone numbers in canonical E.164 format, including their country calling codes. They can only be used with the string type and cannot be combined with allowed values, a regular expression, or maximum lengths in characters or bytes.
For example, a phone number:
{
"kind": "string",
"semantics": "phone"
}
Examples of values are "+12025550123", "+14155550123".
URL
URL semantics identify a string as a URL but add no URL format constraint.
For example, a URL:
{
"kind": "string",
"semantics": "url"
}
Examples of values are "https://blog.example.com/john-smith", "https://john.example.org/".
Profile schema restrictions
Krenalis stores profiles in the tables of the workspace's data warehouse, so the profile schema accepts only a subset of the schemas described above. The restrictions below apply to the profileSchema parameter when you create a workspace and to the schema parameter when you alter the profile schema or preview its alteration. A request with a schema that does not meet them fails with a 400 Bad Request error.
The schema must define at least one property.
Property keys
Every property, including the properties of nested objects, must meet the following requirements:
readOptionalmust betrue.createRequired,updateRequired, andnullablemust befalseor omitted.prefilledmust be empty or omitted.namecannot begin with an underscore, as Krenalis reserves leading underscores for system-managed columns of theprofilesview, such as_kpidand_updated_at.
Column names
Each property is stored in a column of the data warehouse. A top-level property is stored in a column with the same name, while a property of an object is stored in a column whose name is the property path with periods replaced by underscores. For example, address.city is stored in the column address_city. Object properties have no column of their own.
Two properties cannot be stored in columns with the same name, compared case-insensitively. For example, a schema cannot contain both a top-level address_city property and an address object with a city property, nor both email and Email.
Allowed types
All data types are allowed, with the following restrictions:
| Type | Restrictions |
|---|---|
| string | values and pattern are not allowed. maxLength and maxBytes are allowed. |
| array | The element type cannot be array, object, or map. minElements, maxElements, and uniqueElements are not allowed. If the element type is string, it cannot have values or pattern. |
| map | The element type cannot be array, object, or map. If the element type is string, it cannot have values or pattern. |
| object | Its properties are subject to the same restrictions as top-level properties. |
The other types have no restrictions. For example, int, float, and decimal can have a minimum and maximum value.
Allowed semantics
Some semantics can only be used with a specific type. These restrictions also apply to the element type of arrays and maps.
| Semantics | Allowed type |
|---|---|
| country | string with "format": "alpha-2". The alpha-3 format is not allowed. |
| duration | int with "bitSize": 64, not unsigned. decimal and float are not allowed. |
| measurement, money, percentage | decimal with "precision": 18 and "scale": 4. int and float are not allowed. |
| email, phone, url | No additional restrictions. |
For example, the following profile schema uses country, money, and duration semantics:
{
"kind": "object",
"properties": [
{
"name": "country",
"type": {
"kind": "string",
"semantics": "country",
"format": "alpha-2"
},
"readOptional": true
},
{
"name": "lifetime_value",
"type": {
"kind": "decimal",
"semantics": "money",
"currency": "USD",
"precision": 18,
"scale": 4
},
"readOptional": true
},
{
"name": "time_on_site",
"type": {
"kind": "int",
"semantics": "duration",
"unit": "second",
"bitSize": 64
},
"readOptional": true
}
]
}
Changes to an existing profile schema
When you alter the profile schema, the new schema is compared with the current one, and the following additional restrictions apply:
- The type of an existing property cannot change, including its parameters and semantics. For example, you cannot change
maxLength,bitSize,precision, the semantics, or the unit of a duration. The only exception is theobjecttype, whose properties can be added, removed, renamed, and reordered. Otherwise, the request fails with anInvalidAlterSchemaerror. To change the type of a property, see Change property types. - A property can only be renamed within its object. It cannot be moved to a different object or to the top level. Specify renamed properties with the
rePathsparameter. - An object property cannot be renamed while its properties are also changed in the same request. Any change counts, including reordering the properties or changing their descriptions. Otherwise, the request fails with an
InvalidAlterSchemaerror. Apply the two changes in separate requests.
The primarySources parameter is also validated. A primary source cannot be assigned to an object or array property, and must be a source connection whose connector supports users. Otherwise, the request fails with a 400 Bad Request error, or with a ConnectionNotExist error if the connection does not exist.
If a property used as an identity resolution identifier is renamed, the identifier is renamed too. If it is removed, it is also removed from the identifiers.