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.
name
The name of the fence. It must be unique.
nameLocalized
An object containing the localized names of the fence for different languages.
description
An optional description to say what the fence has to do. Although optional, it's recommended that you provide a meaningful description.
descriptionLocalized
An object containing the localized descriptions for different languages.
entity1
The entity type for the left side. For conditional rules, this is the entity that's evaluated first.
ORDERORDERING_FACILITYORDERING_FACILITY_GROUPS
entity2
The entity type for the right side. For conditional rules, this is the entity that gets evaluated second (or not at all).
FACILITYCARRIERCONNECTIONLISTING
type
Defines whether it's a custom fence or rating.
ToolkitFenceToolkitRating
referenceId
An identifier for the fence or the rating. Use a descriptive identifier.
active
Defines whether the fence or rating is active.
truefalse
order
Fences only. Determines whether the fence should be executed before or after different fences. Lower numbers have precedence over higher numbers.
maxPenalty
Ratings only. Determines the weight of the rating in comparison to other ratings. The higher the number, the more important it is.
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:
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_ENTITYLINE_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.
See the Conditional rule parts section.
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.
See the Conditional rule parts section.
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.
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.
ANDOR
Conditional rule predicates
predicates is an array that consists of the following fields. At least one predicate must be defined. Maximum of 100 predicates.
entity
The entity type that can be compared.
ORDERFACILITYCARRIERCONNECTIONLISTINGORDERING_FACILITY- left side onlyORDERING_FACILITY_GROUPS- left side only
entityOperator
The operators determine how an entity's property should be compared to a given value.
See the Entity operators section.
expectedValue
The expected value that the property should match. For example, 2 (number), "WAREHOUSE" (string), "2024-02-19T16:16:38.107Z" (date-string).
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.
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:
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_ENTITYLINE_ITEM
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.
ANDOR
Comparison rule predicates
predicates is an array that consists of the following fields. At least one predicate must be defined. Maximum of 100 predicates.
entityOperator
The operators determine how an entity's property should be compared to a given value.
See the Entity operators section.
leftEntity
The entities that the rating can compare.
ORDERFACILITYCARRIERCONNECTIONLISTINGORDERING_FACILITYORDERING_FACILITY_GROUPS
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.
ORDERFACILITYCARRIERCONNECTIONLISTING
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.
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:
$.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:
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 elementsCOUNT: Counts the number of elements, requires an array of elementsSUBSTRING: Gets a substring of a value, requiresstartandendparametersLAST: Gets the lastncharacters of a string, requires alengthparameter
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

