Schemas

View as Markdown

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

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

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: gram
  • kg: kilogram
  • mm: millimeter
  • cm: centimeter
  • m: meter
  • km: kilometer
  • mL: milliliter
  • L: liter
  • B: byte
  • kB: kilobyte
  • MB: megabyte
  • GB: gigabyte
  • °C: degree Celsius
  • °F: degree Fahrenheit
  • oz: ounce
  • lb: pound
  • in: inch
  • ft: foot
  • yd: yard
  • mi: 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:

  • readOptional must be true.
  • createRequired, updateRequired, and nullable must be false or omitted.
  • prefilled must be empty or omitted.
  • name cannot begin with an underscore, as Krenalis reserves leading underscores for system-managed columns of the profiles view, such as _kpid and _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 the object type, whose properties can be added, removed, renamed, and reordered. Otherwise, the request fails with an InvalidAlterSchema error. 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 rePaths parameter.
  • 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 InvalidAlterSchema error. 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.