Custom routing rules

Custom routing rules (previously known as the DOMS toolkit) help users define factors to consider when selecting the best fulfillment location.

Custom routing rules can be created in Backoffice or via API. We recommend using Backoffice to reduce errors. You'll still need to understand how to work with JSONPath.

You can define fences and ratings:

  • Fences: Exclude facilities from order routing based on to the selected fences.

  • Ratings: Weigh facilities against each other based on the selected ratings.

The table below outlines the fields for custom routing rule fences and ratings within the routing strategy endpoint.

Field
Type
Description
Possible values

name

string

The name of the fence. It must be unique.

nameLocalized

string

An object containing the localized names of the fence for different languages.

description

string

An optional description to say what the fence has to do. Although optional, it's recommended that you provide a meaningful description.

descriptionLocalized

string

An object containing the localized descriptions for different languages.

entity1

enum

The entity type for the left side. For conditional rules, this is the entity that's evaluated first.

  • ORDER

  • ORDERING_FACILITY

  • ORDERING_FACILITY_GROUPS

entity2

enum

The entity type for the right side. For conditional rules, this is the entity that gets evaluated second (or not at all).

  • FACILITY

  • CARRIERCONNECTION

  • LISTING

type

enum

Defines whether it's a custom fence or rating.

  • ToolkitFence

  • ToolkitRating

referenceId

string

An identifier for the fence or the rating. Use a descriptive identifier.

active

boolean

Defines whether the fence or rating is active.

  • true

  • false

order

integer

Fences only. Determines whether the fence should be executed before or after different fences. Lower numbers have precedence over higher numbers.

maxPenalty

integer

Ratings only. Determines the weight of the rating in comparison to other ratings. The higher the number, the more important it is.

rule

object

comparisonRule

object

Rules

Two rule types that can be defined:

Conditional rule

Use rule to set up a conditional rule. Conditional rules test a certain property of an entity (order, facility, listing) against a predefined static value. It can be used for comparing each side against a fixed value (for example, an order line item has a quantity greater than 3).

It can't be used when using the comparisonRule field.

A conditional rule must include:

Field
Description
Possible values

evaluationScope

Defines whether the order is evaluated as a single unit (WHOLE_ENTITY) or if each LINE_ITEM is evaluated separately. See the Evaluation scope section for more details.

  • WHOLE_ENTITY

  • LINE_ITEM

leftPart

The first part that's evaluated. The evaluation result determines whether the right part gets evaluated. It consists of an array of predicates and a predicateConnector that determines how they are connected.

operator

What the positive evaluation of the left side means for the execution of the fence as a whole. For now, there is only the equals operator.

  • EQUALS

rightPart

The second part is evaluated if the first evaluation passes. Its evaluation result determines the outcome of the fence. It consists of an array of predicates and a predicateConnector that determines how they are connected.

Conditional rule parts

The leftPart and the rightPart of a conditional rule must contain at least one predicates. If more than one is used, a predicateConnector must also be defined.

Field
Description
Possible values

predicates

An array of one or more predicates.

predicateConnector

AND will only make the expression true if all predicates evaluate to true. OR will make the rule expression true if any of the predicates evaluate to true.

  • AND

  • OR

Conditional rule predicates

predicates is an array that consists of the following fields. At least one predicate must be defined. Maximum of 100 predicates.

Field
Description
Possible values

entity

The entity type that can be compared.

  • ORDER

  • FACILITY

  • CARRIERCONNECTION

  • LISTING

  • ORDERING_FACILITY - left side only

  • ORDERING_FACILITY_GROUPS - left side only

entityOperator

The operators determine how an entity's property should be compared to a given value.

propertyPath

A JSONPath expression defining the property to look at.

expectedValue

The expected value that the property should match. For example, 2 (number), "WAREHOUSE" (string), "2024-02-19T16:16:38.107Z" (date-string).

transformation

[optional] A transformation.

transformationArgs

[optional] The arguments for the transformation, if required.

Depends on the transformation used. See the Transformers section.

Conditional rules entity operators

An entityOperator determines how an entity's property should be compared to a given value. They can be divided into two groups: Single value entity operators and array entity operators.

Single value entity operators

These operators can only be used for single values, not for arrays.

Operator
Description
Example

VALUE_EQUALS

Actual value equals expectedValue

2 == 2

VALUE_NOT_EQUALS

Actual value is not equal to the expectedValue

2 != 3

VALUE_CONTAINS

Actual value contains expectedValue

The value is HELLO WORLD, and the expectedValue is HELLO

VALUE_NOT_CONTAINS

Actual value doesn't contain expectedValue

The value is HELLO WORLD, and expectedValue is HI

LESS_THAN

Actual value is less than expectedValue

2 < 3

LESS_EQUALS

Actual value is less than or equal to the expectedValue

2 <= 3, 3 <= 3

GREATER_THAN

Actual value is greater than the expectedValue

3 > 2

GREATER_EQUALS

Actual value is greater than or equal to expectedValue

3 >= 2, 2 >= 2

Array entity operators

These operators can only be used for arrays, not for single values. They can be grouped into three categories:

  • ANY: Requires that at least one element of the array satisfies the following condition. If the array is empty, this condition won't be fulfilled.

  • EVERY: Requires that every element of the array satisfies the following condition. If the array is empty, this condition will be true because no element doesn't fulfill the condition.

  • NONE: Requires that no element satisfies the following condition, meaning that every element doesn't satisfy the condition. This condition will always be fulfilled, unless there is an element that satisfies the condition, including for empty arrays.

Possible operator values:

ANY_VALUE_EQUALS

ANY_VALUE_GREATER_EQUALS

ANY_VALUE_GREATER_THAN

ANY_VALUE_LESS_EQUALS

ANY_VALUE_LESS_THAN

ANY_VALUE_NOT_CONTAINS

EVERY_VALUE_EQUALS

EVERY_VALUE_GREATER_EQUALS

EVERY_VALUE_GREATER_THAN

EVERY_VALUE_LESS_EQUALS

EVERY_VALUE_LESS_THAN

EVERY_VALUE_CONTAINS

EVERY_VALUE_NOT_CONTAINS

NO_VALUE_EQUALS

NO_VALUE_GREATER_EQUALS

NO_VALUE_GREATER_THAN

NO_VALUE_LESS_EQUALS

NO_VALUE_LESS_THAN

NO_VALUE_CONTAINS

NO_VALUE_NOT_CONTAINS

Single value operators versus array operators

If your actual value is an array, you have to use an array operator. For example, if you use a wildcard operator (* or ?()), you'll get an array of elements (such as $.orderLineItems[*]). However, if you use a transformer (such as COUNT to get the number of elements or SUM to add the quantities of each orderLineItem), then you will get a single value and must use a single value operator.

Comparison rule

Use comparisonRule to set up a comparison rule. Comparison rules compare a property of the left-hand side (order) with a property of the right-hand side (order, facility, listing). Incompatible with using the rule field.

An example of this could be an order with products of a certain brand that requires a facility tagged with the same brand.

A comparison rule must include:

Field
Description
Possible values

evaluationScope

Defines whether the order is evaluated as a single unit (WHOLE_ENTITY) or if each LINE_ITEM is evaluated separately. See the Evaluation scope section for more details.

  • WHOLE_ENTITY

  • LINE_ITEM

predicates

An array of one or more predicates.

predicateConnector

AND will only make the expression true if all predicates evaluate to true. OR will make the rule expression true if any of the predicates evaluate to true.

  • AND

  • OR

Comparison rule predicates

predicates is an array that consists of the following fields. At least one predicate must be defined. Maximum of 100 predicates.

Field
Description
Possible values

entityOperator

The operators determine how an entity's property should be compared to a given value.

leftEntity

The entities that the rating can compare.

  • ORDER

  • FACILITY

  • CARRIERCONNECTION

  • LISTING

  • ORDERING_FACILITY

  • ORDERING_FACILITY_GROUPS

leftPropertyPath

A string containing a JSONPath for the left entity.

leftTransformation

[optional] The transformation for the left entity.

leftTransformationArgs

[optional] The arguments for the left transformation, if required.

Depends on the transformation used. See the Transformers section.

rightEntity

The entities that the rating can compare.

  • ORDER

  • FACILITY

  • CARRIERCONNECTION

  • LISTING

rightPropertyPath

A string containing a JSONPath for the right entity.

rightTransformation

The transformation for the right entity.

rightTransformationArgs

The transformation arguments for the right transformation, if required.

Depends on the transformation used. See the Transformers section.

Comparison rules entity operators

An entityOperator determines how an entity's property should be compared to a given value.

Operator
Description

LEFT_CONTAINS_RIGHT

The left-hand side should contain all values from the right-hand side.

RIGHT_CONTAINS_LEFT

The right-hand side should contain all values from the left-hand side.

ALL_MATCHES

The arrays of values should be exactly equal.

NO_MATCHES

Values should be different, even when comparing a list with a single value (blocklist case).

Introduction to JSONPath

We use JSONPath for creating custom routing rules. You'll need to understand the operators, functions, and filters to ensure the custom routing rule works as expected. You can find the full information in the JSONPath documentation. You can also use a JSONPath expression tester tool to ensure your path is valid.

JSONPaths are used in propertyPath for conditional rules and leftPropertyPath and rightPropertyPath for comparison rules.

JSONPaths always begin with $, which refers to the entity that's defined in the predicate, for example, an ORDER. Nested properties are accessed using .. Nested array properties, such as orderLineItems, tags, or stickers, are accessed using array brackets ([ and ]) with * to indicate a wildcard. For example, $.orderLineItems[*].quantity.

Instead of a wildcard (*), you can use the ?() syntax. You can then define an arbitrary expression inside the parentheses using the @ symbol to refer to the entity being tested.

For more specific filtering, use ?() instead of *. Inside the parentheses, define an arbitrary expression using @ to refer to the entity being tested. You can then access all of its nested attributes and test for an arbitrary condition.

Let's look at some more examples:

Expression
Description

$.tenantOrderId

Gets the order with the specified tenantOrderId.

$.orderLineItems[*].article

Gets the articles from all orderLineItems, resulting in an array.

$.orderLineItems[?(@.quantity > 3)].article

Gets the articles from orderLineItems with a quantity greater than 3.

$.orderLineItems[?(@.tags.find(tag => tag.id === 'color' && tag.value === 'red'))].article

Gets the articles of all OrderLineItems that have at least one tag of type color with the value red.

It's recommended to keep your expressions as simple as possible without compromising their functionality to avoid mistakes that could lead to misbehavior of the fence/rating.

Evaluation scope

evaluationScope allows you to set how the order will be evaluated. An evaluation scope of WHOLE_ENTITY evaluates the order as a single unit. Whereas with the scope LINE_ITEM, each order line is evaluated separately.

The difference in evaluationScope applies only when the left side of the rule doesn't reference the entire order but operates on the orderLineItem level.

Evaluation scope example

Let's say we set up the following custom fence definition:

Left part

Right part

Depending on whether we set the evalutionScope to WHOLE_ENTITY or LINE_ITEM, we will see different behavior:

WHOLE_ENTITY
LINE_ITEM

If at least one orderLineItem has the tag FAST_RUNNER = true, the entire order must be routed to warehouse locations.

Only orderLineItems with the tag FAST_RUNNER = true must be routed to warehouse locations. The remaining items can potentially also be routed to locations with types other than warehouse.

Transformers

transformation allows for modifying the input to predicates before it gets evaluated. This can serve multiple purposes. For example, only look at the number of elements, get the total price of all orderLineItems, or only consider the beginning of the tenantOrderId.

The transformations currently available are:

  • SUM: Sums the number values of each element, requires an array of elements

  • COUNT: Counts the number of elements, requires an array of elements

  • SUBSTRING: Gets a substring of a value, requires start and end parameters

  • LAST: Gets the last n characters of a string, requires a length parameter

Count transformation

Applies to orders with 10 or more orderLineItems.

Sum transformation

Applies to orders where the sum of all orderLineItems quantities is 100 or more.

Substring transformation

Applies to orders where any orderLineItem has a tenantArticleId that begins with Coca. Here, we use transformationArgs to ensure that the first 4 letters are used.

Last characters transformation

Applies to orders where any orderLineItem has a tenantArticleId that ends with Christmas special

Time specifications

It's possible to define a time specification as an expected value, enabling dynamic comparisons during routing processes. For example, a timestamp stored in a customAttribute can be compared against the current time using predefined expressions.

  • {today}: represents the current day, based on the tenant's configured time zone. This expression refers to a date value (for example, 2025-08-07).

  • {now}: represents the current timestamp, calculated in UTC+0. This expression refers to a specific timestamp (for example, 2025-08-07T18:00:00.000Z).

This functionality, for example, allows routing logic to determine whether an item is eligible for release to sales, based on time-based conditions.

When using the "entityOperator": "EQUALS" for timestamp comparisons, be aware that it includes minutes and seconds. This may lead to unintended mismatches unless the timestamps are precisely aligned.

Last updated