Skip to main content
Version: 10

Manage segments using Segmentation Engine API

Level: advanced

Marketers need to send campaigns, mailings, and offers to the right group of contacts, and to keep that group up to date as contacts' data changes, without re-running the same query by hand every time. The Segmentation Engine solves this by letting you define an audience once, as a segment, and let Creatio maintain its membership automatically. Learn more: Segments (user documentation), Set up and manage segments (user documentation).

Object that stores segments​

Creatio stores segments in the "Segment" (SysDataSegment code) object. Out of the box, segments are available for the "Contact" (Contact code) object only. Besides the base columns available on any object, the "Segment" (SysDataSegment code) object exposes the following columns.

Column

Description

Name

The display name. Must be unique. Creatio rejects a duplicate with a validation error.

"Segment of" (EntitySchema code)

The target entity for membership, accessible as EntitySchema.Name.

"Entry filter data" (EntryFilterData code)

The entry filter JSON.

"Exit filter data" (ExitFilterData code)

The exit filter JSON. Applies only when the segment's exit strategy requires evaluating conditions.

"Exit strategy" (SysExitMode code)

The exit strategy. References the "Segment exit mode" (SysSegmentExitMode code) object.

"Population mode" (SysRefreshMode code)

The actualization schedule. Determines how Creatio populates the segment: "Static list" (on demand only) or "Scheduled" (automatically, based on the segment schedule). Scheduled population is available in version 10.1 and later. References the "Segment refresh mode" (SysSegmentRefreshMode code) object.

"Refresh cron expression" (RefreshCronExpression code)

The Quartz cron expression that defines the population schedule. Creatio fills it based on the Population time, How often, and Day of the week fields of the segment page. An empty value means the segment is not scheduled. Learn more: Methods.

"Refresh time zone id" (RefreshTimeZoneId code)

The ID of the time zone in which the schedule runs. Creatio fills it based on the Time zone field of the segment page. An empty value means UTC.

"Schedule start date" (ScheduleStartDate code)

The date on which the schedule starts, in the time zone set by the "Refresh time zone id" (RefreshTimeZoneId code) column. An empty value means no start limit.

"Schedule end date" (ScheduleEndDate code)

The date on which the schedule ends, in the time zone set by the "Refresh time zone id" (RefreshTimeZoneId code) column. An empty value means no end limit.

"Population status" (SysStatus code)

The current processing state, such as "Draft," "Queued," "Calculating," "Populated," or "Error." References the "Segment system status" (SysSegmentSystemStatus code) object.

"Is usable while updating" (IsUsableWhileUpdating code)

Indicates whether the segment is safe to use in a segment membership filter. System-managed based on the segment status. Not exposed in the UI.

"Segment data table name" (SegmentDataTableName code)

The physical membership table name. Managed automatically. Do not edit manually.

"Current contacts" (RecordCount code)

The last known active member count, updated by the Actualize endpoint. Learn more: Actualize a segment.

An active segment cannot be edited: its entry rules, exit rules, target entity, and population schedule are locked. To change these, deactivate or pause the segment first. An active segment can still be repopulated using its existing rules, for example, through the Actualize endpoint or the Resume segment button.

Schedule segment population​

Since version 10.1, a scheduled segment keeps its membership up to date without manual actions. Creatio re-evaluates the entry rules defined on the Entry rules tab and the exit rules defined on the Exit rules tab of the segment page at every scheduled run. Users configure the schedule on the segment page. Learn more: Set up and manage segments (user documentation).

Creatio creates one persistent Quartz job per scheduled segment and reconciles the jobs at every app or node start, so schedules survive restarts. Each scheduled run starts the same actualization job as on-demand population. This way, runs of the same segment never overlap, and a failure in one segment does not affect others.

If the "Refresh cron expression" (RefreshCronExpression code) column of a scheduled segment is filled, activating or resuming the segment sets the segment status to "Active" but does not populate the segment immediately. The first population runs at the next scheduled time, and the existing membership remains available until then. On-demand population, for example, through the Actualize endpoint, populates the segment immediately regardless of the population mode.

To manage scheduled population via source code, use the ISegmentScheduleService and ISegmentActualizationJobManager interfaces. We recommend setting the schedule using the ISegmentScheduleService interface instead of writing the "Refresh cron expression" (RefreshCronExpression code) and "Refresh time zone id" (RefreshTimeZoneId code) columns directly, for example, using the UpdateQuery DataService class. The interface returns validation errors as a result instead of throwing exceptions. Learn more: Segment scheduling API.

Important

In multi-node deployments, enable clustering of the Quartz job store (quartz.jobStore.clustered=true). Otherwise, each scheduled run can fire on multiple nodes. Learn more: Customize quartz task scheduler.

Read segments via DataService​

The "Segment" (SysDataSegment code) object is a regular entity, so you can list and read segments using the SelectQuery DataService class. The InsertQuery DataService class also works to create segments via source code. Creatio provisions the membership table automatically on insert. Deleting the segment record, regardless of method, drops the table. The membership table schema is fixed and managed by the engine: do not add columns to it or write to it directly. Use the Actualize and Truncate endpoints instead.

Request string​

POST /0/DataService/json/SyncReply/SelectQuery

List segments or read a single segment.

Request body​

Parameter

Type

Required

Description

rootSchemaName

string

Yes

The code of the object schema to query. Set to "SysDataSegment."

rowCount

integer

No

The maximum number of rows to return.

columns

object

Yes

The columns to select, as expression/columnPath pairs.

filters

object

No

A filter, in the same JSON format as an entry filter. Add it to read a single segment, for example, to fetch its EntryFilterData value before editing.

Usage example​

The following example lists segments and returns their "Id" (Id code), "Name" (Name code), "Segment of" (EntitySchema code), and "Current contacts" (RecordCount code) columns.

Request body
{
"rootSchemaName": "SysDataSegment",
"rowCount": 50,
"columns": {
"items": {
"Id": {
"expression": {
"expressionType": 0,
"columnPath": "Id"
}
},
"Name": {
"expression": {
"expressionType": 0,
"columnPath": "Name"
}
},
"EntitySchema": {
"expression": {
"expressionType": 0,
"columnPath": "EntitySchema.Name"
}
},
"RecordCount": {
"expression": {
"expressionType": 0,
"columnPath": "RecordCount"
}
}
}
}
}

Creatio may omit default-valued fields from the response. Do not rely on their presence.

Filter segments​

Filter structure​

A segment filter is either a leaf, a single comparison, or a group, a set of child filters joined by a logical operator. The simplest match-everything filter is an empty group which matches every record of the target entity. A null or blank EntryFilterData value is not the same: actualization rejects it because the segment entry filter is missing, so use {} to mean the whole population. The following example is a match-everything filter.

Match-everything filter
{
"filterType": 6,
"logicalOperation": 0,
"isEnabled": true,
"items": {}
}

A comparison filter leaf has a left side, usually a column, a comparison operator, and a right side, usually a literal value. The following example is a comparison filter leaf that matches contacts named exactly "Andrew Baker."

Comparison filter leaf
{
"filterType": 1,
"comparisonType": 3,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "Name"
},
"rightExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 1,
"value": "Andrew Baker"
}
}
}

All wire-level enums are integers, not strings. Send "filterType": 1, never "filterType": "CompareFilter".

This filter deserializes to the same Filter type that the SelectQuery DataService class accepts, so entry filters and DataService filters share the same syntax. The same filter, including the segment membership filter, also works in C# code through the EntitySchemaQuery class. Learn more about this type: Filters class. Segments and DataService queries share the same underlying filter language:

  • A segment's EntryFilterData value, the rule that decides which records belong in the segment, is JSON text in this format.
  • The same format also describes the segment membership filter you use to check whether a record belongs to a segment.

Segment membership filters​

To activate the segment membership filter, make sure the UseSegmentFiltering additional feature is enabled. Instructions: Change the status of an additional feature for all users. When the feature is disabled, segment filters throw a NotSupportedException.

A segment filter, "filterType": 7, keeps only the records that are, or are not, members of a saved segment. Unlike a comparison filter leaf, it has no leftExpression or rightExpression: the segment to check and which membership rows count are carried instead by the segmentFilterOptions object, and comparisonType may only be "15," (the record is a segment member), or "16" (the record is not a segment member). The segment target entity must match the query rootSchemaName.

Creatio tracks whether a segment is safe to use in filters through the "Is usable while updating" (IsUsableWhileUpdating code) column on the "Segment" (SysDataSegment code) object. Creatio sets this system-managed column automatically based on the segment status. It is not exposed in the UI. When a segment membership filter references a segment whose IsUsableWhileUpdating value is "false," Creatio throws an explicit error instead of returning empty or partial results.

The segmentFilterOptions object supports several columns, for example, segmentId, includeRemovedMembers, and ignoreUserStatus. Learn more: Filter object.

Usage examples​

Each example is a complete EntryFilterData value.

Filter by equality​

The following example is a filter that matches contacts named exactly "Andrew Baker."

Filter by equality
{
"filterType": 1,
"comparisonType": 3,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "Name"
},
"rightExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 1,
"value": "Andrew Baker"
}
}
}

Filter by substring​

The following example is a filter that matches contacts whose email contains "@creatio.com." The match is case-insensitive.

Filter by substring
{
"filterType": 1,
"comparisonType": 11,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "Email"
},
"rightExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 1,
"value": "@creatio.com"
}
}
}

Filter by a lookup value​

The following example is a filter that matches contacts whose Type field is set to the "Employee" lookup value.

Filter by a lookup value
{
"filterType": 1,
"comparisonType": 3,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "Type"
},
"rightExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 10,
"value": "60733efc-f36b-1410-a883-16d83cab0980"
}
}
}

Filter by an empty value​

The following example is a filter that matches contacts with no email set.

Filter by an empty value
{
"filterType": 2,
"comparisonType": 1,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "Email"
}
}

Filter by a range​

The following example is a filter that matches contacts born in the 1990s.

Filter by a range
{
"filterType": 3,
"comparisonType": 0,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "BirthDate"
},
"rightGreaterExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 8,
"value": "1990-01-01"
}
},
"rightLessExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 8,
"value": "1999-12-31"
}
}
}

Filter by a group of conditions​

To build more complex conditions, switch logicalOperation to "1" for Or, and nest additional groups inside items to express (A AND B) OR C. The keys inside items, for example, NameContainsCreatio, are arbitrary labels — choose descriptive names.

The following example is a filter that matches contacts whose name contains "creatio" and whose Type field is set to the "Employee" lookup value.

Filter by a group of conditions
{
"filterType": 6,
"logicalOperation": 0,
"isEnabled": true,
"items": {
"NameContainsCreatio": {
"filterType": 1,
"comparisonType": 11,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "Name"
},
"rightExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 1,
"value": "creatio"
}
}
},
"IsEmployee": {
"filterType": 1,
"comparisonType": 3,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "Type"
},
"rightExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 10,
"value": "60733efc-f36b-1410-a883-16d83cab0980"
}
}
}
}
}

Filter by current membership​

The following example is a filter that matches contacts who are current members of a segment.

Filter by current membership
{
"filterType": 7,
"comparisonType": 15,
"isEnabled": true,
"segmentFilterOptions": {
"segmentId": "11111111-1111-1111-1111-111111111111"
}
}

Filter by non-membership​

The following example is a filter that matches contacts who are not members of a segment.

Filter by non-membership
{
"filterType": 7,
"comparisonType": 16,
"isEnabled": true,
"segmentFilterOptions": {
"segmentId": "11111111-1111-1111-1111-111111111111"
}
}

Filter by past membership​

The following example is a filter that also matches contacts who have since left the segment, since includeRemovedMembers: true drops the active-only restriction.

Filter by past membership
{
"filterType": 7,
"comparisonType": 15,
"isEnabled": true,
"segmentFilterOptions": {
"segmentId": "11111111-1111-1111-1111-111111111111",
"includeRemovedMembers": true
}
}

Filter by membership in a paused segment​

The following example is a filter that matches a segment whose user status is "Paused." ignoreUserStatus: true lets you filter by a segment whose user status is "Paused." The system/lifecycle-status gate still applies.

Filter by membership in a paused segment
{
"filterType": 7,
"comparisonType": 15,
"isEnabled": true,
"segmentFilterOptions": {
"segmentId": "11111111-1111-1111-1111-111111111111",
"ignoreUserStatus": true
}
}

Filter by membership added in a date window​

The following example is a filter that matches members whose AddedOn column falls within a range. Timestamps, including addedOnFrom and addedOnTo, are in UTC using the ISO 8601 format. Every *On column follows the same format.

Filter by membership added in a date window
{
"filterType": 7,
"comparisonType": 15,
"isEnabled": true,
"segmentFilterOptions": {
"segmentId": "11111111-1111-1111-1111-111111111111",
"addedOnFrom": "2026-01-01",
"addedOnTo": "2026-03-31"
}
}

Filter by membership combined with other conditions​

The following example is a filter that matches members of the segment whose Type field is set to the "Employee" lookup value: it nests the segment leaf and a compare leaf inside a "filterType": 6 group.

Filter by membership combined with other conditions
{
"filterType": 6,
"logicalOperation": 0,
"isEnabled": true,
"items": {
"InSegment": {
"filterType": 7,
"comparisonType": 15,
"isEnabled": true,
"segmentFilterOptions": {
"segmentId": "11111111-1111-1111-1111-111111111111"
}
},
"IsEmployee": {
"filterType": 1,
"comparisonType": 3,
"isEnabled": true,
"leftExpression": {
"expressionType": 0,
"columnPath": "Type"
},
"rightExpression": {
"expressionType": 2,
"parameter": {
"dataValueType": 10,
"value": "60733efc-f36b-1410-a883-16d83cab0980"
}
}
}
}
}

Error handling​

Errors related to the request data return the "200 OK" HTTP status code with "success": false. Distinguish them by the success property of the response body, not the HTTP status code. Match on "success": false plus a stable errorMessage prefix. Do not pattern-match on inner exception text, since it can change.

Error

Type

Description

Solution

Segment with Id '<Guid>' not found

Data-level problem

An invalid segment ID.

Verify the ID. Do not retry.

Filter evaluation error: ...

Data-level problem

The entry filter is malformed JSON.

Re-validate the filter JSON. Do not retry.

Filter evaluation error: ...

Data-level problem

The filter references an unknown column.

Check column names against the "Object" type schema.

... data table '<name>' does not exist ...

Data-level problem

The membership table is missing.

Re-create the segment so Creatio provisions the table. Never insert segments with raw SQL.

... Enable the 'UseSegmentFiltering' feature.

Data-level problem

A segment filter is used while the UseSegmentFiltering additional feature is disabled.

Enable the UseSegmentFiltering additional feature.

... actualization is in progress.

Data-level problem

Truncate is called during actualization.

Retry after the current run finishes.

"403 Forbidden" or "302 Found" HTTP status codes

Transport-level problem

Missing or invalid CRT_CSRF cookie or session.

Re-authenticate. Include CRT_CSRF on every POST request.

"400 Bad Request" HTTP status code

Transport-level problem

The request body is malformed.

Fix the request body syntax. Do not retry without fixing.


See also​

Segmentation Engine API endpoints

Filter object

Filters class

Segments (user documentation)

Set up and manage segments (user documentation)