Skip to main content

Profile Tables

Retrieving the structure of an existing profile table

To retrieve all profile tables in an entity:

GET /profile-table-structure/v5/entities/{entity}/profile-tables

To retrieve a single table by ID:

GET /profile-table-structure/v5/entities/{entity}/profile-tables/{profileTableId}

Example response:

{
"id": "16",
"name": "Profiles",
"attributes": [
{ "type": "CUSTOM", "name": "profileId", "unique": true, "mandatory": true, "valueType": "INTEGER", "multiValued": false },
{ "type": "CUSTOM", "name": "creationMoment", "unique": false, "mandatory": true, "valueType": "TIMESTAMP", "multiValued": false },
{ "type": "CUSTOM", "name": "updateMoment", "unique": false, "mandatory": true, "valueType": "TIMESTAMP", "multiValued": false },
{ "type": "LASTNAME", "name": "lastName", "unique": false, "mandatory": true },
{ "type": "FIRSTNAME", "name": "firstName", "unique": false, "mandatory": false },
{ "type": "BIRTHDATE", "name": "birthDate", "unique": true, "mandatory": false },
{ "type": "SEX", "name": "sex", "unique": false, "mandatory": false },
{ "type": "MOTHER_LANGUAGE", "name": "motherLanguage", "unique": false, "mandatory": false },
{ "type": "EMAIL_ADDRESS", "name": "emailAddress", "unique": true, "mandatory": true },
{
"type": "CUSTOM", "name": "customerId", "unique": true, "mandatory": false,
"valueRestriction": { "maxLength": 255 }, "valueType": "STRING", "multiValued": false
},
{
"type": "CUSTOM", "name": "shop", "unique": false, "mandatory": false,
"valueRestriction": { "maxLength": 255, "minLength": 0 }, "valueType": "STRING", "multiValued": false
}
],
"displayOptions": {
"forAttributes": [
{ "name": "lastName", "description": "Last name" },
{ "name": "firstName", "description": "First name" },
{ "name": "birthDate", "description": "Birth date" },
{ "name": "sex", "description": "Sex" },
{ "name": "motherLanguage", "description": "Mother language" },
{ "name": "emailAddress", "description": "e-Mail address" },
{ "name": "customerId", "displayName": "Customer Id" },
{ "name": "shop", "displayName": "Shop" }
]
},
"foreignKeys": [
{
"name": "shop",
"attribute": "shop",
"reference": { "tableId": "UNRESOLVED DATASOURCE ID", "attribute": "storeID" }
}
],
"subscriptions": [
{ "name": "Newsletter" }
]
}

Creating a new profile table

POST /profile-table-structure/v5/entities/{entity}/profile-tables
tip

When reusing an existing table definition, remove the id, creationMoment, and updateMoment fields from the attributes and displayOptions arrays — these are generated automatically by Actito.

Example request body:

{
"name": "Profiles",
"attributes": [
{ "type": "LASTNAME", "name": "lastName", "unique": false, "mandatory": true },
{ "type": "FIRSTNAME", "name": "firstName", "unique": false, "mandatory": false },
{ "type": "BIRTHDATE", "name": "birthDate", "unique": true, "mandatory": false },
{ "type": "SEX", "name": "sex", "unique": false, "mandatory": false },
{ "type": "MOTHER_LANGUAGE", "name": "motherLanguage", "unique": false, "mandatory": false },
{ "type": "EMAIL_ADDRESS", "name": "emailAddress", "unique": true, "mandatory": true },
{
"type": "CUSTOM", "name": "customerId", "unique": true, "mandatory": false,
"valueRestriction": { "maxLength": 255 }, "valueType": "STRING", "multiValued": false
},
{
"type": "CUSTOM", "name": "shop", "unique": false, "mandatory": false,
"valueRestriction": { "maxLength": 255, "minLength": 0 }, "valueType": "STRING", "multiValued": false
}
],
"displayOptions": {
"forAttributes": [
{ "name": "lastName", "description": "Last name" },
{ "name": "firstName", "description": "First name" },
{ "name": "birthDate", "description": "Birth date" },
{ "name": "sex", "description": "Sex" },
{ "name": "motherLanguage", "description": "Mother language" },
{ "name": "emailAddress", "description": "e-Mail address" },
{ "name": "customerId", "displayName": "Customer Id" },
{ "name": "shop", "displayName": "Shop" }
]
},
"foreignKeys": [
{
"name": "shop",
"attribute": "shop",
"reference": { "tableId": "UNRESOLVED DATASOURCE ID", "attribute": "storeID" }
}
],
"subscriptions": [
{ "name": "Newsletter" }
]
}

Field value types

TypeConstraints
STRINGCharacters [a-z, A-Z, 0-9]. Default max length: 255 (configurable via typeValidator)
LONG64-bit integer. No spaces, dots, or commas. Range: -9223372036854775808 to 9223372036854775808
BOOLEANMust be "true" or "false"
DATEYYYYMMDD, YYYY-MM-DD, or dd/MM/yyyy
TIMESTAMPAccepts date-only formats (time defaults to 00:00:00) or full datetime: YYYYMMDDhhmmss, YYYY-MM-DD hh:mm:ss, dd/MM/yyyy HH:mm:ss, MM/dd/yyyy hh:mm:ss AM|PM
NUMERICDecimal separator must be .. No character limit.

Creating a table in the UI

Users can also create profile tables in the Table structure app by importing a JSON file following the same structure as the API.

tip

When creating via the UI, add an "entityName" parameter to specify the target entity (in the API, the entity is passed in the URL path):

{
"name": "Customers",
"entityName": "actito"
}

Updating a profile table

Updates to a profile table are applied via change requests — asynchronous operations that modify metadata, field definitions, or table structure.

POST /profile-table-structure/v5/entities/{entity}/profile-tables/{profileTableId}/change-requests

The request body depends on the type of change. Use the One of tabs in the API specs for the relevant documentation.

Update display options

{
"on": "TABLE",
"type": "UPDATE_DISPLAY_OPTIONS",
"displayOptions": {
"forAttributes": [
{ "name": "emailAddress", "displayName": "emailAddress" }
],
"description": "my description",
"forSubscriptions": [
{ "name": "newsletter", "description": "my description" }
],
"forSegments": [
{
"name": "TESTACTITO",
"displayName": "TEST ACTITO",
"forCategories": [
{ "name": "Segment1", "displayName": "Segment 1" }
]
}
]
}
}

Add a foreign key

A foreign key links two tables together (e.g. a Profile table with a Repository table). The foreign key attribute must match a key attribute in the target table, and both fields must share the same value type.

{
"on": "TABLE",
"type": "ADD_FOREIGN_KEY",
"foreignKey": {
"name": "lookup",
"attribute": "SKU",
"reference": {
"tableId": "7a2f396e-b1d6-45d4-bc68-e16543fc50a4",
"attribute": "SKU"
}
}
}

Remove a foreign key

{
"on": "TABLE",
"type": "REMOVE_FOREIGN_KEY",
"foreignKeyName": "lookup"
}

Add an attribute

info

A mandatory attribute cannot be added to an already populated table.

Custom attribute:

{
"on": "TABLE",
"type": "ADD_ATTRIBUTE",
"attribute": {
"type": "CUSTOM",
"name": "addAttribute",
"valueType": "STRING",
"unique": false,
"mandatory": false
},
"displayOptions": { "displayName": "Add attribute" }
}

Standard attribute:

{
"on": "TABLE",
"type": "ADD_ATTRIBUTE",
"attribute": {
"type": "ADDRESS_STREET",
"name": "addressStreet",
"unique": false,
"mandatory": false
},
"displayOptions": { "displayName": "Address street" }
}

Remove an attribute

{
"on": "TABLE",
"type": "REMOVE_ATTRIBUTE",
"attributeName": "addAttribute"
}

Add a segment

Simple segment:

{
"on": "TABLE",
"type": "ADD_SEGMENT",
"segment": {
"type": "SIMPLE",
"name": "simpleSegment",
"historicize": false,
"defaultValue": true
},
"displayOptions": {
"displayName": "Simple segment",
"forCategories": [
{ "name": "category1", "displayName": "Category 1" },
{ "name": "category2", "displayName": "Category 2" },
{ "name": "category3", "displayName": "Category 3" }
]
}
}

Exclusive segment:

{
"on": "TABLE",
"type": "ADD_SEGMENT",
"segment": {
"type": "EXCLUSIVE",
"name": "exclusiveSegment",
"categories": ["category1", "category2", "category3"],
"historicize": false,
"mandatory": true,
"defaultCategory": "category1",
"initialCategory": "category1"
},
"displayOptions": {
"displayName": "Exclusive segment",
"forCategories": [
{ "name": "category1", "displayName": "Category 1" },
{ "name": "category2", "displayName": "Category 2" },
{ "name": "category3", "displayName": "Category 3" }
]
}
}

Add multiple segments

Multiple simple segments:

{
"on": "TABLE",
"type": "ADD_SEGMENTS",
"segments": [
{ "type": "SIMPLE", "name": "simpleSegment", "historicize": false, "defaultValue": true },
{ "type": "SIMPLE", "name": "otherSimpleSegment", "historicize": false, "defaultValue": true },
{ "type": "SIMPLE", "name": "anotherSimpleSegment", "historicize": false, "defaultValue": true }
],
"displayOptions": [
{
"name": "simpleSegment", "displayName": "Simple segment",
"forCategories": [
{ "name": "category1", "displayName": "Category 1" },
{ "name": "category2", "displayName": "Category 2" },
{ "name": "category3", "displayName": "Category 3" }
]
},
{
"name": "otherSimpleSegment", "displayName": "Other simple segment",
"forCategories": [
{ "name": "category1", "displayName": "Category 1" },
{ "name": "category2", "displayName": "Category 2" },
{ "name": "category3", "displayName": "Category 3" }
]
},
{
"name": "anotherSimpleSegment", "displayName": "Another simple segment",
"forCategories": [
{ "name": "category1", "displayName": "Category 1" },
{ "name": "category2", "displayName": "Category 2" },
{ "name": "category3", "displayName": "Category 3" }
]
}
]
}

Multiple exclusive segments:

{
"on": "TABLE",
"type": "ADD_SEGMENTS",
"segments": [
{
"type": "EXCLUSIVE", "name": "exclusiveSegment",
"categories": ["category1", "category2", "category3"],
"historicize": false, "mandatory": true,
"defaultCategory": "category1", "initialCategory": "category1"
},
{
"type": "EXCLUSIVE", "name": "otherExclusiveSegment",
"categories": ["category1", "category2", "category3"],
"historicize": false, "mandatory": true,
"defaultCategory": "category1", "initialCategory": "category1"
},
{
"type": "EXCLUSIVE", "name": "anotherExclusiveSegment",
"categories": ["category1", "category2", "category3"],
"historicize": false, "mandatory": true,
"defaultCategory": "category1", "initialCategory": "category1"
}
],
"displayOptions": [
{
"name": "exclusiveSegment", "displayName": "Exclusive segment",
"forCategories": [
{ "name": "category1", "displayName": "Category 1" },
{ "name": "category2", "displayName": "Category 2" },
{ "name": "category3", "displayName": "Category 3" }
]
},
{
"name": "otherExclusiveSegment", "displayName": "Other exclusive segment",
"forCategories": [
{ "name": "category1", "displayName": "Category 1" },
{ "name": "category2", "displayName": "Category 2" },
{ "name": "category3", "displayName": "Category 3" }
]
},
{
"name": "anotherExclusiveSegment", "displayName": "Another exclusive segment",
"forCategories": [
{ "name": "category1", "displayName": "Category 1" },
{ "name": "category2", "displayName": "Category 2" },
{ "name": "category3", "displayName": "Category 3" }
]
}
]
}

Remove a segment

{
"on": "TABLE",
"type": "REMOVE_SEGMENT",
"segmentName": "simpleSegment"
}

Remove multiple segments

{
"on": "TABLE",
"type": "REMOVE_SEGMENTS",
"segmentNames": ["otherSimpleSegment", "otherExclusiveSegment", "exclusiveSegment"]
}

Add a subscription

{
"on": "TABLE",
"type": "ADD_SUBSCRIPTION",
"subscription": { "name": "OPTINSMS" },
"displayOptions": { "description": "OPTIN SMS" }
}

Add multiple subscriptions

{
"on": "TABLE",
"type": "ADD_SUBSCRIPTIONS",
"subscriptions": [
{ "name": "newsletter" },
{ "name": "newSubscription" }
],
"displayOptions": [
{ "name": "newsletter", "description": "Subscription to newsletter" },
{ "name": "newSubscription", "description": "New subscription" }
]
}

Remove a subscription

{
"on": "TABLE",
"type": "REMOVE_SUBSCRIPTION",
"subscriptionName": "newsletters"
}

Remove multiple subscriptions

{
"on": "TABLE",
"type": "REMOVE_SUBSCRIPTIONS",
"subscriptionNames": ["newsletter", "newSubscription"]
}

Rename an attribute

{
"on": "ATTRIBUTE",
"type": "RENAME",
"attributeName": "amount",
"newName": "totalAmount"
}

Add accepted values on an attribute

Only works for attributes that were created with value restrictions.

{
"on": "ATTRIBUTE",
"type": "ADD_ACCEPTED_VALUES",
"attributeName": "Centre",
"acceptedValues": ["Brussels", "Paris", "Berlin"]
}

Remove accepted values from an attribute

{
"on": "ATTRIBUTE",
"type": "REMOVE_ACCEPTED_VALUES",
"attributeName": "Centre",
"acceptedValues": ["Berlin"]
}

Make an attribute mandatory

info

This only works if every existing record already has a value for this attribute. Otherwise, run a data import first to populate missing values.

{
"on": "ATTRIBUTE",
"type": "MAKE_MANDATORY",
"attributeName": "firstName"
}

Make an attribute non-mandatory

{
"on": "ATTRIBUTE",
"type": "MAKE_NON_MANDATORY",
"attributeName": "new"
}

Make an attribute unique

info

This only works if all existing values for the field are already unique. Empty values are permitted — they are not considered duplicates. Remove any duplicates before applying this change.

{
"on": "ATTRIBUTE",
"type": "MAKE_UNIQUE",
"attributeName": "firstName"
}

Make an attribute non-unique

info

Ensure the field is not the table's primary key and is not used as a foreign key reference by another table.

{
"on": "ATTRIBUTE",
"type": "MAKE_NON_UNIQUE",
"attributeName": "firstName"
}

Update an attribute's default value

{
"on": "ATTRIBUTE",
"type": "UPDATE_DEFAULT_VALUE",
"attributeName": "newText",
"defaultValue": "toto"
}

Add a segment category

{
"on": "SEGMENT",
"type": "ADD_CATEGORY",
"segmentName": "exclusiveSegment",
"category": "category5",
"displayOptions": { "displayName": "category 5" }
}

Remove a segment category

{
"on": "SEGMENT",
"type": "REMOVE_CATEGORY",
"segmentName": "exclusiveSegment",
"category": "category5",
"fallbackCategory": "category1"
}

Make a segment mandatory

{
"on": "SEGMENT",
"type": "MAKE_MANDATORY",
"segmentName": "exclusiveSegment",
"defaultCategory": "category1",
"categoryForExistingProfilesWhenUnknown": "category1"
}

Make a segment non-mandatory

{
"on": "SEGMENT",
"type": "MAKE_NON_MANDATORY",
"segmentName": "exclusiveSegment"
}

Update a segment's default category

{
"on": "SEGMENT",
"type": "UPDATE_DEFAULT_CATEGORY",
"segmentName": "exclusiveSegment",
"defaultCategory": "category2"
}

Remove segment history

{
"on": "SEGMENT",
"type": "REMOVE_HISTORY",
"segmentName": "RFM"
}

Updating a profile table from the UI

All change requests above can also be applied in the Actito UI by uploading a JSON file in the Tables structure app, or by directly making changes in the platform.

Checking the result of a change request

Since change requests are asynchronous, a successful API call only means the request was accepted — not that it completed successfully. To verify the outcome:

GET /profile-table-structure/v5/entities/{entity}/profile-tables/{profileTableId}/change-requests/{changeRequestId}

Example response:

{
"_embedded": {
"changeRequests": [
{
"id": "127",
"type": "MAKE_MANDATORY",
"on": "ATTRIBUTE",
"status": "FAILED",
"errorCode": "NullValue",
"errorMessage": "Null values found in profile table: unable to make attribute mandatory",
"attributeName": "firstName",
"_audit": { "createdAt": "2025-10-24T17:42:27+02:00", "updatedAt": "2025-10-24T17:42:28+02:00" }
},
{
"id": "102",
"type": "MAKE_UNIQUE",
"on": "ATTRIBUTE",
"status": "SUCCEEDED",
"attributeName": "birthDate",
"_audit": { "createdAt": "2024-11-13T13:04:53+01:00", "updatedAt": "2024-11-13T13:04:54+01:00" }
},
{
"id": "84",
"type": "ADD_ATTRIBUTE",
"on": "TABLE",
"status": "SUCCEEDED",
"attribute": {
"type": "CUSTOM", "name": "shop", "unique": false, "mandatory": false,
"valueRestriction": { "maxLength": 255, "minLength": 0 },
"valueType": "STRING", "multiValued": false
},
"displayOptions": { "displayName": "Shop" },
"_audit": { "createdAt": "2024-06-24T16:05:45+02:00", "updatedAt": "2024-06-24T16:05:46+02:00" }
}
]
},
"page": {
"pageNumber": 0,
"pageSize": 200,
"totalPages": 1,
"totalElements": 6
}
}