> ## 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.

# Location Groups API

> Grouping locations for inventory aggregation and fulfillment routing

# Kibo Locations API Developer Guide

<CardGroup cols={2}>
  <Card title="Fulfillment" icon="book-open" href="/concept-guides/fulfillment" horizontal data-rec="developer-backlink">
    Understand how location groups fit into fulfillment
  </Card>

  <Card title="Location Types" icon="book-open" href="/pages/location-types" horizontal data-rec="developer-backlink">
    Manage location groups in the Admin UI
  </Card>
</CardGroup>

## Understanding Locations in Kibo

In Kibo, a **Location** is a fundamental concept representing any physical place relevant to your commerce operations. This isn't limited to just warehouses; a location can be a retail store, a distribution center, a third-party logistics (3PL) partner, or even a temporary pop-up shop. Each location has its own inventory and fulfillment capabilities.

Building on this, a **Location Group** is a logical collection of these individual locations. Instead of managing dozens or hundreds of stores one by one, you can group them into logical sets like "West Coast Stores," "Outlet Locations," or "Ship-from-Store Network." These groups are not just for organization; they are the engine that drives sophisticated inventory sourcing, order fulfillment routing, and multi-site experiences in Kibo.

***

## How This Domain Fits Into Kibo

The Locations domain is the backbone of Kibo's distributed order management and fulfillment capabilities. Location Groups, in particular, are the glue that connects physical locations to your digital strategy.

* **Inventory**: Location Groups allow you to present an aggregated view of inventory to shoppers. For example, a "Texas Stores" group can show the combined stock of all locations in Texas for in-store pickup.
* **Fulfillment & Orders**: During order processing, Kibo's routing engine uses Location Groups to determine the best place to fulfill an order from. You can define rules like "Fulfill online orders from the 'Main Warehouses' group first."
* **Multi-Site**: You can use Location Groups to control which locations are active or visible on different websites (Channels). Your B2B site might only use warehouse locations, while your B2C site uses both warehouses and retail stores for fulfillment.

***

## Prerequisites

* Kibo API credentials with appropriate administrative permissions.
* 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 **Location** and **Location Group** data (based on official API specs).
* The key patterns Kibo uses for managing location groups (verified from apidocs.kibocommerce.com).
* Common workflows like creating, viewing, and updating location groups (with accurate, tested examples).
* How to avoid the most common beginner mistakes.
* How to read and navigate the official API documentation for Location administration.

***

***

## Kibo Location Group Fundamentals

### How Kibo Organizes Location Data

Kibo's Location Group data is straightforward and powerful. The core object is the `LocationGroup`.

* **`LocationGroup`**: The central object representing your logical grouping.
  * `locationGroupCode`: A unique, human-readable identifier that you define (e.g., `WEST_COAST_STORES`). This is the primary key you'll use in API calls.
  * `name`: A friendly name for display in the Kibo Admin UI (e.g., "West Coast Stores").
  * `locationCodes`: This is the most important field—an array of strings, where each string is the `locationCode` of an individual Location you want to include in this group.
  * `siteIDs`: An optional array of site IDs that this location group is associated with, used for multi-site configurations.

### 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 `LocationGroupApi` client. The client automatically handles the OAuth 2.0 token exchange for every API call.

**Request/Response Structure:**
API responses for Location Groups are clean and predictable. When you create a location group, the API returns the full object you just created, including any server-assigned values.

```json theme={null}
// Actual response schema from creating a Location Group
{
  "locationGroupCode": "SGFG",
  "name": "All Texas Retail Locations",
  "locationCodes": [
    "W001",
    "W002",
    "W003"
  ],
  "siteIDs": [
    12345
  ]
}
```

**Error Handling Approach:**
If an API call fails, the SDK throws a structured error. A common error when creating a location group is a `VALIDATION_ERROR` if one of the `locationCodes` you provided doesn't actually exist in Kibo.

**Pagination and Filtering:**
When getting a list of location groups, the API uses standard `pageSize` and `startIndex` parameters to manage the results.

**API Documentation Reference:**
Throughout this guide, we'll reference specific endpoints. Find complete specs under the "Tenant" administration section, as Location Groups are a tenant-level concept.
[`/api-reference/locationgroup/get-location-groups`](/api-reference/locationgroup/get-location-groups)

***

### Common Location Group Workflows

Kibo developers typically work with Location Groups in these scenarios:

1. **Initial Setup**: Programmatically creating location groups as part of an initial environment setup or migration.
2. **Dynamic Updates**: Adding or removing a store from a group when a new store opens or an old one closes.
3. **Auditing and Reporting**: Fetching all location group configurations to integrate with an external reporting or analytics tool.

Let's explore each pattern step by step.

***

***

## Adding a Location Group: The Kibo Way

### When You Need This

This is the foundational "create" operation. You'll use this anytime you need to define a new logical grouping of stores for fulfillment, inventory, or site visibility. For example, you might create a new group for an upcoming holiday season to manage a specific set of pop-up shops.

### API Documentation Reference

* **Endpoint:** `POST /api/platform/admin/locationgroups`
* **Method:** `POST`
* **SDK Method:** `addLocationGroup`
* **API Docs:** [Add Location Group](/api-reference/locationgroup/add-location-group)

### Understanding the Kibo Approach

Kibo treats Location Group creation as a simple, atomic operation. You provide all the necessary information in a single payload: the unique code, the name, and the list of individual location codes that will belong to the group. The API validates that all the specified locations exist before creating the group, ensuring data integrity.

### 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 LocationGroup resource.
// 3. **Data Preparation**: Construct the 'LocationGroup' request body according to the API schema.
// 4. **API Call**: Use the 'LocationGroupApi' client to call the 'addLocationGroup' method.
```

#### Step-by-Step Implementation

**Step 1: Setting Up the Foundation**

```ts theme={null}
// Essential imports for Location Group operations.
// The SDK client for this is found under the 'Tenant' group.
import dotenv from "dotenv";
dotenv.config();

import { Configuration } from "@kibocommerce/rest-sdk";
import { LocationGroupApi } from "@kibocommerce/rest-sdk/clients/LocationAdmin/apis/LocationGroupApi.js";
    // Configuration setup - this single object is reused for all API clients.
    // Note: Location Group management often requires higher-level API permissions.
    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 || "https://home.mozu.com",
    });

```

**Step 2: The Core Implementation**

```ts theme={null}

async function createLocationGroup() {
  try {
    const api = new LocationGroupApi(configuration);

    // Correct structure expected by AddLocationGroupRequest
    const payload = {
        locationLocationGroup: {
            locationGroupId: 10, // or omit if auto-assigned
            locationGroupCode: "SGFG",
            siteIds: [73029],
            name: "SG-Fulfillment",
            locationCodes: ["W001"],
        },
    };

    console.log(`Creating location group '${payload.locationLocationGroup.name}'...`);

    const response = await api.addLocationGroup(payload);

    console.log("Success: Location group created successfully:");
    console.log(JSON.stringify(response, null, 2));
  } catch (err) {
    console.error("Error: Error creating location group:", err);
  }
}

createLocationGroup();
```

### What Just Happened? (Code Explanation)

* The **setup phase** created the `Configuration` object. Note that managing tenant-level objects like `LocationGroup` may require API credentials with broader permissions than storefront-only credentials.
* The **API call** was made using an instance of `LocationGroupApi`, which is the specific client for these operations.
* The **payload** was a `LocationGroup` object. We defined our own unique `locationGroupCode` and provided the list of existing `locationCodes` to include.
* The **response handling** uses a `try...catch` block. On success, Kibo returns the group object we just created. On failure, we check for a specific `ITEM_ALREADY_EXISTS` error to provide a more helpful message.

### Common Beginner Mistakes

**Mistake 1:** Trying to create a group with non-existent location codes.

```ts theme={null}
// Wrong - The API will reject this with a VALIDATION_ERROR.
const payload = {
    locationGroupCode: "BAD_GROUP",
    name: "Group with Fake Stores",
    locationCodes: [
        "STORE-THAT-DOES-NOT-EXIST" // Kibo validates this list
    ]
};
```

**Solution:** Always ensure the locations you are adding to a group have been created in Kibo first. You can use the `LocationApi` to list existing locations to verify codes.

**Mistake 2:** Using the wrong API client.

The `LocationGroupApi` is under the `@kibocommerce/rest-sdk/clients/Tenant` import, not `Commerce` or `CatalogAdministration`. Because groups are a foundational, tenant-wide setting, they are managed through the Tenant APIs.

***

***

## Multiple Real-World Examples

Here are 5 complete, production-ready examples for common `Location Group` operations.

### Example 1: Get a Specific Location Group

Fetch the configuration for a single, known location group. This is useful for checking details before an update.

* **API Docs:** [Get Location Group](/api-reference/locationgroup/get-location-group)

```ts theme={null}
// ... imports and configuration setup ...
import { Configuration } from "@kibocommerce/rest-sdk";
import { LocationGroupApi } from "@kibocommerce/rest-sdk/clients/LocationAdmin/apis/LocationGroupApi.js";;

async function getLocationGroupDetails(groupCode: string) {
  const api = new LocationGroupApi(configuration);
  console.log(`Fetching details for location group: ${groupCode}...`);

  try {
    // The SDK expects the property name to match API spec exactly:
    const response = await api.getLocationGroup({ locationGroupCode: groupCode });

    console.log("Success: Success! Found group:");
    console.log(JSON.stringify(response, null, 2));
    return response;
  } catch (err: any) {
    console.error("Error: Error fetching location group:", err);
    if (err.apiError?.errorCode === "ITEM_NOT_FOUND") {
      console.error(`No location group found with code '${groupCode}'.`);
    }
  }
}

getLocationGroupDetails("SGFG");
// Usage
// getLocationGroupDetails("SGFG");
```

### Example 2: Update a Location Group (Add a New Store)

This covers the common scenario of opening a new store and adding it to an existing fulfillment group.

* **API Docs:** [Update Location Group](/api-reference/locationgroup/update-location-group)

```ts theme={null}
// ... imports and configuration setup ...
import { Configuration } from "@kibocommerce/rest-sdk";
import { LocationGroupApi } from "@kibocommerce/rest-sdk/clients/LocationAdmin/apis/LocationGroupApi.js";;
import { LocationGroup } from "@kibocommerce/rest-sdk/models/Tenant";

async function addStoreToGroup(groupCode: string, newLocationCode: string) {
  const api = new LocationGroupApi(configuration);
  console.log(`Adding location '${newLocationCode}' to group '${groupCode}'...`);

  try {
    // 1. Get current group details
    const currentGroup = await api.getLocationGroup({ locationGroupCode: groupCode });
    console.log(`Fetched group: ${currentGroup.name}`);

    // 2. Add new code (no duplicates)
    const updatedCodes = Array.from(new Set([...(currentGroup.locationCodes || []), newLocationCode]));

    // 3. Build payload using correct key
    const payload = {
      locationGroupCode: groupCode,
      locationLocationGroup: {
        locationGroupId: currentGroup.locationGroupId,
        locationGroupCode: currentGroup.locationGroupCode,
        siteIds: currentGroup.siteIds,
        name: currentGroup.name,
        locationCodes: updatedCodes,
      },
    };

    // 4. Call update API
    const response = await api.updateLocationGroup(payload);

    console.log("Success: Successfully updated group!");
    console.log(JSON.stringify(response, null, 2));
  } catch (err: any) {
    console.error("Error: Error updating location group:", err);
    if (err.apiError) console.error("API Error:", err.apiError);
  }
}

// Example run
addStoreToGroup("SGFG", "W003");

// Usage: Assumes a "W003" location has been created.
// addStoreToGroup("SGFG", "W003");
```

### Example 3: List All Location Groups

A utility function to get a high-level overview of all location groups configured in the tenant.

* **API Docs:** [Get Location Groups](/api-reference/locationgroup/get-location-groups)

```ts theme={null}
// ... imports and configuration setup ...
import { Configuration } from "@kibocommerce/rest-sdk";
import { LocationGroupApi } from "@kibocommerce/rest-sdk/clients/LocationAdmin/apis/LocationGroupApi.js";;

async function listAllLocationGroups() {
    const locationGroupApi = new LocationGroupApi(configuration);
    console.log("Fetching all location groups...");
    
    try {
        const groupsCollection = await locationGroupApi.getLocationGroups({ pageSize: 200 });
        
        console.log(`Success: Found ${groupsCollection.totalCount} location groups.`);
        groupsCollection.items?.forEach(group => {
            console.log(`  - ${group.name} (Code: ${group.locationGroupCode})`);
        });
        return groupsCollection;
    } catch (error: any) {
        console.error("Error: API Error:", JSON.stringify(error, null, 2));
    }
}

listAllLocationGroups();

// listAllLocationGroups();
```

### Example 4: Remove a Store from a Location Group

The inverse of Example 2, this is for when a store closes or is no longer part of a specific fulfillment strategy.

```ts theme={null}
// ... imports and configuration setup ...
import { Configuration } from "@kibocommerce/rest-sdk";
import { LocationGroupApi } from "@kibocommerce/rest-sdk/clients/LocationAdmin/apis/LocationGroupApi.js";;
import { LocationGroup } from "@kibocommerce/rest-sdk/models/Tenant";

async function removeStoreFromGroup(groupCode: string, locationCodeToRemove: string) {
  const api = new LocationGroupApi(configuration);
  console.log(`Removing location '${locationCodeToRemove}' from group '${groupCode}'...`);

  try {
    // 1. Get current group details
    const currentGroup = await api.getLocationGroup({ locationGroupCode: groupCode });
    console.log(`Fetched group: ${currentGroup.name}`);

    // 2. Remove the given code (instead of adding)
    const updatedCodes = (currentGroup.locationCodes || []).filter(
      (code) => code !== locationCodeToRemove
    );

    // 3. Build payload using correct key
    const payload = {
      locationGroupCode: groupCode,
      locationLocationGroup: {
        locationGroupId: currentGroup.locationGroupId,
        locationGroupCode: currentGroup.locationGroupCode,
        siteIds: currentGroup.siteIds,
        name: currentGroup.name,
        locationCodes: updatedCodes,
      },
    };

    // 4. Call update API
    const response = await api.updateLocationGroup(payload);

    console.log("Success: Successfully updated group (location removed)!");
    console.log(JSON.stringify(response, null, 2));
  } catch (err: any) {
    console.error("Error: Error updating location group:", err);
    if (err.apiError) console.error("API Error:", err.apiError);
  }
}

// Example run
removeStoreFromGroup("SGFG", "W002");

// Usage
// removeStoreFromGroup("SGFG", "W002");
```

### Example 5: Delete a Location Group

Permanently remove a location group. This does *not* delete the individual locations within it.

* **API Docs:** [Delete Location Group](/api-reference/locationgroup/delete-location-group)

```ts theme={null}
// ... imports and configuration setup ...
import { Configuration } from "@kibocommerce/rest-sdk";
import { LocationGroupApi } from "@kibocommerce/rest-sdk/clients/LocationAdmin/apis/LocationGroupApi.js";;

async function deleteLocationGroup(groupCode: string) {
  const api = new LocationGroupApi(configuration);
  console.log(`Deleting location group '${groupCode}'...`);

  try {
    // Call delete endpoint — no body is returned
    await api.deleteLocationGroup({ locationGroupCode: groupCode });

    console.log(`Successfully deleted location group '${groupCode}'.`);
  } catch (err: any) {
    console.error("Error: Error deleting location group:", err);
    if (err.apiError?.errorCode === "ITEM_NOT_FOUND") {
      console.error(`No location group found with code '${groupCode}'.`);
    }
  }
}

// Example run
deleteLocationGroup("SGFG");

// Usage
// deleteLocationGroup("SGFG");
```

***

***

## Troubleshooting Your Location Group Implementation

### Reading Kibo Error Messages

```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 Location Groups:**

* `ITEM_NOT_FOUND`: You tried to get, update, or delete a location group using a `locationGroupCode` that does not exist.
* `ITEM_ALREADY_EXISTS`: You tried to `addLocationGroup` with a `locationGroupCode` that is already in use. Codes must be unique.
* `VALIDATION_ERROR`: The request body is invalid. The most common cause is including a `locationCode` in the `locationCodes` array that does not correspond to an existing Location in your Kibo tenant.
* `REQUIRED_FIELD_MISSING`: You tried to create a group without a `locationGroupCode` or `name`.

### Common Development Issues

**Issue 1:** My `updateLocationGroup` call is wiping out other settings.

* **Why it happens:** The `PUT` operation for updating a location group expects the *entire* `LocationGroup` object in the payload. If you send only the field you want to change (e.g., `{ "locationCodes": [...] }`), Kibo will interpret the missing fields (like `name`) as null and clear them.
* **How to fix it:** Always perform a `GET` on the location group first, modify the retrieved object in your code, and then `PUT` the complete, modified object back.
* **How to avoid it:** Follow the "Read-Modify-Write" pattern shown in Examples 2 and 4.

**Issue 2:** I created a group, but it's not being used for fulfillment.

* **Why it happens:** Creating a `LocationGroup` is just step one. You also need to configure Kibo's Order Management system to *use* that group in its fulfillment logic.
* **How to fix it:** In the Kibo Admin, navigate to **Main > Orders > Settings**. Here you can configure Order Routing and define which location groups should be used for sourcing inventory.
* **API Reference:** The APIs for managing fulfillment settings are separate from the `LocationGroupApi`. Look under the `Commerce/Settings` and `Commerce/Orders` API groups for more advanced configuration.

### Debugging Checklist

1. **Check the `locationGroupCode`:** Is it an exact string match, including case?
2. **Validate `locationCodes`:** Before creating or updating a group, are you sure every single `locationCode` in your array exists in the Kibo tenant?
3. **Verify API Client**: Are you using `LocationGroupApi` from the `@kibocommerce/rest-sdk/clients/Tenant` package?
4. **Check Permissions**: Do your API credentials have the necessary administrative permissions to manage tenant-level settings?
5. **Use the Read-Modify-Write Pattern:** For updates, are you fetching the object first to avoid accidental data loss?
