Profile tables
Retrieving the structure of an existing profile table
If you want to copy the structure of an existing custom table (used temporarily for testing, for instance), you can retrieve the structure of all profile tables in an entity with the call
GET /profile-table-structure/v5/entities/{entity}/profile-tables
If you already know the ID of the table, you can retrieve the structure of a single table with the call
GET /profile-table-structure/v5/entities/{entity}/profile-tables/{profileTableId}
You will get the JSON definition of the table as 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": [
{
"description": "Last name",
"name": "lastName"
},
{
"description": "First name",
"name": "firstName"
},
{
"description": "Birth date",
"name": "birthDate"
},
{
"description": "Sex",
"name": "sex"
},
{
"description": "Mother language",
"name": "motherLanguage"
},
{
"description": "e-Mail address",
"name": "emailAddress"
},
{
"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
You can use the following call to create a new profile table:
POST /profile-table-structure/v5/entities/{entity}/profile-tables
If you want to use the definition you retrieved at the previous step to create a new table, you will need to remove the "id", "creationMoment" and "updateMoment" objects from the "attributes" and the "displayOptions" arrays, because these fields are created automatically by Actito.
{
"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": [
{
"description": "Last name",
"name": "lastName"
},
{
"description": "First name",
"name": "firstName"
},
{
"description": "Birth date",
"name": "birthDate"
},
{
"description": "Sex",
"name": "sex"
},
{
"description": "Mother language",
"name": "motherLanguage"
},
{
"description": "e-Mail address",
"name": "emailAddress"
},
{
"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
Depending on their types, the fields must follow specific constraints:
-
STRING: string of characters [a-z, A-Z, 0-9]
- the default max number of characters for a STRING type is 255. It can be modified with a "typeValidator" parameter (see table above)
-
LONG:
- a 64bit integer (no space, dot or comma in number)
- maximum value: 9223372036854775808
- minimum value: -9223372036854775808
-
BOOLEAN: match one of the following values “true” or “false”
-
DATE: string of characters matching one of the following formats:
- YYYYMMDD
- YYYY-MM-DD
- dd/MM/yyyy
-
TIMESTAMP: string of characters matching one of the following formats:
- YYYYMMDD *
- YYYY-MM-DD *
- dd/MM/yyyy *
- YYYYMMDDhhmmss
- YYYY-MM-DD hh:mm:ss
- dd/MM/yyyy HH:mm:ss
- MM/dd/yyyy hh:mm:ss AM|PM
- If no values are specified for "hhmmss", the values "00:00:00" will be added
-
NUMERIC:
- separator must be '.'
- no character amount limit
Creating a table in the UI
Users of the Actito interface can also create new profile table in the "Table structure" app.
They can import a JSON file that follows the same structure as in the API.
The only difference is that they must add an "entityName" parameter to specify the entity on which the new table is created (in the API, the entity name is passed in the path of the call).
{
"name": "Customers",
"entityName":"actito",
[...]
}
Updating a profile table
A profile table can be updated by applying an operation on the table meta data (change display options, description etc), on existing fields (change user name, data validation etc), or on the table structure (add a relation, index a field, etc).
These updates are called "change requests" and are applied asynchronously. By retrieving the status of a change request, you can check if it was successful.
A change request can be created with the following call:
POST /custom-table-structure/v5/entities/{entity}/custom-tables/{customTableId}/change-requests
The body of the call depends on the type of change request. In the API specs, use the One of tabs to display the relevant documentation.
Update display options
Example of JSON body to update display options of a table:
{
"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 foreign key
Adding a foreign key means linking two tables together (for instance, a Profile table with a Repository table).
This link is made on an attribute of the source table (the foreign key) that must match a key attribute of the target table.
The type of the 2 fields making the link between both table must have 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 foreign key
Removing a foreign key means deleting the link between two tables.
{
"on": "TABLE",
"type": "REMOVE_FOREIGN_KEY",
"foreignKeyName":"lookup"
}
Add attribute
Examples of JSON bodies to add a custom or standard attribute to a table:
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 attribute
Example of JSON body to delete an attribute from a table:
{
"on": "TABLE",
"type": "REMOVE_ATTRIBUTE",
"attributeName": "addAttribute"
}
Add segment
Example of JSON body to add a simple or exclusive segment to a table:
Add 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"
}
]
}
}
Add 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
Example of JSON body to add multiple simple or exclusive segments to a table:
Add multiple simple segment
{
"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"
}
]
}
]
}
Add multiple exclusive segment
{
"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 segment
Example of JSON body to remove a segment from a table:
{
"on": "TABLE",
"type": "REMOVE_SEGMENT",
"segmentName": "simpleSegment"
}
Remove multiple segments
Example of JSON body to remove multiple segments from a table:
{
"on": "TABLE",
"type": "REMOVE_SEGMENTS",
"segmentNames": [
"otherSimpleSegment",
"otherExclusiveSegment",
"exclusiveSegment"
]
}
Add subscription
Example of JSON body to add a subscription to a table:
{
"on": "TABLE",
"type": "ADD_SUBSCRIPTION",
"subscription": {
"name": "OPTINSMS"
},
"displayOptions": {
"description": "OPTIN SMS"
}
}
Add multiple subscriptions
Example of JSON body to add multiple subscriptions to a table:
{
"on": "TABLE",
"type": "ADD_SUBSCRIPTIONS",
"subscriptions": [
{
"name": "newsletter"
},
{
"name": "newSubscription"
}
],
"displayOptions": [
{
"name": "newsletter",
"description": "Subscription to newsletter"
},
{
"name": "newSubscription",
"description": "New subscription"
}
]
}
Remove subscription
Example of JSON body to remove a subscription from a table:
{
"on": "TABLE",
"type": "REMOVE_SUBSCRIPTION",
"subscriptionName": "newsletters"
}
Remove multiple subscriptions
Example of JSON body to remove multiple subscriptions from a table:
{
"on": "TABLE",
"type": "REMOVE_SUBSCRIPTIONS",
"subscriptionNames": [
"newsletter",
"newSubscription"
]
}
Rename attribute
Example of JSON body to rename an attribute from a table:
{
"on": "ATTRIBUTE",
"type": "RENAME",
"attributeName": "amount",
"newName": "totalAmount"
}
Add accepted values on attribute
This operation will add accepted values to an attribute. This only works for attributes that were created with value restrictions.
{
"on": "ATTRIBUTE",
"type": "ADD_ACCEPTED_VALUES",
"attributeName" : "Centre",
"acceptedValues" : [
"Brussels",
"Paris",
"Berlin"
]
}
Remove accepted value on attribute
Example of JSON body to remove accepted values from an attribute:
{
"on": "ATTRIBUTE",
"type": "REMOVE_ACCEPTED_VALUES",
"attributeName" : "Centre",
"acceptedValues" : [
"Berlin"
]
}
Make attribute mandatory
This change request will make an attribute mandatory.
This operation only works if every single record in the table already have a value for this attribute. Otherwise, you will first need to create a data import to update existing records with a value.
{
"on": "ATTRIBUTE",
"type": "MAKE_MANDATORY",
"attributeName": "firstName"
}
Make attribute non mandatory
This change request will make this attribute non-mandatory anymore.
{
"on": "ATTRIBUTE",
"type": "MAKE_NON_MANDATORY",
"attributeName": "new"
}
Make attribute unique
This operation will make an attribute unique.
This operation only works if the existing values for this field in the table are already unique and there are no duplicates. You can have several empty values though, as the empty value is not technically considered as a value. Otherwise, you will first need to make sure to remove the duplicate values.
{
"on": "ATTRIBUTE",
"type": "MAKE_UNIQUE",
"attributeName" : "firstName"
}
Make attribute non unique
This operation will remove the unicity of an attribute.
Make sure first that the field is not the key of your table, or is not used as a link by another table.
{
"on": "ATTRIBUTE",
"type": "MAKE_NON_UNIQUE",
"attributeName" : "firstName"
}
Update attribute default value
Example of JSON body to update the attribute's default value:
{
"on": "ATTRIBUTE",
"type": "UPDATE_DEFAULT_VALUE",
"attributeName": "newText",
"defaultValue": "toto"
}
Add segment category
Example of JSON body to add a segment category:
{
"on": "SEGMENT",
"type": "ADD_CATEGORY",
"segmentName": "exclusiveSegment",
"category": "category5",
"displayOptions": {
"displayName": "category 5"
}
}
Remove segment category
Example of JSON body to remove a segment category:
{
"on": "SEGMENT",
"type": "REMOVE_CATEGORY",
"segmentName": "exclusiveSegment",
"category": "category5",
"fallbackCategory": "category1"
}
Make segment mandatory
Example of JSON body to make a segment mandatory:
{
"on": "SEGMENT",
"type": "MAKE_MANDATORY",
"segmentName": "exclusiveSegment",
"defaultCategory": "category1",
"categoryForExistingProfilesWhenUnknown": "category1"
}
Make segment non mandatory
Example of JSON body to make a segment non mandatory:
{
"on": "SEGMENT",
"type": "MAKE_NON_MANDATORY",
"segmentName": "exclusiveSegment"
}
Update segment default category
Example of JSON body to update the segment's default category:
{
"on": "SEGMENT",
"type": "UPDATE_DEFAULT_CATEGORY",
"segmentName": "exclusiveSegment",
"defaultCategory": "category2"
}
Remove segment history
Example of JSON body to remove the segment's history:
{
"on": "SEGMENT",
"type": "REMOVE_HISTORY",
"segmentName": "RFM"
}
Updating a profile table from the UI
All the above operation can also be carried in the Actito UI by uploading a JSON file with the same structure in the 'Tables structure' app or by directly making the changes in the platform.

Checking the result of a change request
As change requests are asynchronous, just because the call to create one is in success doesn't mean the operation was carried out successfully. For instance, when creating a change request to make an existing attribute mandatory, the system will asynchronously check that all records already have a value for this attribute.
You can check the result of a change request with the following call:
GET /profile-table-structure/v5/entities/{entity}/profile-tables/{profileTableId}/change-requests/{changeRequestId}
The response displays both the content of the change request and its status.
{
"_embedded": {
"changeRequests": [
{
"_links": {
"self": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests/127"
}
},
"_audit": {
"createdAt": "2025-10-24T17:42:27+02:00",
"updatedAt": "2025-10-24T17:42:28+02:00"
},
"type": "MAKE_MANDATORY",
"on": "ATTRIBUTE",
"id": "127",
"status": "FAILED",
"errorCode": "NullValue",
"errorMessage": "Null values found in profile table: unable to make attribute mandatory",
"attributeName": "firstName"
},
{
"_links": {
"self": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests/105"
}
},
"_audit": {
"createdAt": "2025-01-22T14:31:02+01:00",
"updatedAt": "2025-01-22T14:31:02+01:00"
},
"type": "MAKE_MANDATORY",
"on": "ATTRIBUTE",
"id": "105",
"status": "FAILED",
"errorCode": "NullValue",
"errorMessage": "Null values found in profile table: unable to make attribute mandatory",
"attributeName": "shop"
},
{
"_links": {
"self": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests/104"
}
},
"_audit": {
"createdAt": "2025-01-22T14:29:03+01:00",
"updatedAt": "2025-01-22T14:29:04+01:00"
},
"type": "MAKE_MANDATORY",
"on": "ATTRIBUTE",
"id": "104",
"status": "FAILED",
"errorCode": "NullValue",
"errorMessage": "Null values found in profile table: unable to make attribute mandatory",
"attributeName": "shop"
},
{
"_links": {
"self": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests/102"
}
},
"_audit": {
"createdAt": "2024-11-13T13:04:53+01:00",
"updatedAt": "2024-11-13T13:04:54+01:00"
},
"type": "MAKE_UNIQUE",
"on": "ATTRIBUTE",
"id": "102",
"status": "SUCCEEDED",
"attributeName": "birthDate"
},
{
"_links": {
"self": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests/84"
}
},
"_audit": {
"createdAt": "2024-06-24T16:05:45+02:00",
"updatedAt": "2024-06-24T16:05:46+02:00"
},
"type": "ADD_ATTRIBUTE",
"on": "TABLE",
"id": "84",
"status": "SUCCEEDED",
"attribute": {
"type": "CUSTOM",
"name": "shop",
"unique": false,
"mandatory": false,
"valueRestriction": {
"maxLength": 255,
"minLength": 0
},
"valueType": "STRING",
"multiValued": false
},
"displayOptions": {
"displayName": "Shop"
}
},
{
"_links": {
"self": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests/68"
}
},
"_audit": {
"createdAt": "2023-11-23T16:51:02+01:00",
"updatedAt": "2023-11-23T16:51:07+01:00"
},
"type": "ADD_ATTRIBUTE",
"on": "TABLE",
"id": "68",
"status": "SUCCEEDED",
"attribute": {
"type": "CUSTOM",
"name": "customerId",
"unique": true,
"mandatory": false,
"valueRestriction": {
"maxLength": 255
},
"valueType": "STRING",
"multiValued": false
},
"displayOptions": {
"displayName": "Customer Id"
}
}
]
},
"filter": {
"sort": "id",
"order": "ASC"
},
"page": {
"pageNumber": 0,
"pageSize": 200,
"totalPages": 1,
"totalElements": 6
},
"_links": {
"first": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests?page=0&pageSize=200&sort=id&order=ASC"
},
"last": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests?page=0&pageSize=200&sort=id&order=ASC"
},
"self": {
"href": "/v5/entities/Profiles/profile-tables/16/change-requests?page=0&pageSize=200&sort=id&order=ASC"
}
}
}