Data Search Step
Use this step to search and retrieve records from your organization's datasets. Configure search criteria with filters, sorting, and linked entity relationships. Display results in customizable tables with optional confirmation pages.
Top-level properties
| name | type | required | constraints | description |
|---|---|---|---|---|
datasets | array | yes | items: dataset | One or more dataset search configurations |
Dataset
| name | type | required | constraints | description |
|---|---|---|---|---|
datasetId | string | yes | Identifier of the dataset to search | |
setup | object | yes | type: DataSearchSetup | Search configuration including criteria and selection mode |
results | object | yes | type: DataSearchResults | Results display configuration |
Setup
| name | type | required | constraints | description |
|---|---|---|---|---|
required | boolean | yes | Whether a selection is mandatory for workflow continuation | |
selectionMode | string | yes | enum: AUTOMATIC, MANUAL | How results are selected: automatic picks first match, manual requires user selection |
primarySearchCriteria | object | yes | type: SearchCriteria | Main search criteria for the primary dataset |
linkedEntitiesFilters | object | yes | Additional filters for linked entities (key: entity identifier, value: SearchCriteria) |
Selection Modes
AUTOMATIC: Automatically selects the first matching resultMANUAL: Requires user to manually select from search results
Search Criteria
| name | type | required | constraints | description |
|---|---|---|---|---|
sortFieldId | string | yes | Field identifier to sort results by | |
sortDirection | string | yes | enum: ASCENDING, DESCENDING | Sort order direction |
joinLogic | string | yes | enum: AND, OR | How multiple filters are combined |
filters | array | yes | items: SearchCriteriaFilter | Array of filter conditions |
Sort Directions
ASCENDING: Sort from lowest to highest (A-Z, 0-9)DESCENDING: Sort from highest to lowest (Z-A, 9-0)
Join Logic
AND: All filters must match (intersection)OR: Any filter can match (union)
Search Criteria Filter
| name | type | required | constraints | description |
|---|---|---|---|---|
fieldId | string | yes | nullable: true | Field identifier to filter on |
operator | string | yes | enum: EQUALS, NOT_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUALS, LESS_THAN, LESS_THAN_OR_EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH; nullable: true | Comparison operator |
value | string | yes | nullable: true; supports mapping pattern: {{Step.Field}} | Filter value (literal, mapped from workflow data, or empty string) |
Operators
EQUALS: Exact matchNOT_EQUALS: Not equal to valueGREATER_THAN: Numeric or date comparisonGREATER_THAN_OR_EQUALS: Greater than or equalLESS_THAN: Less than valueLESS_THAN_OR_EQUALS: Less than or equalCONTAINS: String contains substringSTARTS_WITH: String begins with valueENDS_WITH: String ends with value
Results
| name | type | required | constraints | description |
|---|---|---|---|---|
showConfirmationPage | boolean | yes | Whether to display a confirmation page after selection | |
tableMode | string | yes | enum: DEFAULT, CUSTOM | Table display mode: default shows all fields, custom shows only specified fields |
fields | array | yes | items: DataSearchResultsField | Fields to display in results table (required when tableMode is CUSTOM) |
Table Modes
DEFAULT: Display all available fields from the datasetCUSTOM: Display only the fields specified infieldsarray
Results Field
| name | type | required | constraints | description |
|---|---|---|---|---|
fieldId | string | yes | nullable: true | Field identifier from dataset |
customLabel | string | yes | Display label for the field in results table |
Minimal Example (JSON)
{
"datasets": [
{
"datasetId": "contacts_db",
"setup": {
"required": true,
"selectionMode": "AUTOMATIC",
"primarySearchCriteria": {
"sortFieldId": "last_name",
"sortDirection": "ASCENDING",
"joinLogic": "AND",
"filters": []
},
"linkedEntitiesFilters": {}
},
"results": {
"showConfirmationPage": false,
"tableMode": "DEFAULT",
"fields": []
}
}
]
}Full Example (JSON)
{
"datasets": [
{
"datasetId": "customer_records",
"setup": {
"required": true,
"selectionMode": "MANUAL",
"primarySearchCriteria": {
"sortFieldId": "last_name",
"sortDirection": "ASCENDING",
"joinLogic": "AND",
"filters": [
{
"fieldId": "email",
"operator": "EQUALS",
"value": "{{`form`.`email`}}"
},
{
"fieldId": "status",
"operator": "EQUALS",
"value": "active"
},
{
"fieldId": "created_date",
"operator": "GREATER_THAN_OR_EQUALS",
"value": "2024-01-01"
}
]
},
"linkedEntitiesFilters": {
"orders": {
"sortFieldId": "order_date",
"sortDirection": "DESCENDING",
"joinLogic": "OR",
"filters": [
{
"fieldId": "status",
"operator": "NOT_EQUALS",
"value": "cancelled"
},
{
"fieldId": "total_amount",
"operator": "GREATER_THAN",
"value": "100"
}
]
}
}
},
"results": {
"showConfirmationPage": true,
"tableMode": "CUSTOM",
"fields": [
{
"fieldId": "customer_id",
"customLabel": "Customer ID"
},
{
"fieldId": "first_name",
"customLabel": "First Name"
},
{
"fieldId": "last_name",
"customLabel": "Last Name"
},
{
"fieldId": "email",
"customLabel": "Email Address"
},
{
"fieldId": "phone",
"customLabel": "Phone Number"
}
]
}
}
]
}TypeScript Example
import {
dataSearchStepConfig,
type DataSearchStepConfig,
} from '@odin/workflows-schema';
const searchStep: DataSearchStepConfig = {
datasets: [
{
datasetId: 'product_catalog',
setup: {
required: false,
selectionMode: 'MANUAL',
primarySearchCriteria: {
sortFieldId: 'product_name',
sortDirection: 'ASCENDING',
joinLogic: 'AND',
filters: [
{
fieldId: 'category',
operator: 'EQUALS',
value: '{{`form`.`category`}}',
},
{
fieldId: 'price',
operator: 'LESS_THAN_OR_EQUALS',
value: '{{`form`.`max_price`}}',
},
{
fieldId: 'product_name',
operator: 'CONTAINS',
value: '{{`form`.`search_term`}}',
},
],
},
linkedEntitiesFilters: {
inventory: {
sortFieldId: 'warehouse_id',
sortDirection: 'ASCENDING',
joinLogic: 'AND',
filters: [
{
fieldId: 'quantity',
operator: 'GREATER_THAN',
value: '0',
},
],
},
},
},
results: {
showConfirmationPage: true,
tableMode: 'CUSTOM',
fields: [
{
fieldId: 'product_id',
customLabel: 'Product ID',
},
{
fieldId: 'product_name',
customLabel: 'Product Name',
},
{
fieldId: 'price',
customLabel: 'Price',
},
{
fieldId: 'in_stock',
customLabel: 'In Stock',
},
],
},
},
],
};
// Validate the configuration
const result = dataSearchStepConfig.safeParse(searchStep);
if (result.success) {
console.log('Valid data search configuration');
} else {
console.error('Validation errors:', result.error);
}Updated 15 days ago
