Although the Order Routing UI is the easiest way to configure routing resources, some configurations and testing can be performed via API. The Order Routing APIs are grouped into four topics for supporting data lists, filters, groups, and routing.
The schemas and request templates are available in the API documentation, but this guide provides a supplemental walkthrough to explain how to use these calls.
Data Lists
Custom data lists are used to create filters, allowing them to fine-tune which cases the filter should be applied for. For instance, if a particular location group cannot fulfill particular product UPCs then a custom data list could be created containing those UPCs. A filter could be applied to the group with that data list applied to the “Item UPC” attribute. This would result in the order being assigned to the group only if the UPC of the order item was not in the list.
The supported Data List operations are:
How Data Lists Work
A data list must be one of three types: String, Number, or Location. This is the type of values that will populate the list, determined by the dataType parameter.
The individual name:value pairs that populate the list are configured in the entries array. This array always identifies the note (or name) and value of the entry. This value is always input as a string regardless of the list type. For example, a String data list may be set as the following when creating or editing a data list:
"dataType": "STRING", "entries": [ { "notes": "Glassware Department", "stringValue": "Glassware" }, { "notes": "Picture Frame Department", "stringValue": "PictureFrame" }, { "notes": "Fragile Wood Department", "stringValue": "Fragile Wood" } ]
A Number data list may be set as the following:
"dataType": "NUMBER", "entries": [ { "notes": "Austin Labor Rate", "stringValue": "1.75" }, { "notes": "Dallas Labor Rate", "stringValue": "1.79" } ]
And a Location data list may be set as the following:
"dataType": "LOCATION", "entries": [ { "notes": "Location Code 1", "stringValue": "5201" }, { "notes": "Location Code 2", "stringValue": "5202" }, { "notes": "Location Code 3", "stringValue": "5203" } ]
Routing Filters
In Order Routing, filters are used to “filter out” fulfillers within a location group being routed to that do not match certain criteria. For example, a filter can be created so that orders can only be assigned or viewed if a fulfiller is located within 100 miles of the customer. Multiple filters can be applied to a group to further narrow the list of fulfillers. For example, two filters can be created so that the order can be only assigned or viewed if the fulfiller is located within 100 miles of the customer and the order total price is less than $1,000.
With the Order Routing APIs, filters can be created based on custom data as well as managed by retrieving existing filter information and deleting a filter. The supported Filter operations are:
- SaveCriteriaSetFilter
- SaveCustomDataListFilter
- SaveCustomDataValueFilter
- GetFilter
- DeleteFilter
- TestFilter
- TestSetFilter
Location Groups
Although location groups may be created and managed by the dedicated Location Group API, the Order Routing application also contains API extensions for adjusting groups specifically in the context of calculating routing. The supported Group operations are:
Locations can be added and removed via these operations, but the API is also used to set the sort options, filters, and failover/restart behaviors.
Routing Candidates and Suggestions
The Routing API operations include different methods of testing your routing configuration and gathering routing data:
The Suggest Candidates operation is a resource used to filter fulfillment locations based on inventory and order routing rules. Rather than determine exactly where the shipment would be routed to if it were fulfilled immediately, the API returns a list of all eligible locations (candidates). The call works for all routing types and supports both partial and full cases in which locations have inventory. It is particularly useful with Ship to Home orders to calculate the estimated arrival time of a shipment.
The Suggest Routing (or Routing Suggestion) operation is used o answer the question, “Where exactly would this order be assigned if I were to create it now?” The response is the best routing assignment scenario, depending on the current inventory and routing filters or rules that are in place. The API will attempt to only return a single location assignment per item, if it can, in order to provide the most efficient order routing suggestion.
In both cases, the call does not assign the order to any location yet. Instead, it reports the selections that may be made by Order Routing if the order were actually being assigned. This makes the APIs useful for testing routing scenarios.
Comparison of Responses
The Candidates API will return a candidateSuggestions
collection of locations and their location data that the shipment could potentially be routed to, based on inventory and routing rules. That decisioning logic is included in the response in addition to the location information.
[ { "tenantID": 00000, "siteID": 11111, "environmentID": 1, "created": 1618581253685, "updated": 1618581253685, "creatorUsername": null, "updaterUsername": null, "suggestionID": 1001001, "orderID": 10, "externalResponseID": null, "events": [ { "type": "NEW_REQUEST", "name": null, "causeID": 97, "errors": null, "request": { "items": [ { "orderItemID": 00000, "partNumber": null, "sku": null, "quantity": 2, "customItemData": null, "itemDependency": null, "backorderable": true, "upc": "exampleItem" } ], "orderType": "DIRECTSHIP", "environmentID": 1, "shippingAddress": { "addressID": 01110, "addressLine1": "10 Example St", "city": "Test City", "countryCode": "US", "customerID": 10001, "latitude": 011111111110, "longitude": 100000000001, "phone": "9720001111", "postalCode": "750011", "state": "TX" }, "isExpress": true, "pickupLocationCode": null, "locationCodeWhiteList": [ "location1", "location2", "location3" ], "exclusionListLocationCode": [ "blacklistedLocation" ], "inventoryRequestType": "ANY", "externalResponseID": null, "orderID": 10, "total": 123, "fraud": null, "customData": null, "bundlingStrategy": "ITEM_DEPENDENCY", "numShipmentsNotInRequest": 0 } }, { "type": "ROUTE_SELECTED", "name": "route.ordertype.directship", "causeID": 227, "errors": null, "tenantID": 00000, "siteID": 11111, "environmentID": 1, "orderType": "DIRECTSHIP", "route": "route.ordertype.directship:227", "active": true, "groups": [ "{groupID=100, name=Default, rank=1, isDefaultGroup=false, useRetailerExclusionList=true, afterActionPartial=GroupAfterAction(actionID=1453, name=null, failoverAction=QUANTITY_SPLIT_ASSIGN_IF_FULFILLED, restartAttempt=START_AT_BEGINNING), afterActionNone=GroupAfterAction(actionID=1452, name=null, failoverAction=LINE_ITEM_SPLIT_ASSIGN_IF_FULFILLED, restartAttempt=START_AT_BEGINNING), description=, active=true, fulfillmentLimit=null}" ] }, { "type": "INVENTORY_REQUEST", "name": null, "causeID": null, "errors": [], "request": { "locationCode": null, "userID": null, "pageSize": null, "pageNum": null, "sortBy": null, "type": "ANY", "items": [ { "partNumber": null, "upc": "exampleItem", "sku": "exampleItem", "quantity": 2 } ], "requestLocation": { "unit": "MILES", "radius": null, "postalCode": "12345", "latitude": null, "longitude": null, "countryCode": "US", "locationCode": null }, "limit": 1000, "locationWhitelist": [ "location1", "location2", "location3" ], "locationPriorityList": null, "locationBlacklist": null, "ignoreSafetyStock": false, "includeNegativeInventory": null, "directShip": true, "transferEnabled": null, "pickup": null, "includeInAggregateExport": null, "includeInLocationExport": null, "excludeBlockedAssignment": true, "includeAttributes": false, "sortByEnum": null, "tags": null }, "tenantID": 00000, "siteID": 11111, "environmentID": 1, "orderID": 10, "responseTimeMillis": 140, "response": [ { "success": null, "messages": null, "numResults": null, "locationName": "Store One", "locationCode": "location1", "tenantID": 00000, "onHand": 33, "available": 28, "allocated": 5, "pending": 0, "partNumber": null, "upc": "exampleItem", "sku": "exampleItem", "blockAssignment": false, "ltd": 0, "floor": 0, "safetyStock": 0, "distance": 711.8406819306866, "directShip": true, "transferEnabled": true, "pickup": true, "countryCode": "US", "currencyID": null, "retailPrice": null, "inventoryLocatorName": null, "attributes": null, "taggedInventory": null }, { "success": null, "messages": null, "numResults": null, "locationName": "Location Two", "locationCode": "location2", "tenantID": 00000, "onHand": 242, "available": 206, "allocated": 36, "pending": 0, "partNumber": null, "upc": "exampleItem", "sku": "exampleItem", "blockAssignment": false, "ltd": 0, "floor": 10, "safetyStock": 0, "distance": 1559.822496185389, "directShip": true, "transferEnabled": true, "pickup": true, "countryCode": "US", "currencyID": null, "retailPrice": null, "inventoryLocatorName": null, "attributes": null, "taggedInventory": null } ] }, { "type": "GROUP", "name": "Default", "causeID": 676, "errors": null, "group": "{groupID=100, name=Default, rank=1, isDefaultGroup=false, useRetailerExclusionList=true, afterActionPartial=GroupAfterAction(actionID=1453, name=null, failoverAction=QUANTITY_SPLIT_ASSIGN_IF_FULFILLED, restartAttempt=START_AT_BEGINNING), afterActionNone=GroupAfterAction(actionID=1452, name=null, failoverAction=LINE_ITEM_SPLIT_ASSIGN_IF_FULFILLED, restartAttempt=START_AT_BEGINNING), description=, active=true, fulfillmentLimit=null}", "locations": [ { "location": { "locationID": 33333, "locationCode": "Location One", "name": "location1", "tenantID": 00000, "express": false, "active": true, "postalCode": "29681-2913", "countryCode": "US", "latitude": 34.7335, "longitude": -82.2496, "directShip": true, "transferEnabled": true, "pickup": true, "state": "SC", "created": 1600361525000, "updated": 1611240378000, "formattedAddress": ", SC 29681-2913\nUS", "addressAsOneLine": ", SC 29681-2913, US" }, "group": null, "distance": "711.8406819306866 mi", "rank": 2, "maxLTDValueInInventory": 0, "inventoryCollection": [ { "partNumber": null, "attributes": [], "ltd": 0, "floor": 0, "safetyStock": 0, "onHand": 33, "available": 28, "upc": "exampleItem", "sku": "exampleItem" } ] }, { "location": { "locationID": 44444, "locationCode": "location2", "name": "Location Two", "tenantID": 00000, "express": false, "active": true, "postalCode": "78758", "countryCode": "US", "latitude": 30.3867, "longitude": -97.7083, "directShip": true, "transferEnabled": true, "pickup": true, "state": "TX", "created": 1596425613000, "updated": 1616679718000, "formattedAddress": ", TX 78758\nUS", "addressAsOneLine": ", TX 78758, US" }, "group": null, "distance": "1559.822496185389 mi", "rank": 1, "maxLTDValueInInventory": 0, "inventoryCollection": [ { "partNumber": null, "attributes": [], "ltd": 0, "floor": 10, "safetyStock": 0, "onHand": 242, "available": 206, "upc": "exampleItem", "sku": "exampleItem" } ] } ] }, { "type": "GROUP_SORT", "name": "Default", "causeID": 676, "errors": [], "sorts": [], "inputLocations": [ "location1", "location2" ], "outputLocations": [ "location2", "location1" ] }, { "type": "FOUND_FULL_ORDER_LOCATION", "name": "Location Two", "causeID": 81960, "errors": null }, { "type": "RESPONSE", "name": null, "causeID": null, "errors": null, "externalResponseID": null, "response": { "assignmentSuggestions": { "1": [ { "orderItemID": 1, "locationID": 44444, "locationCode": "location2", "quantity": 2 } ] }, "stateChangeSuggestions": { }, "availableLocations": [], "responseID": null, "externalResponseID": null, "suggestionLog": null } } ], "persisted": true, "pathString": "/29195/47906/1" } ]
The Suggestion API will return the collection of suggested location assignments OR state changes for each order item, based on current inventory and routing rules. There is one entry for each order item – in the example, one order item receives a suggested fulfillment location while the other order item could not be fulfilled by any location and thus the suggestion is to cancel the item instead.
{ "assignmentSuggestions": { "11111111": [ { "orderItemID": 11111111, "locationID": 000000, "quantity": 1 } ] }, "stateChangeSuggestions": { "00000000": { "orderItemID": 00000000, "stateChange": "CANCEL", "quantity": 1 } }, "availableLocations": [], "responseID": 354608901, "externalResponseID": null, "suggestionLog": null }