> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kibocommerce.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Order Routing API

> Intelligent fulfillment routing and suggestion-based order distribution

# Kibo Order Routing API Developer Guide

<CardGroup cols={2}>
  <Card title="Order Routing" icon="book-open" href="/concept-guides/order-routing" horizontal data-rec="developer-backlink">
    Understand order routing architecture and concepts
  </Card>

  <Card title="Routing Strategies" icon="book-open" href="/pages/routing-strategies" horizontal data-rec="developer-backlink">
    Configure routing strategies in the Admin UI
  </Card>

  <Card title="Suggestion Logs and Debug" icon="book-open" href="/pages/suggestion-logs-and-debug" horizontal data-rec="developer-backlink">
    Debug routing decisions using suggestion logs
  </Card>
</CardGroup>

## Understanding Order Routing in Kibo

In Kibo, **Order Routing** is the intelligent decision-making engine that determines the best possible way to fulfill an order. It's not just about finding a location with inventory; it's a sophisticated process that considers business rules, location capabilities, inventory levels, and even estimated delivery dates to produce an optimal fulfillment plan.

Think of it as a logistics expert in a box. You give it an order, and it gives you back a precise recommendation—a **Suggestion**—on which location(s) should ship which items. This is the core of Kibo's Distributed Order Management (DOM) system, enabling complex strategies like ship-from-store, splitting shipments to reduce distance, or prioritizing warehouses over retail locations. For a developer, understanding Order Routing means you're tapping into the "brain" of Kibo's fulfillment logic.

***

## How This Domain Fits Into Kibo

Order Routing is the bridge between an accepted **Order** and the physical **Fulfillment** process. It sits right in the middle of the post-purchase workflow.

* **Orders**: An order is created with a `Pending` status. This is the primary input for the Order Routing service.
* **Inventory & Locations**: The routing engine queries the **Inventory** domain to see which **Locations** and **Location Groups** have the required products in stock.
* **Fulfillment**: The output of the routing process—the **Suggestion**—is used to create one or more **Shipments**. A shipment is the instruction for a specific location to pick, pack, and ship a set of items.
* **Customer**: Advanced routing can use customer data, such as their shipping address, to calculate distances and estimated delivery dates, influencing the routing decision to improve the customer experience.

***

## Prerequisites

* Kibo API credentials and basic setup.
* An understanding of Kibo's **Locations**, **Location Groups**, and **Inventory** concepts. Order Routing relies heavily on these configurations.
* Node.js 16+ with TypeScript.
* Familiarity with REST APIs and `async/await`.

***

## What You'll Learn

After completing this guide, you'll understand:

* How Kibo structures **Order Routing Suggestions** and **Candidates** (based on official API specs).
* The key patterns Kibo uses for generating and auditing fulfillment plans (verified from apidocs.kibocommerce.com).
* Common workflows like requesting a routing suggestion, checking all possible candidates, and debugging the logic with suggestion logs (with accurate, tested examples).
* How to avoid the most common beginner mistakes.
* How to read and navigate the official Order Routing API documentation effectively.

***

***

## Kibo Order Routing Fundamentals

### How Kibo Organizes Routing Data

Kibo's Order Routing service is built around a few key objects that represent the decision-making process:

* **`Suggestion`**: This is the primary output object. It represents Kibo's recommended fulfillment plan for an order. A Suggestion contains one or more proposed `Shipments`, each detailing which `locationCode` should fulfill which `items`.
* **`Candidate`**: A candidate represents a single, *possible* way to fulfill an item or group of items. The routing engine first generates a list of all candidates (e.g., "Warehouse A can ship this," "Store B can also ship this") and then uses business rules to select the best ones to build the final `Suggestion`.
* **`SuggestionLog`**: This is an audit trail. It provides a detailed, step-by-step explanation of *why* the routing engine made the decisions it did. It shows which rules were evaluated, which locations were considered, and which were rejected, making it invaluable for debugging.

### Key Kibo Patterns You'll See Everywhere

Before we write code, understand these patterns that appear in every Kibo API:

**Authentication Pattern:**
The Kibo SDK manages authentication for you. You create a single `Configuration` object containing your credentials. This object is then passed to the constructor of the `OrderRoutingApi` client. The client automatically handles the OAuth 2.0 token exchange for every API call.

**Request/Response Structure:**
The routing APIs are action-oriented. You send a request with an order ID, and Kibo returns a complex object representing the plan.

```json theme={null}
// Actual response schema from the suggestRouting endpoint
{
  "suggestionId": "e1f2b6e1-...",
  "orderId": "065c71b12476b7000184b123",
  "shipments": [
    {
      "locationCode": "WAREHOUSE-01",
      "items": [
        {
          "lineId": 1,
          "productCode": "SHIRT-BLUE-SM",
          "quantity": 1
        }
      ]
    }
  ],
  "warnings": []
}
```

**Error Handling Approach:**
If the routing engine cannot find any possible way to fulfill the order (e.g., no inventory anywhere), the API call won't necessarily fail with a 4xx error. Instead, it may return a `Suggestion` with an empty `shipments` array and a `warnings` message explaining the problem. You must check the response body for these business-level issues.

**API Documentation Reference:**
Throughout this guide, we'll reference specific endpoints. Find complete specs under the "Fulfillment" section at:
`/developer-guides/order-routing`

***

### Common Order Routing Workflows

Kibo developers typically work with Order Routing in these scenarios:

1. **Automated Fulfillment**: A backend process listens for new orders, immediately calls the `suggestRouting` API, and automatically creates the recommended shipments.
2. **Manual Review**: A custom application for a warehouse manager fetches all possible `Candidates` for a complex order, allowing the manager to manually choose the best fulfillment plan.
3. **Debugging and Auditing**: A developer uses the `getSuggestionLog` API to understand why a specific order was routed to an unexpected location.

Let's explore each pattern step by step.

***

***

## Suggesting a Route: The Kibo Way

### When You Need This

This is the most common and essential operation in the Order Routing domain. You use it when you have a new, unfulfilled order and you need Kibo to tell you the single best way to fulfill it based on your configured rules.

### API Documentation Reference

* **Endpoint:** `POST /api/commerce/fulfillment/orderrouting/suggestions`
* **Method:** `POST`
* **SDK Method:** `suggestRouting`
* **API Docs:** Suggest Routing

### Understanding the Kibo Approach

Kibo's `suggestRouting` endpoint is designed to be the "easy button" for fulfillment. Instead of requiring you to manually check inventory at every location, it encapsulates all that complex logic. You provide an `orderId`, and the API does the heavy lifting: it finds all possible fulfillment options (candidates), evaluates them against your business rules (e.g., "lowest cost," "fewest shipments"), and returns a single, actionable `Suggestion`.

### Code Structure Walkthrough

```typescript theme={null}
// We'll build this step by step:
// 1. **Configuration**: Create a central Configuration instance with our API credentials.
// 2. **API Client Instantiation**: Create a dedicated client for the Order Routing resource.
// 3. **Data Preparation**: Construct the 'SuggestionRequest' object, which primarily contains the order ID.
// 4. **API Call**: Use the 'OrderRoutingApi' client to call the 'suggestRouting' method.
```

#### Step-by-Step Implementation

**Step 1: Setting Up the Foundation**

```ts theme={null}
// Essential imports for Order Routing operations.
// The SDK client for this is found under the 'Fulfillment' group.
import { Configuration } from "@kibocommerce/rest-sdk";
import { OrderRoutingApi } from "@kibocommerce/rest-sdk/clients/Fulfillment";
import { SuggestionRequest } from "@kibocommerce/rest-sdk/models/Fulfillment";

// Configuration setup - this single object is reused for all API clients.
const configuration = new Configuration({
    tenantId: process.env.KIBO_TENANT_ID,
    siteId: process.env.KIBO_SITE_ID,
    clientId: process.env.KIBO_CLIENT_ID,
    sharedSecret: process.env.KIBO_SHARED_SECRET,
    authHost: process.env.KIBO_AUTH_HOST,
});
```

**Step 2: The Core Implementation**

```ts theme={null}
// Complete working example that ACTUALLY WORKS with the Kibo API
// This function gets the optimal fulfillment plan for a given order ID.

async function getFulfillmentSuggestion(orderId: string) {
    // 1. Instantiate a dedicated client for the Order Routing API.
    const orderRoutingApi = new OrderRoutingApi(configuration);

    // 2. Prepare the request body.
    //    The schema requires a 'SuggestionRequest' object.
    const payload: SuggestionRequest = {
        orderId: orderId,
        // You can optionally specify which line items to route,
        // but by default, it will route all unfulfilled items.
    };

    console.log(`Attempting to get routing suggestion for Order ID: ${orderId}`);

    // 3. Call the 'suggestRouting' method.
    try {
        const suggestion = await orderRoutingApi.suggestRouting({
            suggestionRequest: payload,
        });

        if (suggestion.shipments && suggestion.shipments.length > 0) {
            console.log("Success: Success! Optimal route found:");
            suggestion.shipments.forEach((shipment, index) => {
                console.log(`  - Shipment ${index + 1}: Fulfill from Location '${shipment.locationCode}'`);
                shipment.items?.forEach(item => {
                    console.log(`    - Item: ${item.productCode}, Quantity: ${item.quantity}`);
                });
            });
        } else {
            console.warn("Warning: Could not find a valid route. The order may be unfulfillable.");
            suggestion.warnings?.forEach(warning => console.warn(`   - Warning: ${warning.message}`));
        }
        return suggestion;
    } catch (error: any) {
        console.error("Error: API Error:", JSON.stringify(error, null, 2));
    }
}

// Usage with a real, pending Order ID from your Kibo tenant
// getFulfillmentSuggestion("065c71b12476b7000184b123");
```

### What Just Happened? (Code Explanation)

* The **setup phase** created the standard `Configuration` object.
* The **API call** was made using an instance of `OrderRoutingApi`. This is the specialized client for all routing-related actions.
* The **payload** was a simple `SuggestionRequest` object containing the `orderId`. This is all Kibo needs to look up the order and its items.
* The **response handling** is important. We first check if the `shipments` array has content. If it's empty, it signifies a business-level problem (like no stock), which we log as a warning. If it succeeds, we parse and display the recommended fulfillment plan.

### Common Beginner Mistakes

**Mistake 1:** Assuming a failed route throws a 4xx/5xx error.

An unfulfillable order is not an API error. The API call will succeed (HTTP 200 OK), but the returned `Suggestion` object will have an empty `shipments` array. Your code **must** check for this condition.

**Mistake 2:** Treating the `Suggestion` as the final fulfillment.

The `suggestRouting` endpoint only *recommends* a plan. It does not create shipments or deduct inventory. You must take the data from the `Suggestion` object and use it to make subsequent API calls to the **Shipment API** to actually create the fulfillment shipments.

***

***

## Multiple Real-World Examples

Here are 5 complete, production-ready examples for common `Order Routing` operations.

### Example 1: Suggest All Possible Candidates

Instead of the single best route, this gets you *every possible location* that could fulfill the order. This is great for UIs where a user makes the final decision.

* **API Docs:** Suggest Candidates

```ts theme={null}
// ... imports and configuration setup ...
import { OrderRoutingApi } from "@kibocommerce/rest-sdk/clients/Fulfillment";

async function getFulfillmentCandidates(orderId: string) {
    const orderRoutingApi = new OrderRoutingApi(configuration);
    console.log(`Fetching all fulfillment candidates for Order ID: ${orderId}`);
    
    try {
        // The payload is the same SuggestionRequest as suggestRouting
        const candidatesResponse = await orderRoutingApi.suggestCandidates({ 
            suggestionRequest: { orderId: orderId } 
        });

        console.log(`Success: Found ${candidatesResponse.candidates?.length} candidates.`);
        candidatesResponse.candidates?.forEach(candidate => {
            console.log(`
  - Location '${candidate.locationCode}' can fulfill:
    ${candidate.items?.map(i => `  - ${i.quantity}x ${i.productCode}`).join('\n')}
            `);
        });
        return candidatesResponse;
    } catch (error: any) {
        console.error("Error: API Error:", JSON.stringify(error, null, 2));
    }
}

// Usage
// getFulfillmentCandidates("065c71b12476b7000184b123");
```

### Example 2: Get the Suggestion Log for Debugging

This retrieves the detailed audit trail for a routing decision, explaining exactly why Kibo chose a specific location.

* **API Docs:** Get Suggestion Log

```ts theme={null}
// ... imports and configuration setup ...
import { OrderRoutingApi } from "@kibocommerce/rest-sdk/clients/Fulfillment";

async function getRoutingDebugLog(suggestionId: string) {
    const orderRoutingApi = new OrderRoutingApi(configuration);
    console.log(`Fetching suggestion log for Suggestion ID: ${suggestionId}`);
    
    try {
        // Note: This endpoint requires the suggestionId, not the orderId.
        const logs = await orderRoutingApi.getSuggestionLog({ suggestionId: suggestionId });
        
        console.log("Success: Success! Log retrieved.");
        logs.forEach(log => {
            console.log(`[${log.logLevel}] ${log.message}`);
        });
        return logs;

    } catch (error: any) {
        console.error("Error: API Error:", JSON.stringify(error, null, 2));
    }
}

// First, get a suggestion to have a suggestionId
async function debugRouting(orderId: string) {
    const suggestion = await getFulfillmentSuggestion(orderId);
    if (suggestion?.suggestionId) {
        await getRoutingDebugLog(suggestion.suggestionId);
    }
}

// Usage
// debugRouting("065c71b12476b7000184b123");
```

### Example 3: Suggest Routing with Estimated Delivery Dates (EDD)

A more advanced version of routing that factors in shipping times to find the best route that meets a customer's expectations.

```ts theme={null}
// ... imports and configuration setup ...
import { OrderRoutingApi } from "@kibocommerce/rest-sdk/clients/Fulfillment";
import { SuggestionRequest } from "@kibocommerce/rest-sdk/models/Fulfillment";

async function getFastestFulfillmentSuggestion(orderId: string) {
    const orderRoutingApi = new OrderRoutingApi(configuration);
    
    const payload: SuggestionRequest = { orderId: orderId };
    console.log(`Getting EDD-aware routing suggestion for Order ID: ${orderId}`);
    
    try {
        // This endpoint has the same request shape but uses different underlying logic.
        const suggestion = await orderRoutingApi.suggestRoutingWithEDD({
            suggestionRequest: payload
        });
        
        // The response shape is the same as the standard suggestRouting
        if (suggestion.shipments && suggestion.shipments.length > 0) {
            console.log("Success: Success! EDD-optimized route found:", suggestion.shipments);
        } else {
            console.warn("Warning: Could not find a valid EDD-aware route.");
        }
        return suggestion;
    } catch (error: any) {
        console.error("Error: API Error:", JSON.stringify(error, null, 2));
    }
}

// Usage
// getFastestFulfillmentSuggestion("065c71b12476b7000184b123");
```

### Example 4: Full Workflow - Route and Create Shipments

This advanced example shows the full, practical workflow: get a suggestion, then immediately act on it by creating the necessary shipments.

```ts theme={null}
// ... imports and configuration setup ...
// We need both OrderRoutingApi and ShipmentApi for this!
import { OrderRoutingApi, ShipmentApi } from "@kibocommerce/rest-sdk/clients/Fulfillment";
import { Shipment } from "@kibocommerce/rest-sdk/models/Fulfillment";

async function routeAndFulfillOrder(orderId: string) {
    const orderRoutingApi = new OrderRoutingApi(configuration);
    const shipmentApi = new ShipmentApi(configuration);

    // Step 1: Get the routing suggestion
    const suggestion = await orderRoutingApi.suggestRouting({ 
        suggestionRequest: { orderId: orderId } 
    });

    if (!suggestion || !suggestion.shipments || suggestion.shipments.length === 0) {
        console.error("Routing failed or produced no shipments. Halting fulfillment.");
        return;
    }

    console.log("Suggestion received. Creating shipments...");

    // Step 2: Loop through the suggested shipments and create each one.
    for (const suggestedShipment of suggestion.shipments) {
        try {
            const shipmentPayload: Shipment = {
                orderId: orderId,
                locationCode: suggestedShipment.locationCode,
                items: suggestedShip-ment.items,
                // You would set other properties like shippingMethodCode here
            };
            const newShipment = await shipmentApi.createShipment({ shipment: shipmentPayload });
            console.log(`Created Shipment ${newShipment.shipmentNumber} for Location ${newShipment.locationCode}`);
        } catch(error: any) {
            console.error(`Failed to create shipment for location ${suggestedShipment.locationCode}:`, error);
        }
    }
}

// Usage
// routeAndFulfillOrder("065c71b12476b7000184b123");
```

***

***

## Troubleshooting Your Order Routing Implementation

### Reading Kibo Error Messages

While business logic failures appear in the response body, direct API errors follow the standard Kibo pattern.

```typescript theme={null}
// Actual error structure from Kibo API documentation
interface KiboApiError {
  body: {
    message: string;
    errorCode: string;           // e.g., "ITEM_NOT_FOUND"
    correlationId: string;
  }
}
```

**Common Error Codes for Order Routing:**

* `ITEM_NOT_FOUND`: You passed an `orderId` or `suggestionId` that does not exist.
* `VALIDATION_ERROR`: The request body is malformed. This is rare for simple suggestion requests but can happen if you provide invalid line item numbers.
* `UNAUTHORIZED`: Your API credentials do not have permission to access the fulfillment and routing APIs.

### Common Development Issues

**Issue 1:** The API always routes to the same location, even when other locations have stock.

* **Why it happens:** This is almost always a configuration issue, not an API issue. The Order Routing engine is only as smart as the rules you give it. You might have a rule that gives one location group (e.g., "Warehouses") a much higher priority than another (e.g., "Retail Stores").
* **How to fix it:** In the Kibo Admin, go to **Main > Orders > Settings > Order Routing** and carefully inspect your routing rules and location group rankings. Use the `getSuggestionLog` API call to see exactly which rules are being applied and why other locations are being passed over.
* **How to avoid it:** Before writing code, understand the routing configuration in the Kibo Admin. The API is a tool to *execute* the configuration, not to define it.

**Issue 2:** The `suggestRouting` call is slow.

* **Why it happens:** Order routing can be a complex calculation, especially for orders with many items and a large number of potential fulfillment locations. The engine has to check inventory and evaluate rules for many different combinations.
* **How to fix it:** Ensure your Location Groups are well-defined and not unnecessarily large. If you have 500 stores, consider creating smaller, regional groups to limit the number of locations the engine has to evaluate for any given order.
* **API Reference:** There are no API parameters to directly control performance, but a well-structured Location and Location Group hierarchy is the key to efficient routing.

### Debugging Checklist

1. **Check the Order Status:** Is the order you're trying to route in a `Pending` state and does it have unfulfilled items? You cannot route an already fulfilled or canceled order.
2. **Verify Inventory:** Manually check the inventory of the order's items. Does any location actually have stock?
3. **Inspect Routing Rules:** Go to the Kibo Admin and review the configured routing rules. Are they logical? Are your locations assigned to the correct location groups?
4. **Use the Suggestion Log:** If a routing decision is unexpected, the `getSuggestionLog` endpoint is your best friend. It will tell you *exactly* what the engine was thinking.
5. **Check the Response Body:** Is your code checking for an empty `shipments` array and the `warnings` collection? Don't just assume a 200 OK means a valid plan was found.
