OrderAllocation (BETA)

Allocation API (BETA)

Ask the allocation engine which warehouses an order or basket would ship from, without changing the order, the cart, or inventory.

Beta

The allocation engine is in beta. Its behavior, settings, and API can change before general availability. To enable the engine in dev.omnium.no, please contact support.

The Allocation API runs the allocation engine as a simulation: it answers which warehouses (stores) an order or basket would ship from, how many shipments that makes, and which alternatives exist. Nothing is written - the order, the cart, and inventory are left as they are. A typical use is a checkout that wants to show delivery options or split-shipment information before the order is placed.

This is the same simulation the allocation simulator runs in the Omnium UI.

Endpoints

MethodEndpointDescription
POST/api/Allocation/SimulateWork out where an order or basket should ship from

The endpoint requires the Admin or ApiUser role.

Simulate allocation

Send exactly one subject:

  • orderId or cartId for an order or a cart that already exists in Omnium.
  • order or cart for a basket that does not exist in Omnium yet. A checkout normally sends the basket, since it does not exist in Omnium until the order is placed.

Request

FieldTypeDescription
OrderIdstringId of an order in Omnium
CartIdstringId of a cart in Omnium
OrderobjectAn order that is not stored in Omnium, in the same model as the Order API
CartobjectA basket that is not stored in Omnium, in the same model as the Cart API
ProfileKeysarrayAdditional profiles to rank the plans under, at most 10. Each adds a ranking after the primary profile's ranking. See profiles
InventoryOverridesarrayWhat-if availability per SKU and warehouse, at most 2000 entries. See inventory overrides
ReplaceInventoryWithOverridesboolWhen true, only the supplied availability is used and Omnium's own inventory is ignored. Default false
TriggerstringThe trigger the simulation runs as: InitialAllocation (default) or Reallocation. Allocation rules scoped to a trigger only take part when it matches
IncludeTraceboolWhen true, the response includes the engine's full reasoning in trace. Default false, since the trace is large

Profiles

A profile is a ranking policy. The primary profile decides selectedPlan and is always the first ranking. Omnium picks it in this order:

  1. The order's or cart's requestedAllocationProfileKey.
  2. The default profile in the allocation settings - set globally, and optionally overridden for the order's market or sales store.
  3. Balanced.

An unknown key is skipped and the next source is used. Profiles in profileKeys add more rankings after the primary one, so you can compare policies in one call. The plans are worked out once and each profile only orders them, so asking for three profiles costs little more than asking for one.

KeyRanks plans by
BalancedA mix of fewest shipments, distance, shipping cost, delivery probability, warehouse priority, and keeping lines where they are
FewestShipmentsFewest warehouses first
LowestCostLowest estimated shipping cost first
ClosestShortest distance to the customer first
HighestDeliveryProbabilityDeepest stock first, so the shipments are most likely to be picked in full
GreenestMainly estimated emissions, with distance and number of shipments, then warehouse priority

Inventory overrides

A checkout that already holds its own availability can pass it in inventoryOverrides instead of relying on Omnium's inventory. You can also use overrides to try a scenario, such as a warehouse running out of a product. The given values replace what Omnium holds for that SKU and warehouse; entries without a skuId or warehouseId are ignored.

FieldTypeDescription
SkuIdstringThe SKU, matching the order line code
WarehouseIdstringThe warehouse (store) code
AvailabledecimalUnits available to promise

Example: simulate a basket at checkout

POST /api/Allocation/Simulate
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
  "cartId": "C123456",
  "profileKeys": ["Closest"],
  "inventoryOverrides": [
    { "skuId": "1003456-42", "warehouseId": "S077", "available": 0 }
  ],
  "includeTrace": false
}

Response

FieldTypeDescription
RequestIdstringIdentifies this run
OutcomestringThe result of the run. See outcomes
PrimaryProfileKeystringThe profile that decided the selected plan
SelectedPlanobjectThe plan at the top of the primary ranking. null when no plan was found
PlansarrayEvery feasible plan. Rankings refer to them by planId
RankingsarrayOne ordered list of plans per requested profile, the primary profile first
UnallocatableLinesarrayLines no warehouse could serve, each with the reasons why
TracearrayThe engine's reasoning. Only included when includeTrace is true
ConfigurationVersionstringThe version of the allocation configuration the decision was made against
TotalMslongHow long the run took, in milliseconds

Plan

FieldTypeDescription
PlanIdstringIdentifies the plan. The same decision gets the same id across runs
ShipmentsarrayThe shipments the plan creates, one per warehouse and shipment
EstimatedShippingCostdecimalEstimated internal shipping cost, when the shipping options carry costs
TotalDistanceKmdoubleTotal distance from the sending warehouses to the destination, when coordinates are known
DeliveryProbabilitydecimalFrom 0 to 1: how likely it is that every shipment can be picked in full, given stock depth
IsPartialbooltrue when the plan leaves some lines unplaced
ShipmentCountintNumber of shipments the plan creates

Planned shipment

FieldTypeDescription
WarehouseIdstringThe warehouse code to ship from
SourceShipmentIdstringThe existing shipment this replaces, when the order already had one
ShippingMethodNamestringThe shipping method the plan chose, when it chose one
AllowedShippingMethodNamesarrayShipping methods that can be used from this warehouse
TotalWeightKgdoubleTotal weight of the shipment
DistanceKmdoubleDistance from the warehouse to the destination, when coordinates are known
LinesarrayThe order lines in the shipment

Planned line

FieldTypeDescription
LineIdstringThe order line id
SkuIdstringThe SKU
QuantitydecimalThe quantity this shipment carries
ArrivesOndatetimeWhen the goods reach the warehouse, if they are not there yet
PurchaseOrderIdstringThe purchase order the line waits for, if any
PurchaseOrderLineIdstringThe purchase order line the quantity comes from
DeliveryIdstringThe delivery within that purchase order

Ranking

FieldTypeDescription
ProfileKeystringThe profile this ranking is for
SelectedPlanIdstringThe plan this profile would choose
PlansarrayThe plans in order under this profile, best first. Each has planId, score, labels, and breakdown

In a ranked plan, score runs from 0 to 1 and the lowest score ranks first, the same direction as rule priority. It is the score of the profile's first tier; later tiers only break ties. breakdown holds the score per objective across all tiers, where lower is also better. labels says what the plan is best at, for showing to a customer: Recommended marks the first plan in that ranking, and FewestShipments, Cheapest, Closest, and MostLikelyToDeliver mark the plans that are best on that measure across all plans.

Unallocatable line and trace entry

An unallocatable line has lineId, skuId, quantity, and reasons - a list of trace entries.

FieldTypeDescription
StagestringThe engine stage the entry belongs to: Candidates, LineRules, Segmentation, ShipmentRules, or Scoring
KindstringInfo, WarehouseExcluded, WarehouseRestricted, WarehousePreferred, PlanRejected, Repaired, or Scored
MessagestringThe reason, as a stable key such as InsufficientStock. See reason keys
RuleIdstringThe allocation rule responsible, when a rule was
WarehouseIdstringThe warehouse the entry concerns
LineIdstringThe order line the entry concerns
PlanIdstringThe plan the entry concerns

Example response

{
  "requestId": "7f3c2a9e-51b4-4c8e-9d2a-0b6e1f4a8c73",
  "outcome": "Simulated",
  "primaryProfileKey": "Balanced",
  "selectedPlan": {
    "planId": "a41f09c2",
    "shipments": [
      {
        "warehouseId": "S012",
        "sourceShipmentId": null,
        "shippingMethodName": "HomeDelivery",
        "allowedShippingMethodNames": ["HomeDelivery", "PickupPoint"],
        "totalWeightKg": 2.4,
        "distanceKm": 18.6,
        "lines": [
          { "lineId": "1", "skuId": "1003456-42", "quantity": 1, "arrivesOn": null, "purchaseOrderId": null, "purchaseOrderLineId": null, "deliveryId": null },
          { "lineId": "2", "skuId": "2004871-M", "quantity": 2, "arrivesOn": null, "purchaseOrderId": null, "purchaseOrderLineId": null, "deliveryId": null }
        ]
      }
    ],
    "estimatedShippingCost": 79,
    "totalDistanceKm": 18.6,
    "deliveryProbability": 0.83,
    "isPartial": false,
    "shipmentCount": 1
  },
  "plans": [],
  "rankings": [
    {
      "profileKey": "Balanced",
      "selectedPlanId": "a41f09c2",
      "plans": [
        {
          "planId": "a41f09c2",
          "score": 0.12,
          "labels": ["Recommended", "FewestShipments", "Closest"],
          "breakdown": { "SplitCount": 0, "ShippingCost": 0.32, "Distance": 0.04, "DeliveryProbability": 0.17, "WarehousePriority": 0.25, "CurrentWarehouse": 0 }
        }
      ]
    },
    {
      "profileKey": "Closest",
      "selectedPlanId": "a41f09c2",
      "plans": [
        {
          "planId": "a41f09c2",
          "score": 0.04,
          "labels": ["Recommended", "FewestShipments", "Closest"],
          "breakdown": { "Distance": 0.04, "SplitCount": 0, "DeliveryProbability": 0.17 }
        }
      ]
    }
  ],
  "unallocatableLines": [],
  "trace": null,
  "configurationVersion": "3f9a1c07be42",
  "totalMs": 42
}

plans is shortened in this example; in a real response it lists every feasible plan, including the selected one.

Outcomes

OutcomeMeaning
SimulatedThe engine found a plan for the order
NoFeasiblePlanNo combination of warehouses can serve the order. See unallocatableLines for the reasons
PartialPlanOnlyThe best plan leaves some lines unplaced. They are listed in unallocatableLines
SkippedNotEnabledAllocation is not enabled
SkippedNothingToAllocateThere are no lines or no warehouses to allocate
SkippedVslUnsupportedThe order uses virtual stock locations, which the allocation engine does not handle

Errors

StatusWhen
400The request has no body, does not contain exactly one of orderId, cartId, order, or cart, or has a trigger other than InitialAllocation or Reallocation
404No order or cart exists with the given orderId or cartId

A simulation of a stored order covers the whole order, including shipments the engine already decided on earlier. Stock is read as it is now, so the result can differ from the decision made when the order was placed.

For the full interactive API reference, see the swagger documentation.

On this page