Skip to main content

Kibo Reservations API Developer Guide

Understanding Reservations in Kibo

In Kibo, a Reservation is a temporary, short-term hold on a specific quantity of a product at a specific location. It’s a key mechanism to prevent overselling during the active shopping process, especially in high-volume environments. What makes Kibo’s approach different is that a reservation is an explicit, API-managed object, not an implicit side-effect of adding an item to a cart. When a customer proceeds to checkout, your application should create a reservation for the items in their cart. This “soft-allocates” the inventory, taking it out of the available-to-sell pool for a limited time. If the customer completes the purchase, the reservation is committed; if they abandon the cart, the reservation is deleted or expires, and the inventory is automatically returned to the pool. This system provides a robust guarantee that what’s in the cart is available to be purchased.

How This Domain Fits Into Kibo

The Reservations domain is the bridge between the Cart/Checkout process and the Inventory domain. It ensures data integrity for inventory during the most volatile part of the customer journey.
  • Inventory: A reservation reduces the available quantity of a product at a location but does not affect the onHand quantity. It’s a temporary promise. Only when an order is fulfilled is the onHand quantity decremented.
  • Checkout & Cart: The checkout flow is the primary driver for creating and managing reservations. A successful checkout should commit the reservation, while an abandoned cart should delete it.
  • Orders: Once an order is placed, the associated reservation is typically committed. The orderId is a key piece of data stored on the reservation object itself, linking the inventory hold to the final transaction.

Prerequisites

  • Kibo API credentials and basic setup
  • Node.js 16+ with TypeScript
  • Familiarity with REST APIs and asynchronous concepts

What You’ll Learn

After completing this guide, you’ll understand:
  • How Kibo uses reservations to temporarily hold inventory (based on official API specs).
  • The key patterns for creating, updating, committing, and deleting reservations (verified from apidocs.kibocommerce.com).
  • The common workflow for managing inventory holds during a customer checkout.
  • How to avoid the most common beginner mistakes, like confusing a reservation with a final inventory transaction.
  • How to read and navigate the official Commerce Inventory Reservations API documentation effectively.

Kibo Reservations Fundamentals

How Kibo Organizes Reservation Data

The system is centered on the Reservation object. It’s a simple yet powerful construct:
  • Reservation: The core object representing the inventory hold. It is identified by a system-generated reservationId. The most important properties are:
    • orderId: Links the reservation to a cart or checkout object (which will later become the order).
    • locationCode: Specifies where the inventory is being held. Inventory is always location-specific.
    • items: An array of objects, each specifying a productCode, quantity, lineId and id (a unique identifier for that item within the cart/order).

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 (Client ID, Shared Secret, etc.). This object is then passed to the constructor of specific API clients (e.g., new ReservationsApi(configuration)). Request/Response Structure: Many reservation operations are done in bulk for efficiency. The API expects and returns a ReservationCollection object, which contains an array of individual Reservation objects.
// Actual response schema for POST /api/commerce/reservation
{
  "id": "string",
  "siteId": 0,
  "tenantId": 0,
  "userId": "string",
  "customerAccountId": 0,
  "items": [
    {
      "lineId": 0,
      "id": "string",
      "orderItemId": "string",
      "product": {
        "productCode": "string",
        "name": "string",
        "productType": "string",
        "mfgPartNumber": "string",
        "variationProductCode": "string",
        "sku": "string",
        "goodsType": "string",
        "productUsage": "string",
        "bundledProducts": [
          {
            "productCode": "string",
            "name": "string",
            "goodsType": "string",
            "quantity": 0,
            "optionAttributeFQN": "string",
            "measurements": {
              "height": {
                "unit": "string",
                "value": 0
              },
              "width": {
                "unit": "string",
                "value": 0
              },
              "length": {
                "unit": "string",
                "value": 0
              },
              "weight": {
                "unit": "string",
                "value": 0
              }
            }
          }
        ],
        "isSplitExtrasInShipment": true,
        "properties": [
          {
            "attributeFQN": "string",
            "values": [
              {
                "stringValue": "string"
              }
            ]
          }
        ],
        "measurements": {
          "height": {
            "unit": "string",
            "value": 0
          },
          "width": {
            "unit": "string",
            "value": 0
          },
          "length": {
            "unit": "string",
            "value": 0
          },
          "weight": {
            "unit": "string",
            "value": 0
          }
        },
        "isTaxable": true,
        "serialNumber": "string",
        "condition": "string"
      },
      "quantity": 0,
      "fulfillmentLocationCode": "string",
      "fulfillmentMethod": "string",
      "allocations": [
        {
          "itemId": "string",
          "quantity": 0,
          "fulfillmentLocationCode": "string",
          "transferLocationCode": "string",
          "productCode": "string",
          "futureDate": "2025-11-07T16:33:22.065Z",
          "isStateChange": true,
          "allocationId": 0
        }
      ],
      "allowsBackOrder": true,
      "allocationStatus": "string",
      "inventoryTags": [
        {
          "name": "string",
          "value": "string"
        }
      ],
      "suggestions": [
        {
          "locationCode": "string",
          "suggestionType": "string",
          "quantity": 0,
          "productCode": "string",
          "futureDate": "2025-11-07T16:33:22.065Z"
        }
      ],
      "fulfillmentContact": {
        "id": 0,
        "email": "string",
        "firstName": "string",
        "middleNameOrInitial": "string",
        "lastNameOrSurname": "string",
        "companyOrOrganization": "string",
        "phoneNumbers": {
          "home": "string",
          "mobile": "string",
          "work": "string"
        },
        "address": {
          "address1": "string",
          "address2": "string",
          "address3": "string",
          "address4": "string",
          "cityOrTown": "string",
          "stateOrProvince": "string",
          "postalOrZipCode": "string",
          "countryCode": "string",
          "addressType": "string",
          "isValidated": true
        }
      }
    }
  ],
  "cartId": "string",
  "orderId": "string",
  "orderNumber": 0,
  "expirationDateTime": "2025-11-07T16:33:22.065Z",
  "zipCode": "string",
  "status": "string",
  "auditInfo": {
    "createdBy": "string",
    "createdAt": "2025-11-07T16:33:22.065Z",
    "updatedBy": "string",
    "updatedAt": "2025-11-07T16:33:22.065Z"
  },
  "changeMessages": [
    {
      "id": "string",
      "identifier": "string",
      "correlationId": "string",
      "userId": "string",
      "appKey": "string",
      "appName": "string",
      "subjectType": "string",
      "subject": "string",
      "verb": "string",
      "message": "string",
      "createDate": "2025-11-07T16:33:22.065Z"
    }
  ],
  "reservationType": "string",
  "fulfillmentContact": {
    "id": 0,
    "email": "string",
    "firstName": "string",
    "middleNameOrInitial": "string",
    "lastNameOrSurname": "string",
    "companyOrOrganization": "string",
    "phoneNumbers": {
      "home": "string",
      "mobile": "string",
      "work": "string"
    },
    "address": {
      "address1": "string",
      "address2": "string",
      "address3": "string",
      "address4": "string",
      "cityOrTown": "string",
      "stateOrProvince": "string",
      "postalOrZipCode": "string",
      "countryCode": "string",
      "addressType": "string",
      "isValidated": true
    }
  }
}
Error Handling Approach: If an API call fails, the SDK throws a structured error. For reservations, a common error is VALIDATION_CONFLICT, which indicates that the requested quantity is not available to be reserved.
// Actual error schema from Kibo
{
    "message": "Validation Error: Enough inventory not found for the items [Hats_001,787872]",
    "errorCode": "VALIDATION_CONFLICT",
    "correlationId": "e0b5b9b0-a5f1-4f1e-9a0c-12345abcdef"
}
API Documentation Reference: Throughout this guide, we’ll reference specific endpoints. Find complete specs at: /api-overviews/openapi_reservation_overview

Common Reservation Workflows

  1. Standard Checkout: Create a reservation when a user enters the checkout flow. Commit the reservation on successful order placement. Delete the reservation if the user abandons the flow.
  2. Cart Quantity Update: Update the reservation when a user changes an item’s quantity in their cart during checkout.
  3. Order Cancellation: If a customer cancels an order shortly after placing it (before fulfillment), the corresponding reservation might be deleted to release the inventory immediately.
Let’s explore each CRUD operation step by step.

Create Reservations: The Kibo Way

When You Need This

This is the first step in the checkout process. As soon as a customer signals their intent to buy (e.g., by clicking “Proceed to Checkout”), you should create a reservation to hold the items in their cart.

API Documentation Reference

Endpoint: POST /commerce/reservation Method: POST API Docs: /api-overviews/openapi_reservation_overview

Understanding the Kibo Approach

Kibo optimizes this operation by allowing you to reserve items for a single order at multiple locations in one API call. You provide an array of Reservation objects, and the system processes them together. The API call is synchronous—it will immediately check for available inventory and either succeed by returning the created reservation objects or fail with an VALIDATION_CONFLICT error. This gives you instant feedback to show the customer.

Code Structure Walkthrough

// We'll build this step by step:
// 1. **Configuration**: Create a central Configuration instance.
// 2. **API Client Instantiation**: Create a dedicated client for the Reservations API.
// 3. **Data Preparation**: Construct an array of Reservation objects based on the items in the customer's cart.
// 4. **API Call**: Use the instantiated client to call the `addReservations` method.

Step-by-Step Implementation

Step 1: Setting Up the Foundation
// Essential imports for Reservation operations.
import { Configuration } from "@kibocommerce/rest-sdk";
import { Reservati as Reservation } from "@kibocommerce/rest-sdk/clients/Reservation/models";
import { ReservationApi } from "@kibocommerce/rest-sdk/clients/Reservation";
import { ReservationCollecti as ReservationCollection } from "@kibocommerce/rest-sdk/clients/Reservation/models";
import 'dotenv/config';

// Global configuration object available to all examples
const configuration = new Configuration({
    tenantId: process.env.KIBO_TENANT_ID || 'test-tenant',
    siteId: process.env.KIBO_SITE_ID || 'test-site',
    clientId: process.env.KIBO_CLIENT_ID || 'test-client',
    sharedSecret: process.env.KIBO_SHARED_SECRET || 'test-secret',
    authHost: process.env.KIBO_AUTH_HOST || 'home.mozu.com',
});
Step 2: The Core Implementation
// Complete working example for creating reservations for a cart.
// 'cartItems' would be the items from your cart object.
// 'orderId' would be the ID of your cart/checkout object.
async function createReservationsForCart(
    orderId: string,
    cartItems: { lineId: number;fulfillmentMethod: string, product : any; quantity: number }[],
    zipCode: string
): Promise<Reservation> {
    console.log(`Creating reservations for order ID: ${orderId}...`);
    const reservationsClient = new ReservationApi(configuration);

    // 1. Prepare the request payload. The API expects an array of Reservation objects.
    const reservationPayload: Reservation = {
        cartId: orderId,
        items: cartItems,
        zipCode: zipCode
    };

    // 2. Call the method on the client.
    try {
        const createdReservations = await reservationsClient.createReservation({
            reservati: reservationPayload,
        });
        console.log("Success! Reservations created:", createdReservations);
        return createdReservations;
    } catch (error) {
        // This error should be handled in the UI.
        console.error("API Error creating reservations:", JSON.stringify(error, null, 2));
        throw error; // Propagate the error to be handled by the checkout flow.
    }
}

Update & Delete Reservations

Update Reservations

When You Need This: If a customer changes the quantity of an item or adds/removes an item after the initial reservation has been made (e.g., on the final review step of checkout). API Documentation Reference: The Kibo Approach: Similar to creation, updating is a bulk operation. You send the complete, updated set of Reservation objects. Kibo then adjusts the inventory holds accordingly.
async function updateReservationsForCart(
    updatedReservations: Reservation
): Promise<Reservation> {
    const reservationClient = new ReservationApi(configuration);
    try {
        const result = await reservationClient.updateReservation({
            reservationId: updatedReservations.id as string,
            reservati: updatedReservations,
        });
        console.log("Reservations updated successfully.");
        return result;
    } catch (error) {
        console.error("API Error updating reservations:", JSON.stringify(error, null, 2));
        throw error;
    }
}

Delete a Reservation

When You Need This: When a customer abandons the checkout flow or their session expires. Deleting the reservation releases the held inventory back into the available-to-sell pool. API Documentation Reference:
  • Endpoint: DELETE /commerce/reservation/{reservationId}
  • Method: DELETE
  • API Docs: Delete Reservation
The Kibo Approach: This is a simple, direct operation to remove a single reservation hold by its unique ID.
async function deleteReservationById(reservationId: string): Promise<void> {
    const reservationClient = new ReservationApi(configuration);
    try {
        // This call returns a 204 No Content on success.
        await reservationClient.deleteReservation({ reservationId });
        console.log(`Reservation ${reservationId} deleted successfully.`);
    } catch (error) {
        console.error("API Error deleting reservation:", JSON.stringify(error, null, 2));
        throw error;
    }
}

Multiple Real-World Examples

Example 1: The Full Checkout Reservation Workflow This example simulates the entire lifecycle of a reservation during a successful purchase.
async function runFullCheckoutReservation(orderId: string, items: any[], locationCode: string) {
    const reservationClient = new ReservationApi(configuration);

    // 1. Create the reservation at the start of checkout.
    const createdReservation = await createReservationsForCart(orderId, items, locationCode);
    if (!createdReservation) {
        throw new Error("Failed to create any reservations.");
    }
    const reservationId = createdReservation.id as string;
    console.log(`Reservation ${reservationId} created.`);

    // --- Customer completes the order successfully ---
    console.log("Order placed. Closing reservation...");

    // 2. Close the reservation. This is an advanced action.
    try {
        await reservationClient.closeReservation({ reservationId:  reservationId });
        console.log(`Reservation ${reservationId} has been closed.`);
    } catch (error) {
        console.error("Failed to close reservation:", JSON.stringify(error, null, 2));
        // In a real app, you might need to handle this failure (e.g., by cancelling the order).
        throw error;
    }
}
Example 2: Get All Reservations for a Specific Order
async function getReservationsByOrderId(orderId: string): Promise<ReservationCollection> {
    const reservationClient = new ReservationApi(configuration);
    try {
        // Use the filter parameter to query for reservations linked to a specific orderId.
        const response = await reservationClient.getReservationsByCartId({
            cartId: orderId
        });
        console.log(`Found ${response.items?.length} reservation(s) for order ${orderId}.`);
        return response;
    } catch (error) {
        console.error("Failed to get reservations:", JSON.stringify(error, null, 2));
        throw error;
    }
}
Example 3, 4, 5: The createReservationsForCart, updateReservationsForCart, and deleteReservationById functions shown in the previous sections serve as complete, runnable examples for the core CRUD operations.

Integrating Reservations with Other Kibo Domains

Reservations + Inventory Integration

This is the most direct relationship. A reservation’s entire purpose is to manipulate inventory availability. The addReservations call will fail if the available quantity at the specified locationCode is less than the requested quantity. Committing a reservation signals to the inventory system that this quantity is now allocated to an order and will be decremented from the onHand count upon shipment.

Reservations + Order Management (OMS)

In a sophisticated Order Management System (OMS) flow, reservations are used to determine sourcing. Before fulfilling an order, the OMS may create temporary reservations at several possible locations to find the optimal sourcing solution. Once the best location is determined, the reservation at that location is committed, and the temporary reservations at the other locations are deleted.

Troubleshooting Your Reservations Implementation

Reading Kibo Error Messages

interface KiboApiError {
  errorCode: string;      // Specific error codes from apidocs.kibocommerce.com
  message: string;          // Error description
  correlationId: string;  // For support tracking
}
Common Error Codes for Reservations:
  • INSUFFICIENT_STOCK: The most common error. It means you cannot create or update a reservation because there is not enough available inventory.
  • RESERVATION_NOT_FOUND: The reservationId you provided to deleteReservation or another endpoint does not exist.
  • VALIDATION_ERROR: The request body is malformed. A common cause is a missing locationCode or an invalid productCode.

Common Development Issues

Issue 1: My addReservations call fails with an INSUFFICIENT_STOCK error, but the UI shows the item is in stock.
  • Why it happens: This is a classic race condition. Between the time the customer loaded the product page and when they tried to check out, another customer (or a store associate) purchased the last item. The reservation API provides the real-time, authoritative answer on availability.
  • How to fix it: Your checkout UI must gracefully handle this error. When you catch an INSUFFICIENT_STOCK error, you should display a clear message to the user (e.g., “An item in your cart is no longer available”) and prompt them to review their cart.
Issue 2: Inventory is being “locked” and never becomes available again.
  • Why it happens: This usually means your application is creating reservations but failing to delete them when a user abandons their cart. Without a deleteReservation call, the inventory will remain held until the reservation automatically expires (typically after a short period, like 30 minutes).
  • How to fix it: Ensure your application has a robust mechanism to detect an abandoned session or an explicit “Remove from Cart” action during checkout. This mechanism must trigger a call to the deleteReservation endpoint. While Kibo’s automatic expiration is a good safety net, you should not rely on it for normal operation.