Docs & Guides
Rule Types & Options
28 min
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 each item that needs it https //paccurate readme io/docs/building rules 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 { "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 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));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" } ] }'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 { "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 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" } ] }'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)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 { "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 🚧 important using 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 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));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" } ] }'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 { "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 📘 note adding 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 providing new dimensions for the packer to try if the original dimensions do not fit 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 { "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 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 { "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= 📘 note in the pack diagram the 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 { "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 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 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 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 ] } } ] }' 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));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 "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 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 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 } } ] }' 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));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 to 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 then the item's dimensions { "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 as seen in the above visual, despite there being 2200 items in the request, the response displays 275 of the group packed item conclusion