---
title: Rule Types & Options
slug: docs/rule-types
description: Learn about Paccurate API rule types for optimizing packing decisions with operational constraints. Discover how to configure rules for orientation, dunnage, fragility, and grouped items to enhance your warehouse efficiency.
icon: 🎛️
docTags: 
createdAt: 2025-05-29T16:20:21.183Z
---

The Paccurate API becomes especially powerful once we start incorporating rules into pack requests. These rules ensure that the packing decision is made not just on weights and dimensions, but operational constraints that occur in distribution centers and pack stations. This can include accommodating for dunnage, ensuring items are packed with a specific orientation, forcing items into their own packaging, and myriad other essential business logic required by your operations. In this section we will be learning about each type of rule the API supports and how to configure them for [How To Construct A Rule](docId:-jsrxjqaLskB-7anwKCps)

In order to function properly when a pack is run, each rule requires at minimum an `operation` attribute, and depending on the rule, an `options` object.  The combination of the two are then applied to the `item` that was targeted and any `target` that was included in the rule definition.

## Options

Most `operation` values require a corresponding `options` object. These options vary for each operation. They include fields for things like dimension changes, origin, box type defaults, and more. In the sections below, we'll cover the options requirements for each type of operation.

## Operation

Put simply, the `operation` is the type of rule to be applied to the item. It is a string, and must be one of the following:

- internal-space
- alternate-dimensions
- exclude
- exclude-all
- irregular
- lock-orientation
- fragile
- group-pack

We'll cover each one more in-depth below, along with how to configure them with an `options` object.

### Exclude

Exclude is a very straightforward rule. It requires no options, simply an item (or items) it is assigned to, and targets for the item(s) to be excluded from: cartons or other items.

```text
{
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "targetItemRefIds": [
        1
      ],
      "operation": "exclude"
    }
  ]
}

```

In the example above, Item A (refId 0) has an exclude rule with a `targetItemRefIds` value of `[1]` -- this means it cannot be packed with Item B. It can, however, pack with Item C (refId 2). As you can see [here](https://inspector.manage.paccurate.io/config-editor?config=N4IglgLgpgtgylCBnEAuA2qATlAZgSQBM0AGAGhAHcowBzACwjQEYBWCwsGKAOyTAD2fNKAAeLAEwUAnpIoAvNBIAsAXwoBHAK4BDHhEizUzCjx3c0IfNBgACAIIh12PERYVqdRmnYhO3PkFhVDE5ECMADgVJdRBtPQMII2VTcyhLa1hbACEnMhcCYlQpKhoGJmLff15+IRQQkHFUADYZJRSQRWK1TV19QzQOswtUKxtbAGEnAF0KACMBUQAVaQAHKHrMUq8IAFkdJrZyEGH00YBmAFpcCFsAJR0bkA4uGqD60NRz1vC0b+ivs1VKpZiAsFoADYbNBbSCwO6uIrHCA6LC0RCZGAIwqbZiggTrLA6AxCSxQUQAYwhWkI6RBqiAA==), it does just that.

Exclude is one of Paccurate's most frequently used rules and is often used to handle branded boxes,  dangerous items, or optional SIOC.

:::CodeblockTabs
```javascript
const fetch = require('node-fetch');
const body = {
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "targetItemRefIds": [
        1
      ],
      "operation": "exclude"
    }
  ]
}
const url = 'https://api.paccurate.io/';
const options = {
  method: 'POST',
  body: JSON.stringify(body),
  headers: {accept: 'application/json', 'content-type': 'application/json'}
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));
```

```shell
curl --request POST \
     --url https://api.paccurate.io/ \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \ 
     -d '{
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "targetItemRefIds": [
        1
      ],
      "operation": "exclude"
    }
  ]
}'
```

```python
import requests

url = "https://api.paccurate.io/"
packData = {
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "targetItemRefIds": [
        1
      ],
      "operation": "exclude"
    }
  ]
}
headers = {
    "accept": "application/json",
    "content-type": "application/json"
}

response = requests.post(url, json=packData, headers=headers)

print(response.text)
```
:::

### Exclude All

If you have an item that can never pack with any other items, an easy way of excluding it from everything else is by applying an "exclude-all" rule. It behaves as described -- exclude this item from being packed with all other items.

```text
{
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "operation": "exclude-all"
    }
  ]
}

```

Applying the exclude-all rule to the same Item, [you can see](https://inspector.manage.paccurate.io/config-editor?config=N4IglgLgpgtgylCBnEAuA2qATlAZgSQBM0AGAGhAHcowBzACwjQEYBWCwsGKAOyTAD2fNKAAeLAEwUAnpIoAvNBIAsAXwoBHAK4BDHhEizUzCjx3c0IfNBgACAIIh12PERYVqdRmnYhO3PkFhVDE5ECMADgVJdRBtPQMII2VTcyhLa1hbACEnMhcCYlQpKhoGJmLff15+IRQQkHFUADYZJRSQRWK1TV19QzQOswtUKxtbAGEnAF0KACMBUQAVaQAHKHrMUq8IAFkdJrZyEGH00YBmAFpcCFsAJR0bkA4uGqD60NRz1vC0b+ivs1VKpZiAsFoADYbNBbSCwO6uIrHATrLA6AxCSxQUQAYwhWkIUEuOghEJmqiAA==) now instead of packing with Item C, it packs alone:

:::Iframe{iframeHeight="500" code="<iframe width=&#x22;600px&#x22; src=&#x22;https://inspector.manage.paccurate.io/config-editor?config=N4IglgLgpgtgylCBnEAuA2qATlAZgSQBM0AGAGhAHcowBzACwjQEYBWCwsGKAOyTAD2fNKAAeLAEwUAnpIoAvNBIAsAXwoBHAK4BDHhEizUzCjx3c0IfNBgACAIIh12PERYVqdRmnYhO3PkFhVDE5ECMADgVJdRBtPQMII2VTcyhLa1hbACEnMhcCYlQpKhoGJmLff15+IRQQkHFUADYZJRSQRWK1TV19QzQOswtUKxtbAGEnAF0KACMBUQAVaQAHKHrMUq8IAFkdJrZyEGH00YBmAFpcCFsAJR0bkA4uGqD60NRz1vC0b+ivs1VKpZiAsFoADYbNBbSCwO6uIrHATrLA6AxCSxQUQAYwhWkIUEuOghEJmqiAA==&embed=true&#x22;>"}

:::

:::CodeblockTabs
```curl
curl --request POST \
     --url https://api.paccurate.io/ \
     --header 'accept: application/json' \
     --header 'content-type: application/json'
     -d '{
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "operation": "exclude-all"
    }
  ]
}'
```

```python
import requests

url = "https://api.paccurate.io/"
packData = {
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "operation": "exclude-all"
    }
  ]
}
headers = {
    "accept": "application/json",
    "content-type": "application/json"
}

response = requests.post(url, json=packData, headers=headers)

print(response.text)
```

```nodejs
const fetch = require('node-fetch');
const body = {
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "operation": "exclude-all"
    }
  ]
}
const url = 'https://api.paccurate.io/';
const options = {
  method: 'POST',
  body: JSON.stringify(body),
  headers: {accept: 'application/json', 'content-type': 'application/json'}
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));
```
:::

### Pack As-Is (SIOC)

When an item is already packed in a shippable container, we can assign it a "pack as is" rule to ensure it is not packed with any other items and is exclusively packed in a "container" of its own dimensions. This differs from "exclude-all" because it doesn't place the item in an available carton. Like the exclude rules, "pack-as-is" does not require any options.

```text
{
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name":"Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name":"Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name":"Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "operation": "pack-as-is"
    }
  ]
}

```

Viewing this request in our inspector tool, [you can see](https://inspector.manage.paccurate.io/config-editor?config=N4IglgLgpgtgylCBnEAuA2qATlAZgSQBM0AGAGhAHcowBzACwjQEYBWCwsGKAOyTAD2fNKAAeLAEwUAnpIoAvNBIAsAXwoBHAK4BDHhEizUzCjx3c0IfNBgACAIIh12PERYVqdRmnYhO3PkFhVDE5ECMADgVJdRBtPQMII2VTcyhLa1hbACEnMhcCYlQpKhoGJmLff15+IRQQkHFUADYZJRSQRWK1TV19QzQOswtUKxtbAGEnAF0KACMBUQAVaQAHKHrMUq8IAFkdJrZyEGH00YBmAFpcCFsAJR0bkA4uGqD60NRz1vC0b+ivs1VKpZiAsFoADYbNBbSCwO6uIrHATrLA6AxCSyrHQAYwA1pcdEhLmAUCDVEA===) that Item A is not packed in the carton provided in the `boxTypes` array, but in a custom box that shares the item's dimensions.

:::Iframe{iframeHeight="500" code="<iframe width=&#x22;100%&#x22; src=&#x22;https://inspector.manage.paccurate.io/config-editor?config=N4IglgLgpgtgylCBnEAuA2qATlAZgSQBM0AGAGhAHcowBzACwjQEYBWCwsGKAOyTAD2fNKAAeLAEwUAnpIoAvNBIAsAXwoBHAK4BDHhEizUzCjx3c0IfNBgACAIIh12PERYVqdRmnYhO3PkFhVDE5ECMADgVJdRBtPQMII2VTcyhLa1hbACEnMhcCYlQpKhoGJmLff15+IRQQkHFUADYZJRSQRWK1TV19QzQOswtUKxtbAGEnAF0KACMBUQAVaQAHKHrMUq8IAFkdJrZyEGH00YBmAFpcCFsAJR0bkA4uGqD60NRz1vC0b+ivs1VKpZiAsFoADYbNBbSCwO6uIrHATrLA6AxCSyrHQAYwA1pcdEhLmAUCDVEA===&embed=true&#x22;>"}

:::

:::BlockQuote
🚧 ImportantUsing this rule does not allow the item to be combined with other items. If you have items that *can* be shipped as-is but can also be combined with other SKUs and overboxed, it requires a combination of other rules. The pack as is item price is also set to 0.
:::

Pack-as-is is most often used for large or heavy items -- things like litter or electronics that are already overboxed and tightly packed. For more advanced pack-as-is behavior, take a look at our use case article around [Ship In Own Container](https://docs.paccurate.io/docs/on-demand-cartonization#ship-in-own-container-with-optional-overboxing).

:::CodeblockTabs
```javascript
const fetch = require('node-fetch');
const body = {
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name": "Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name": "Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name": "Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "operation": "pack-as-is"
    }
  ]
};
const url = 'https://api.paccurate.io/';
const options = {
  method: 'POST',
  body: JSON.stringify(body),
  headers: {accept: 'application/json', 'content-type': 'application/json'}
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));
```

```shell
curl --request POST \
     --url https://api.paccurate.io/ \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \ 
     -d '{
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name": "Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name": "Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name": "Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "operation": "pack-as-is"
    }
  ]
}'
```

```python
import requests

url = "https://api.paccurate.io/"
packData = {
  "itemSets": [
    {
      "refId": 0,
      "weight": 15,
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 24
      },
      "quantity": 1,
      "name": "Item A"
    },
    {
      "refId": 1,
      "weight": 5,
      "dimensions": {
        "x": 12,
        "y": 8,
        "z": 12
      },
      "quantity": 4,
      "name": "Item B"
    },
    {
      "refId": 2,
      "weight": 25,
      "dimensions": {
        "x": 6,
        "y": 24,
        "z": 24
      },
      "quantity": 4,
      "name": "Item C"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 150,
      "name": "3-ft Raft",
      "dimensions": {
        "x": 36,
        "y": 36,
        "z": 36
      }
    }
  ],
  "rules": [
    {
      "itemRefId": 0,
      "operation": "pack-as-is"
    }
  ]
}
headers = {
    "accept": "application/json",
    "content-type": "application/json"
}

response = requests.post(url, json=packData, headers=headers)

print(response.text)

```
:::

### Internal Space

If an item has space inside of it that can be used to contain other items in an order, we can define that space using the `internal-space` rule.  At a high level, we are creating a new `boxType` that is attached to the item, and adding some additional properties such as where the subspace is in relation to the item and how to represent the items packed within it.

```text
{
  "rules":[
  {
    "operation": "internal-space",
    "itemRefId": 0,
    "options": {
      "type": "subspace",
      "boxType": {
        "weightMax": 2,
        "name": "Item A interior",
        "price": 0,
        "dimensions": {
          "x": 1.5,
          "y": 1.5,
          "z": 1.5
        }
      },
      "origin": {
        "x": 0.25,
        "y": 1,
        "z": 1
      },
      "display": true,
      "displayChildren": true
    }
  }
 ]
}

```

Let's break down the rule above. First, the `operation` is set to "internal-space", which tells the API we're creating some space on an item (`"itemRefId":0`). With the operation defined and item selected, we create an `options` object. The options object has 2 required properties: `type`, `boxType` and 3 optional properties:`origin`, `display`, and `displayChildren`.

- `type`: String, must be set to "subspace" -- this tells the API that the box being created in the `boxType` property is a subspace of the parent box in which the item will be packed
- `boxType`: BoxType, these are the same properties as any type of box defined in a pack request. It requires a `dimensions` object containing the length, width, and height (x,y, and z properties), and `weightMax` integer value. In order to do any sort of targeting for exclusion, we'd want to add refId as well. A property called `name` can be added as well, helping better clarify the box type when it is returned by the API pack response.
- `origin`: Point, with x, y and z coordinates. This property defines where the subspace is positioned relative to the item's origin.
- `display`: Boolean. When set to `true`, the subspace is displayed as dotted lines in the response image within the item in the parent carton
- `displayChildren`: Boolean. When set to `true`, the items packed inside the subspace will be displayed inside the parent carton. Otherwise, they will only be displayed in the returned subspace box image as part of the pack response.

:::BlockQuote
📘 NoteAdding an internal-space rule will return a box in the response for each item that has a space attached to it, regardless of if the internal space has items packed inside. The box in the response will have a subspace property.
:::

### Alternate Dimensions

Sometimes, an item's dimensions provided from a WMS or ERP may not be wholly accurate: that is, the item can shrink, fold, or expand when it is placed into a carton to be shipped. To accommodate the real-life packing behavior, we can use the Alternate Dimensions rule. Alternate dimensions can work two ways:

1. Providing new dimensions for the Packer to try if the original dimensions do not fit
2. Providing new dimensions to replace the original dimensions when packing the item.

The options available to this rule are:

- `dimensions`: a list of additional dimensions that will be attempted when packing the item. These dimensions are sorted ascending by volume
- `dimensionChanges`: a list of dimension change vectors that are applied to the item dimensions that will be used when packing is attempted. These are fixed numbers (think: "1.5 inches")
- `dimensionScaleChanges`: a list of dimension scale-change vectors that are multiplied with the item's original dimensions to generate new packing dimensions. These are percentages (think: 30% shorter, 10% taller)
- `replaceOriginal`: when set to true, the original item dimensions are ignored and only the dimensions generated by this rule are considered.

Combined with concise item targeting, this rule can be quite powerful. Here is an example rule where T-Shirt items are "folded" virtually before being placed in their carton.

```text
{
  "itemSets": [
    {
      "refId": 0,
      "weight": 0.5,
      "dimensions": {
        "x": 0.5,
        "y": 12,
        "z": 18
      },
      "quantity": 2,
      "name": "Fold This t-shirt"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 40,
      "name": "T-Shirt Box",
      "dimensions": {
        "x": 4,
        "y": 11,
        "z": 16
      }
    }
  ],
  "rules": [
    {
      "operation": "alternate-dimensions",
      "itemMatch": {
        "property": "name",
        "expression": "t-shirt"
      },
      "options": {
        "replaceOriginal": true,
        "dimensionScaleChanges": [
          {
            "x": 0.5,
            "z": -0.66
          }
        ]
      }
    }
  ]
}

```

As you can see above, the dimensions of the shirt provided to the API include a length of 18, which is longer than our available container (at 16). By adding an alternate dimensions rule, and setting `replaceOriginal` to `true`, we are able to reduce the length of the item by 2/3 (66% or `-0.66`), make the height a little taller to accommodate that folded material, and place the shirts into the box:

:::Iframe{iframeHeight="800" code="<iframe width=&#x22;500&#x22; src=&#x22;https://inspector.manage.paccurate.io/config-editor?config=N4IglgLgpgtgylCBnEAuA2qATlAZgSQBM0AGAGhAHcowBzACwlIDoBWCwsGKAOyTAD2fNKAAeLdiACeaAIwAmCgC85ADgC+FAI4BXAIY8IkGakUgee7mhAAxAQBtCAAgAq9MEicQAtEndYmdQBdCgAjAVEXKQAHKBQMUGo6RgBZPXFUABZyc0soaxdvOH8IJwAhCJAOLl5+IXixNEyKE1lZZTkANnVgiiwdezi0TBABWKw9IyFrPXtoLAtob05uPkFhCkhYNIgAY3oREGisMagAk1yrCihRY7i6nmsfPzAAkE1R6KnhVGwoaPsel2UAA8lg6GALPY0BB+lBqqsHnBdrMoABhegGWhDBIgDIkNgdVDeAmdbpBHoUoA===&embed=true&#x22;>"}

:::

As shown in the response visualization -- the height is now .75 (.5 x 1.5), the length is now 6.12 (18 x .66), and the width remains the same at 12. Other use cases for this rule would be applying dunnage on any or all axes, or compact-able items whose native dimensions can shrink when placed in a carton.

### Irregular

Irregular is a rule specifically for items that are on spools or rolls. A rolled irregular item is simply where the item dimensions X, Y, and Z, represent the thickness, width, and total length of a material meant to be rolled up (possibly on a spool, dowel, etc.) and shipped as such. Marked this way, the bounding box of the roll cylinder will be used as its shipping dimensions. E.g., a roll has a width 60 inches and a diameter of 12 inches, it will be shipped as if it were a 12" x 12" x 60" item. Rolls can have a maximum allowable diameter, and any rolls that must be split will have their weights calculated on a pro-rated basis of the total length and weight in the item contents.

The options for the Irregular rule are:

- `type` must be set to "roll"
- `innerDiameter` Is a number that represents the diameter of the dowel or tube that sets the initial diameter of the roll
- `spoolWeight` is a number representing the weight of the spool, if applicable
- `maxDiameter` is a number representing the maximum acceptable diameter of the generated roll
- `maxWeight` is a number representing the maximum acceptable weight of the generated roll
- `minRollLength` is the minimum length that causes the rolling behavior. For example, if less than 12", ship the item flat without rolling.

Here is an example config with pair of rollable items

```text
{
  "itemSets": [
    {
      "refId": 1,
      "quantity": 1,
      "dimensions": {
        "x": 5,
        "y": 11.25,
        "z": 22
      },
      "weight": 1,
      "name": "Rollable Item 1",
      "color": "#5e2144",
      "sequence": "rollable"
    },
    {
      "refId": 2,
      "quantity": 1,
      "dimensions": {
        "x": 9.25,
        "y": 5,
        "z": 10
      },
      "weight": 1,
      "name": "Rollable Item 2",
      "color": "#523131",
      "sequence": "rollable"
    }
  ],
  "boxTypes": [
    {
      "weightMax": 40,
      "name": "T-Shirt Box",
      "dimensions": {
        "x": 18,
        "y": 18,
        "z": 18
      }
    }
  ],
  "rules": [
    {
      "operation": "irregular",
      "itemRefId": 1,
      "options": {
        "type": "roll",
        "innerDiameter": 0.5,
        "spoolWeight": 0.25,
        "maxDiameter": 6.75,
        "maxWeight": 10.5,
        "minRollLength": 2
      }
    },
    {
      "operation": "irregular",
      "itemRefId": 2,
      "options": {
        "type": "roll",
        "innerDiameter": 1.5,
        "spoolWeight": 0.25,
        "maxDiameter": 6.75,
        "maxWeight": 10.5,
        "minRollLength": 2
      }
    }
  ]
}

```

Executed, the API packs it [like this](https://inspector.manage.paccurate.io/config-editor?config=N4IglgLgpgtgylCBnEAuA2qATlAZgSQBM0BGAGhAEcBXAQwDsJIBPUiwsGKepMAex5pQADzQBWCq1QkSAOgBMEkAC808+QF8KAdyhgA5gAsIbEPVpc0IAEp8ANndoAjO1AAE+aDDckQFAMb2fFhWAMRiUPIkACzRfiBIUDTc/lBWWPaOLmla2HhEahQ0DEwQUuQgHFw8/IKoImgAnApKUkqq0gAMWiC6Bsam5paoNpnOrh5ebvLxgXbBYWLyAMwkq/GJyfSp6WPZIBoAuhROfMIAKswADlAoGKB9RhAAsrSiqNGdFENpI+cAtHBDGAsBA3AAhM7xKrcXgCO4NaQADkkpBRKjRGiOFCw1Fcd0wID4NywtCYAisIJw+jxtBCFEgsGs+WI0goxPJdVAZRuuwc8TA9HoUCwABEwBZECK0J1ZEokFc+PYAOp6J4yloUGBvcWS6AhVAANlkAHYlNrhKr+iYunKtYLbA4ADLcfQQQxqLFkUDEkVk2qUrDU2n08BeZkEVnydlXTkIkA834gDL8hlCkW6rj60h2hKKlVqgaoWWKLU6iVZ6VG03mt5W9W280OzIu+huj2oTRHDRAA=):



:::Iframe{iframeHeight="800" code="<iframe width=&#x22;100%&#x22; src=&#x22;https://inspector.manage.paccurate.io/config-editor?config=N4IglgLgpgtgylCBnEAuA2qATlAZgSQBM0BGAGhAEcBXAQwDsJIBPUiwsGKepMAex5pQADzQBWCq1QkSAOgBMEkAC808+QF8KAdyhgA5gAsIbEPVpc0IAEp8ANndoAjO1AAE+aDDckQFAMb2fFhWAMRiUPIkACzRfiBIUDTc/lBWWPaOLmla2HhEahQ0DEwQUuQgHFw8/IKoImgAnApKUkqq0gAMWiC6Bsam5paoNpnOrh5ebvLxgXbBYWLyAMwkq/GJyfSp6WPZIBoAuhROfMIAKswADlAoGKB9RhAAsrSiqNGdFENpI+cAtHBDGAsBA3AAhM7xKrcXgCO4NaQADkkpBRKjRGiOFCw1Fcd0wID4NywtCYAisIJw+jxtBCFEgsGs+WI0goxPJdVAZRuuwc8TA9HoUCwABEwBZECK0J1ZEokFc+PYAOp6J4yloUGBvcWS6AhVAANlkAHYlNrhKr+iYunKtYLbA4ADLcfQQQxqLFkUDEkVk2qUrDU2n08BeZkEVnydlXTkIkA834gDL8hlCkW6rj60h2hKKlVqgaoWWKLU6iVZ6VG03mt5W9W280OzIu+huj2oTRHDRAA=&embed=true&#x22;>"}

:::



:::BlockQuote
📘 Note in the pack diagramThe items are "spooled" where applicable, and remaining "length" is rendered as flat.
:::

### Lock Orientation

The `lock-orientation` rule is used to force a specific orientation of an item when the item is placed in a carton. For example, a bottle of liquid should not be packed on its side, or any type of item whose movement is restricted to one or two axes. This prevents the API from trying to place the item at an orientation that is not permitted in practice.

The options object for `lock-orientation` has just one value:

- `freeAxes`: An array of 1-2 axis indices that denote which axes can be rotated. Ex: \[0,1] would mean the item can be rotated on its x and y (pitch and yaw) axes.

```text
{
  "boxTypeChoiceGoal": "lowest-cost",
  "itemSets": [
    {
      "refId": 0,
      "quantity": 1,
      "dimensions": {
        "x": 12,
        "y": 5,
        "z": 3
      },
      "weight": 1,
      "name": "Ship Upright",
      "color": "#1fd12b",
      "sequence": "tall"
    },
    {
      "refId": 2,
      "quantity": 1,
      "dimensions": {
        "x": 9.25,
        "y": 5,
        "z": 10
      },
      "weight": 1,
      "name": "Item 2",
      "color": "#2e00e6",
      "sequence": ""
    }
  ],
  "boxTypes": [
    {
      "weightMax": 40,
      "name": "tall box",
      "dimensions": {
        "x": 18,
        "y": 18,
        "z": 18
      }
    },
    {
      "weightMax": 40,
      "name": "short box",
      "dimensions": {
        "x": 6,
        "y": 16,
        "z": 10
      }
    }
  ],
  "rules": [
    {
      "operation": "lock-orientation",
      "itemRefId": 0,
      "options": {
        "freeAxes": [
          0
        ]
      }
    }
  ]
}

```

Given the config above, the "Ship Upright" item (targeted using `"itemRefId":0`) has only one free axis -- its vertical axis (X), noted here as 0. With the rule applied, the order is packed as such:

:::Iframe{iframeHeight="800" code="<iframe width=&#x22;100%&#x22; height=&#x22;100&#x22; src=&#x22;https://inspector.manage.paccurate.io/config-editor?config=N4IgRg9gHgKgngBwKYGEAWECWBjJBxCAQwBsQAuEYiAdyQGcAXAWmwkZABoRMGkBbAMpIGdcgG1QAJyQAzAJIATcgAYuARwCuhAHYMeccgEYuCzHyTa6mCJfKgoRgExcDZAKxcAXuQDMAXy5aTABzNAYjLm1Cc3IQATRMBAACAFUESRCwzhBWKklYgGJDGQVDRzBsuiRNC1xYhhJSAKlZRXJnEE0dPQZXYxBTc0trWzJ7cgBOADpHDxBXOe8yQ2UAkCDQ8OXI6KRYuV4+JMds3Ih8igLHJGVlJAA2SuqNWr2KED8AXS5IWER6cSgDZhACyhAcZAALKoQFEYhQGsRiElftlBhYrDZRGMQBDDAAOFxGQkgJYEvzNdZITIMMEQ6E7eEgOgYSQMFHQNFmDEjbHjMj3InLQWkoyrL5cSQaYgAsgSEAQZCSQh6GyxKjYADWTHOmAsDVV2myPH4ACVWkoyDDFYa+SAZNIkABBKCysTKT4Uz1AA=&embed=true&#x22;>"}

:::

As you can see, the green upright item is in fact shipped upright. Now, adding an [additional axis to rotate on](https://inspector.manage.paccurate.io/config-editor?config=N4IgRg9gHgKgngBwKYGEAWECWBjJBxCAQwBsQAuEYiAdyQGcAXAWmwkZABoRMGkBbAMpIGdcgG1QAJyQAzAJIATcgAYuARwCuhAHYMeccgEYuCzHyTa6mCJfKgoRgExcDZAKxcAXuQDMAXy5aTABzNAYjLm1Cc3IQATRMBAACAFUESRCwzhBWKklYgGJDGQVDRzBsuiRNC1xYhhJSAKlZRXJnEE0dPQZXYxBTc0trWzJ7cgBOADpHDxBXOe8yQ2UAkCDQ8OXI6KRYuV4+JMds3Ih8igLHJGVlJAA2SuqNWr2KED8AXS5IWER6cSgDZhACyhAcZAALKoQFEYhQGsRiElftlBhYrDZRGMQBDDAAOFxGQkgJYEvzNdZITIMMEQ6E7eEgOgYSQMFHQNFmDEjbHjMj3InLQWkoyrL5cSQaYgAsgSEAQZCSQh6GyxKjYADWTHOmAsDVV2myPH4ACVWkoyDDFYa+SAZNIkABBKCysSqRyfCleoA) (`"freeAxes":[0,2]`), the item can ship laying down, and our shipment "cost" is 1920 instead of 5832 in the previous configuration.

:::Iframe{iframeHeight="800" code="<iframe src=&#x22;https://inspector.manage.paccurate.io/config-editor?config=N4IgRg9gHgKgngBwKYGEAWECWBjJBxCAQwBsQAuEYiAdyQGcAXAWmwkZABoRMGkBbAMpIGdcgG1QAJyQAzAJIATcgAYuARwCuhAHYMeccgEYuCzHyTa6mCJfKgoRgExcDZAKxcAXuQDMAXy5aTABzNAYjLm1Cc3IQATRMBAACAFUESRCwzhBWKklYgGJDGQVDRzBsuiRNC1xYhhJSAKlZRXJnEE0dPQZXYxBTc0trWzJ7cgBOADpHDxBXOe8yQ2UAkCDQ8OXI6KRYuV4+JMds3Ih8igLHJGVlJAA2SuqNWr2KED8AXS5IWER6cSgDZhACyhAcZAALKoQFEYhQGsRiElftlBhYrDZRGMQBDDAAOFxGQkgJYEvzNdZITIMMEQ6E7eEgOgYSQMFHQNFmDEjbHjMj3InLQWkoyrL5cSQaYgAsgSEAQZCSQh6GyxKjYADWTHOmAsDVV2myPH4ACVWkoyDDFYa+SAZNIkABBKCysSqRyfCleoA&embed=true&#x22; width=&#x22;100%&#x22;>"}

:::

Locking an item's orientation can have significant impacts on overall packing performance, as it will restrict the types of containers an item can be packed into. If your item master contains a lot of items with orientation constraints, it may be beneficial to [audit your available cartons](https://paccurate.io/pacsimulate) to make sure they are optimized for those constraints.

:::CodeblockTabs
```shell
curl --request POST \
     --url https://api.paccurate.io/ \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \ 
     -d '{
  "boxTypeChoiceGoal": "lowest-cost",
  "itemSets": [
    {
      "refId": 0,
      "quantity": 1,
      "dimensions": {
        "x": 12,
        "y": 5,
        "z": 3
      },
      "weight": 1,
      "name": "Ship Upright",
      "color": "#1fd12b",
      "sequence": "tall"
    },
    {
      "refId": 2,
      "quantity": 1,
      "dimensions": {
        "x": 9.25,
        "y": 5,
        "z": 10
      },
      "weight": 1,
      "name": "Item 2",
      "color": "#2e00e6",
      "sequence": ""
    }
  ],
  "boxTypes": [
    {
      "weightMax": 40,
      "name": "tall box",
      "dimensions": {
        "x": 18,
        "y": 18,
        "z": 18
      }
    },
    {
      "weightMax": 40,
      "name": "short box",
      "dimensions": {
        "x": 6,
        "y": 16,
        "z": 10
      }
    }
  ],
  "rules": [
    {
      "operation": "lock-orientation",
      "itemRefId": 0,
      "options": {
        "freeAxes": [
          0
        ]
      }
    }
  ]
}'

```

```nodejs
const fetch = require('node-fetch');
const body = {
  "boxTypeChoiceGoal": "lowest-cost",
  "itemSets": [
    {
      "refId": 0,
      "quantity": 1,
      "dimensions": {
        "x": 12,
        "y": 5,
        "z": 3
      },
      "weight": 1,
      "name": "Ship Upright",
      "color": "#1fd12b",
      "sequence": "tall"
    },
    {
      "refId": 2,
      "quantity": 1,
      "dimensions": {
        "x": 9.25,
        "y": 5,
        "z": 10
      },
      "weight": 1,
      "name": "Item 2",
      "color": "#2e00e6",
      "sequence": ""
    }
  ],
  "boxTypes": [
    {
      "weightMax": 40,
      "name": "tall box",
      "dimensions": {
        "x": 18,
        "y": 18,
        "z": 18
      }
    },
    {
      "weightMax": 40,
      "name": "short box",
      "dimensions": {
        "x": 6,
        "y": 16,
        "z": 10
      }
    }
  ],
  "rules": [
    {
      "operation": "lock-orientation",
      "itemRefId": 0,
      "options": {
        "freeAxes": [
          0
        ]
      }
    }
  ]
}
const url = 'https://api.paccurate.io/';
const options = {
  method: 'POST',
  body: JSON.stringify(body),
  headers: {accept: 'application/json', 'content-type': 'application/json'}
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));
```

```python
import requests

url = "https://api.paccurate.io/"
packData = {
  "boxTypeChoiceGoal": "lowest-cost",
  "itemSets": [
    {
      "refId": 0,
      "quantity": 1,
      "dimensions": {
        "x": 12,
        "y": 5,
        "z": 3
      },
      "weight": 1,
      "name": "Ship Upright",
      "color": "#1fd12b",
      "sequence": "tall"
    },
    {
      "refId": 2,
      "quantity": 1,
      "dimensions": {
        "x": 9.25,
        "y": 5,
        "z": 10
      },
      "weight": 1,
      "name": "Item 2",
      "color": "#2e00e6",
      "sequence": ""
    }
  ],
  "boxTypes": [
    {
      "weightMax": 40,
      "name": "tall box",
      "dimensions": {
        "x": 18,
        "y": 18,
        "z": 18
      }
    },
    {
      "weightMax": 40,
      "name": "short box",
      "dimensions": {
        "x": 6,
        "y": 16,
        "z": 10
      }
    }
  ],
  "rules": [
    {
      "operation": "lock-orientation",
      "itemRefId": 0,
      "options": {
        "freeAxes": [
          0
        ]
      }
    }
  ]
}
headers = {
    "accept": "application/json",
    "content-type": "application/json"
}

response = requests.post(url, json=packData, headers=headers)

print(response.text)
```
:::

### Fragile

Paccurate provides a `fragile` rule that ensures fragile items are not packed in a manner that may harm them in shipping. This could mean ensuring the fragile item is only placed on top of other items, defining a maximum weight for an item that can be placed on top of the fragile item, or even excluding it from being packed with heavier items.

The options object for `fragile` supports 5 values:

- `display`: a boolean value determining whether or not to display the reserved subspace above the fragile item in the returned pack image. Useful for analysis purposes.
- `maxWeight`: a number value defining the maximum weight of items that can be placed above the fragile item.
- `onTopOnly`: a boolean value that instructs Paccurate whether or not additional items can be placed above the fragile item this rule is applied to. This will override the maxWeight parameter if it is being passed as an option.
- `excludeOverweight`: a boolean value that automatically excludes the fragile item from being packed with items that exceed the weight defined in `maxWeight` and have a different refId.
- `unrestrictedPlacement`: a boolean value that bypasses the creation of reserved subspaces above each item, as well was overrides `onTopOnly` if previously specified.

In the example configuration below, we are looking for items with the string "frag" in the sequence to assign the fragile rule. This rule sets a max weight of 3, and excludes the fragile item from being packed with items over 3. Setting "unrestrictedPlacement" to true enables multiple fragile items to be placed on top of each other.

```text
"rules": [
    {
      "itemMatch": {
        "property": "sequence",
        "expression": "frag"
      },
      "operation": "fragile",
      "options": {
        "display": false,
        "onTopOnly": false,
        "maxWeight": 3,
        "excludeOverweight": true,
        "unrestrictedPlacement": true
      }
    }
  ]

```

[Here](https://inspector.manage.paccurate.io/config-editor?config=N4IgRg9gHgKgngBwKYGEAWECWBjJBxCAQwBsQAuEAWwgGcAXAWkzqUppABoRnWBlJOuzIBtUACckAMwCSAE3IBGLgEcAroQB2dZnHIAOLrMyUkGmpghnyoKOQDMXXWQCsXAF7kALAF8uAdyRMAHM0OkUuDUITchAAMTFCIMxiJAACaRZKThBsCGIIMRiAYk9nAAYATgAmMGyaJDVTXBjJBKCQX3EpOXIqlXUtHV7DY1NzSyEbRWcAOgB2VxAnBU8ZxY8XXxAA4NDFMoiopBiACSRCADc4dMzs3PzCihKKgDZZO2cOji6ZeTIHEBqTTaOhOTwjExmCxWMhTFyOLzuchzLY7EJhMirRaRaIUAByBUoJFSPCyXHuBWKLzsnjKVSqHQAulxILBEEghKIQBJfvZ/IF0QBZQi2MgKcqHXEgAAyhDEQTSACFoNkjJDxjC4QoDEtFC8kWR6d5Otzun8AWjQsLReKDiAcccKIKkLJUsrbBCxtDJiAbUpdWQKgbxcbmdzVClOaBScK6Ng0NYQAgxBBkGJQTF6o0NM0uEgoMmORqWm0viBU0gEtpLCXEsljlxU9XNSAjDQEMRCE5JCR6o2NDBUwB5DTEbu9pBcIlQADqAr2/zzUGwxFUsiQQ4ulctGLoYlUk5Aqg0EnoYhwLFkAAVO7hIbv90hQ94gA) is a diagram of the items being packed into two boxes, despite there being room for all of the items to be packed together in one large box:

:::Iframe{iframeHeight="800" code="<iframe width=&#x22;100%&#x22; src=&#x22;https://inspector.manage.paccurate.io/config-editor?config=N4IgRg9gHgKgngBwKYGEAWECWBjJBxCAQwBsQAuEAWwgGcAXAWkzqUppABoRnWBlJOuzIBtUACckAMwCSAE3IBGLgEcAroQB2dZnHIAOLrMyUkGmpghnyoKOQDMXXWQCsXAF7kALAF8uAdyRMAHM0OkUuDUITchAAMTFCIMxiJAACaRZKThBsCGIIMRiAYk9nAAYATgAmMGyaJDVTXBjJBKCQX3EpOXIqlXUtHV7DY1NzSyEbRWcAOgB2VxAnBU8ZxY8XXxAA4NDFMoiopBiACSRCADc4dMzs3PzCihKKgDZZO2cOji6ZeTIHEBqTTaOhOTwjExmCxWMhTFyOLzuchzLY7EJhMirRaRaIUAByBUoJFSPCyXHuBWKLzsnjKVSqHQAulxILBEEghKIQBJfvZ/IF0QBZQi2MgKcqHXEgAAyhDEQTSACFoNkjJDxjC4QoDEtFC8kWR6d5Otzun8AWjQsLReKDiAcccKIKkLJUsrbBCxtDJiAbUpdWQKgbxcbmdzVClOaBScK6Ng0NYQAgxBBkGJQTF6o0NM0uEgoMmORqWm0viBU0gEtpLCXEsljlxU9XNSAjDQEMRCE5JCR6o2NDBUwB5DTEbu9pBcIlQADqAr2/zzUGwxFUsiQQ4ulctGLoYlUk5Aqg0EnoYhwLFkAAVO7hIbv90hQ94gA&embed=true&#x22;>"}

:::

When considering additional packing materials as part of fragility packing, you will want to [use an alternate-dimensions rule](https://paccurate.readme.io/docs/rule-types#alternate-dimensions) to accommodate for the change in packed dimensions for the item.

:::CodeblockTabs
```shell
curl --request POST \
     --url https://api.paccurate.io/ \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \ 
     -d '{
  "boxTypeChoiceGoal": "most-items",
  "itemSets": [
    {
      "refId": 1,
      "quantity": 8,
      "dimensions": {
        "x": 3,
        "y": 5,
        "z": 4
      },
      "weight": 1,
      "name": "Fragile Item",
      "color": "#45092b",
      "sequence": "frag"
    },
    {
      "refId": 2,
      "quantity": 2,
      "dimensions": {
        "x": 15.75,
        "y": 14.5,
        "z": 5
      },
      "weight": 10,
      "name": "Heavy Item",
      "color": "#496d35"
    },
    {
      "refId": 3,
      "quantity": 4,
      "dimensions": {
        "x": 5,
        "y": 4,
        "z": 7
      },
      "weight": 4.5,
      "name": "Normal item",
      "color": "#634022"
    }
  ],
  "boxTypes": [
    {
      "refId": 3,
      "weightMax": 150,
      "name": "Large Box",
      "dimensions": {
        "x": 18,
        "y": 16,
        "z": 22
      }
    },
    {
      "refId": 3,
      "weightMax": 150,
      "name": "Med Box",
      "dimensions": {
        "x": 11,
        "y": 9,
        "z": 15
      }
    }
  ],
  "rules": [
    {
      "itemMatch": {
        "property": "sequence",
        "expression": "frag"
      },
      "operation": "fragile",
      "options": {
        "display": false,
        "onTopOnly": false,
        "maxWeight": 3,
        "excludeOverweight": true,
        "unrestrictedPlacement": true
      }
    }
  ]
}'

```

```nodejs
const fetch = require('node-fetch');
const body = {
  "boxTypeChoiceGoal": "most-items",
  "itemSets": [
    {
      "refId": 1,
      "quantity": 8,
      "dimensions": {
        "x": 3,
        "y": 5,
        "z": 4
      },
      "weight": 1,
      "name": "Fragile Item",
      "color": "#45092b",
      "sequence": "frag"
    },
    {
      "refId": 2,
      "quantity": 2,
      "dimensions": {
        "x": 15.75,
        "y": 14.5,
        "z": 5
      },
      "weight": 10,
      "name": "Heavy Item",
      "color": "#496d35"
    },
    {
      "refId": 3,
      "quantity": 4,
      "dimensions": {
        "x": 5,
        "y": 4,
        "z": 7
      },
      "weight": 4.5,
      "name": "Normal item",
      "color": "#634022"
    }
  ],
  "boxTypes": [
    {
      "refId": 3,
      "weightMax": 150,
      "name": "Large Box",
      "dimensions": {
        "x": 18,
        "y": 16,
        "z": 22
      }
    },
    {
      "refId": 3,
      "weightMax": 150,
      "name": "Med Box",
      "dimensions": {
        "x": 11,
        "y": 9,
        "z": 15
      }
    }
  ],
  "rules": [
    {
      "itemMatch": {
        "property": "sequence",
        "expression": "frag"
      },
      "operation": "fragile",
      "options": {
        "display": false,
        "onTopOnly": false,
        "maxWeight": 3,
        "excludeOverweight": true,
        "unrestrictedPlacement": true
      }
    }
  ]
}
const url = 'https://api.paccurate.io/';
const options = {
  method: 'POST',
  body: JSON.stringify(body),
  headers: {accept: 'application/json', 'content-type': 'application/json'}
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error('error:' + err));
```

```python
import requests

url = "https://api.paccurate.io/"
packData = {
  "boxTypeChoiceGoal": "most-items",
  "itemSets": [
    {
      "refId": 1,
      "quantity": 8,
      "dimensions": {
        "x": 3,
        "y": 5,
        "z": 4
      },
      "weight": 1,
      "name": "Fragile Item",
      "color": "#45092b",
      "sequence": "frag"
    },
    {
      "refId": 2,
      "quantity": 2,
      "dimensions": {
        "x": 15.75,
        "y": 14.5,
        "z": 5
      },
      "weight": 10,
      "name": "Heavy Item",
      "color": "#496d35"
    },
    {
      "refId": 3,
      "quantity": 4,
      "dimensions": {
        "x": 5,
        "y": 4,
        "z": 7
      },
      "weight": 4.5,
      "name": "Normal item",
      "color": "#634022"
    }
  ],
  "boxTypes": [
    {
      "refId": 3,
      "weightMax": 150,
      "name": "Large Box",
      "dimensions": {
        "x": 18,
        "y": 16,
        "z": 22
      }
    },
    {
      "refId": 3,
      "weightMax": 150,
      "name": "Med Box",
      "dimensions": {
        "x": 11,
        "y": 9,
        "z": 15
      }
    }
  ],
  "rules": [
    {
      "itemMatch": {
        "property": "sequence",
        "expression": "frag"
      },
      "operation": "fragile",
      "options": {
        "display": false,
        "onTopOnly": false,
        "maxWeight": 3,
        "excludeOverweight": true,
        "unrestrictedPlacement": true
      }
    }
  ]
}
headers = {
    "accept": "application/json",
    "content-type": "application/json"
}

response = requests.post(url, json=packData, headers=headers)

print(response.text)
```
:::

### Group Pack

When packing large quantities of smaller items (think: hundreds of doses of medicine, any item that ships in large unit quantities) it is much more expedient to pack the items as a grouped unit. Our `group-pack` rule enables this logic. Paccurate uses the smallest available `boxType` dimension to determine when a group pack rule should be triggered. The options for `group-pack` are as follows:

- `scaleFactorThreshold`: a number that is used as a numerator when comparing an item's axis dimension against the smallest boxType's same dimension. For example, if this were set to 10, the item scaling would only apply if the item's dimensions are 1/10th the height of the smallest box height.
- `axes`: a list of the numerical value of axes for scaling to be applied to.
- `axisMultiplier`: a number by which each dimension is multiplied to create the "group" size of the pack.
- `nameSuffix`: a string that is appended to the item name in the pack response when group pack is applied to the item

When an item is small enough to trigger group-pack, Paccurate will use the scaled dimensions of the item to pack the grouped items in a carton. For example, if there was a quantity of 1000 small items as part of the request, the API would convert that 1000 into 10 units of 100, and pack those 10 100-unit instances.

In the following example, we create a group pack rule that doubles the dimensions of all axes if the smallest container is 4x larger than the item's dimensions.

```text
{
  "itemSets": [
    {
      "refId": 1,
      "weight": 0.16,
      "dimensions": {
        "x": 0.5,
        "y": 1,
        "z": 1
      },
      "quantity": 2200
    }
  ],
  "boxTypes": [
    {
      "refId": 3,
      "weightMax": 800,
      "name": "12 Box",
      "dimensions": {
        "x": 12,
        "y": 12,
        "z": 12
      }
    }
  ],
"rules": [
    {
      "operation": "group-pack",
      "itemMatch": {
        "all": true
      },
      "options": {
        "scaleFactorThreshold": 4,
        "axes": [
          0,
          1,
          2
        ],
        "axisMultiplier": 2,
        "type": "auto",
        "nameSuffix": "auto-case-100"
      }
    }
  ]
}

```

Paccurate returns a response with all 2200 items packed in one container.

:::Iframe{code="<iframe src=&#x22;https://inspector.manage.paccurate.io/config-editor?config=N4IgRg9gHgKgngBwKYGEAWECWBjJBxCAQwBsQAuEAWwgGcAXAWkzqUppABoRnWBlJOuzIBtUACckAMwCSAE3IBGLgHckmAOZo65AAwA6BQDYuszJSQA7GpghXyoKLr0BWLnEVcAXooC+XAI4AroQWdMzuZABMkTo6PgC6XJCwiEhCoiASMvJkAMwqapp0ALKEjmQAHLFcFoTm5CAKkQAEAELQnCCm5lY2dmQOipFuQ15DPglcYoHEaeQZEMhihGG2DepiEIEIDAiE2ADWnTyUpXTYaPYgJKRkdNNIfiCLq/2gNNgkSABi+3QQYhgaAkNAwxByABYuGU5iIdBwlJFEtcoJgaMUZmEEMRMEgxORhiA6KkGoRAv9OrVzLxApJJJhytdyRAGJ8aEgGApYiAJvEfEA===&embed=true&#x22; height=&#x22;800&#x22; width=&#x22;100%&#x22;>"}

:::

As seen in the above visual, despite there being 2200 items in the request, the response displays 275 of the group-packed item.

## Conclusion

