1. Locations
  2. Layouts

Locations

Layouts

Layouts control the storage space inside of a location. Layouts can be nested inside of other layouts to create any combination to mimic the real world setup that an organization has. Inventory items are then able to be added to layouts and shared between organizations for increased visibility.

Add Layouts

Overview

You can easily create layouts from the PackageX dashboard. It's encouraged since layouts are typically set and forget.

WARNING

Make sure the editing access to layouts are not blocked in your settings either on the dashboard or the organization settings found on: organization.settings.locations.layouts.locked

Layouts can be nested by setting a parent_path property on the layout you wish to nest. As a result, you'll need to make sure that you create any parent layouts first and then create any children. In this example:

  • We'll create a parent layout called Aisle 1
  • Then nest Shelf A and Shelf B under Aisle 1.
  • Lastly, we'll nest Bins Alpha, Bravo, and Charlie under Shelf A, and Bins, Delta, Echo, and Foxtrot under Shelf B.

In the end, we'll have layouts that are structured:

        Aisle 1
└─ Shelf A
   ├─ Bin Alpha
   ├─ Bin Bravo
   ├─ Bin Charlie
└─ Shelf B
   ├─ Bin Delta
   ├─ Bin Echo
   ├─ Bin Foxtrot

      

Limitations: There is a soft cap of about 1,000 layouts per nesting level. For example, in the example above you can have Aisles 1 thru 1000. Each Aisle can have 1000 Shelves. Each shelf can have 1000 bins. We think these are realistic limits to maintain performance. With this in mind, if your use case requires a higher limit, please reach out.

Create Parent Layout

POST
`/v1/locations/:location/layouts`

To create a layout you'll need to provide a name for the layout. If you don't provide an id, one will be generated for you. Layouts are always added as array values.

js
        const data = [
  {
    id: "lay_aisle_1",
    name: "Aisle 1",
    parent_path: "/", //optional on parent layouts since they are at the root
  },
];

fetch(`https://api.packagex.io/v1/locations/loc_8GiCVuqZqBJi43v2WebaME/layouts`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data),
});

      

Add Shelves

POST
`/v1/locations/:location/layouts`

This will set the shelves as children of Aisle 1. You'll be able to update the name property but not the ID, since that will create a new layout.

js
        const data = [
  {
    id: "lay_shelf_A",
    name: "Shelf A",
    parent_path: "/lay_aisle_1",
  },
  {
    id: "lay_shelf_B",
    name: "Shelf B",
    parent_path: "/lay_aisle_1",
  },
];

fetch(`https://api.packagex.io/v1/locations/loc_8GiCVuqZqBJi43v2WebaME/layouts`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data),
});

      

Add Bins

POST
`/v1/locations/:location/layouts`

Now that we have our shelves set up, we can add bins in the same process as the shelves. In this manner, you can add as much hierarchy as needed.

js
        const data = [
  {
    id: "lay_binA",
    name: "Bin Alpha",
    parent_path: "/lay_aisle_1/lay_shelf_A",
  },
  {
    id: "lay_binB",
    name: "Bin Bravo",
    parent_path: "/lay_aisle_1/lay_shelf_A",
  },
  {
    id: "lay_binC",
    name: "Bin Charlie",
    parent_path: "/lay_aisle_1/lay_shelf_A",
  },
  {
    id: "lay_binD",
    name: "Bin Delta",
    parent_path: "/lay_aisle_1/lay_shelf_B",
  },
  {
    id: "lay_binE",
    name: "Bin Echo",
    parent_path: "/lay_aisle_1/lay_shelf_B",
  },
  {
    id: "lay_binF",
    name: "Bin Foxtrot",
    parent_path: "/lay_aisle_1/lay_shelf_B",
  },
];

fetch(`https://api.packagex.io/v1/locations/loc_8GiCVuqZqBJi43v2WebaME/layouts`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data),
});

      

Layout Code

Optionally, the layouts can have a code to make it easier for you to identify them. For a given location, the codes have to be distinct.

js
        const data = [
  {
    id: "lay_aisle_1",
    name: "Aisle 1",
    parent_path: "/", //optional on parent layouts since they are at the root
    code: "la1"
  },
];

fetch(`https://api.packagex.io/v1/locations/loc_8GiCVuqZqBJi43v2WebaME/layouts`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data),
});

      

Delete Layouts

When deleting layouts, you will just need to pass in the ID of the layouts you want to delete into the request body.

DANGER

When deleting a layout, any children that this layout has will also be deleted.

DELETE
`/v1/locations/:location/layouts`
js
        const data = ["lay_shelf_B"]; //This will also delete Bins Delta, Echo and Foxtrot since they are nested under Shelf B.

fetch(`https://api.packagex.io/v1/locations/loc_8GiCVuqZqBJi43v2WebaME/layouts`, {
  method: "DELETE",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(data),
});

      

Delete Location

When deleting location, you will just need to pass in the ID of the location you want to delete into the request URL params.

DANGER

When deleting a location, it will be a soft delete. deleted_at: {{Deleted date time}}

DELETE
`/v1/locations/:locations`
js
        fetch(`https://api.packagex.io/v1/locations/loc_8GiCVuqZqBJi43v2WebaME`, {
  method: "DELETE",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
});

      

Activate Locations

To activate a deleted location, you need to pass activate_location:true in the body of the request.

POST
`/v1/locations/:locations`
js
        const data = {
activate_location: true;
};

fetch(`https://api.packagex.io/v1/locations/loc_8GiCVuqZqBJi43v2WebaME`, {
  method: "POST",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  }
 body: JSON.stringify(data),
});


      

Retrieve Single Layout

GET
`/v1/locations/:location/layouts/:layout`

If you know the id or code of your layout, you can retrieve it using that.

js
        const response = await fetch("https://api.packagex.io/v1/locations/loc_czhgjrk5JaVvyATPDbyURp/layouts/lay_binD", {
  method: "GET",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
}).then((res) => res.json());

//The result will be a single layout object
const layout = response.data;

      

List Layouts

Because we don't limit the nesting structure of your layouts, there is no predictable schema that we can set for a URL. Consequently, you can retrieve layouts via query parameters instead with the schema that you defined. Layouts will always return as an array, even if there is one value present. There is no pagination; all results for a query will be returned in the response.

Get All Layouts

This will get all layouts. Be mindful that if you have many layouts, the list of responses could be large.

js
        const response = await fetch("https://api.packagex.io/v1/locations/loc_czhgjrk5JaVvyATPDbyURp/layouts", {
  method: "GET",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
}).then((res) => res.json());

//The result is an array of layout objects
const layouts = response.data;

      

Filter Layouts

You can specify the parent path of a layout to get its direct children using parent_path in the query param. While most modern runtime will do this for you, you may need to manually encode "/" with the url correct "%2F" URL-encode value.

In the example layouts that we created above, here are the queries we would use (without %2F encoding for readability):

Nesting Level Query Param
Aisles (parent level) ...layouts?parent_path=/
Shelf A ...layouts?parent_path=/lay_shelf_A
Bin Bravo ...layouts?parent_path=/lay_shelf_A/lay_binB

Note: Bin Bravo would result in an empty array in the response object since there is nothing nested inside of it yet.

js
        const response = await fetch("https://api.packagex.io/v1/locations/loc_czhgjrk5JaVvyATPDbyURp/layouts?parent_path=/", {
  method: "GET",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
}).then((res) => res.json());

//The result is an array of layout objects
const layouts = response.data;

      

You can also filter layouts using the layout code as follows

js
        const response = await fetch("https://api.packagex.io/v1/locations/loc_czhgjrk5JaVvyATPDbyURp/layouts?code=la1", {
  method: "GET",
  headers: {
    "PX-API-KEY": process.env.PX_API_KEY,
    "Content-Type": "application/json",
  },
}).then((res) => res.json());

//The result is an array of layout objects
const layouts = response.data;