Skip to main content

Inventory

ION tracks parts by serial number or lot number. You can also leave a part untracked and record only its quantity. Part inventory holds information about a part and sets it up so you can track it in runs and aBOM construction.

Inventory tracking types

Query part inventories

List part inventory with a filter:
Set the filter variables:
Get a single part inventory record by ID:

Create part inventories

When you specify no quantity, the inventory object has a quantity of 0. You can also autogenerate the serial number or lot number. Create the inventory with this mutation:
A serialized part can also belong to a lot, so the input can include a lot number. A serial-tracked part cannot have a quantity greater than 1. Set the variables for a serialized part:
Set the variables for a lot-tracked part:
Autogenerate a serial or lot number with these variables:

Update inventory items

You can change almost all the fields on an inventory object except its relation to the part it is an instance of. All the quantity and tracking-type validations enforced on creation are also enforced on update. Update the inventory with this mutation:
Set the variables:

Delete part inventories

Delete the inventory with this mutation:
Set the variables:

Issue parts to runs

Part kits

Part kits let you allocate specific parts and quantities for a run. To create a part kit, you must already have a run. See the Runs example for how to create one. To remove parts from inventory and attach them to the run that consumes them, use a part kit object. Create a kit with this mutation:
Set the variables:

Issue inventory to kits

To move parts from inventory into the part kit, use the issueItemToKit mutation. Whether a part is serial-tracked, lot-tracked, or untracked, you reference its partInventoryId and, when the item is not serial-tracked, the quantity you want to issue to that kit: Issue an item to the kit with this mutation:
Set the variables:
Issuing serials, lots, or untracked parts uses the same issueItemToKit mutation. When you issue parts to a kit, the kit shows the quantity of that required part fulfilled as issuedQuantity. The quantity is decremented from the original inventory object. When your organization enforces pickable locations, issueItemToKit refuses inventory that sits at a location not marked pickable, with a VALIDATION_ERROR:

Kitting WIP inventory for outside processing

When the organization setting allowWipOspKitting is on, WIP inventory can be issued to a kit if it’s linked to a purchase order line through an outside processing (OSP) run step. PartInventory.isLinkedToOspPoLine reports that, and you can filter on it.
Breaking change for API consumers. In July 2026 this field was briefly live in the API as isLinkedToSkipInventoryPoLine, though it never appeared in this reference’s schema, and it required the purchase order line to have skip_inventory_creation set. It’s now isLinkedToOspPoLine, on both PartInventory and PartInventoriesInputFilters, and it keys on the run step being marked outside processing. skip_inventory_creation no longer plays a part. Rename the field in any query or filter that used the old name. A query that still asks for the old field fails with Cannot query field.

Move parts back to inventory

Once a serial-tracked part is built, move it back to inventory for use on a higher-level assembly. Move an item back to inventory with this mutation:
Set the variables:
You must include the quantity you are moving back to inventory. For a lot-tracked or untracked item, this quantity can be less than the full amount originally issued.

Query part kits

List part kits with a filter:
Set the filter variables:

Update several kits in one request

updatePartKits applies the same update path as updatePartKit to each item in the list, so every item carries its own etag:
Set the variables:

Plan kit picks

The partKitPickList query returns the inventory to pull to fulfill one or more kits. pickStrategy takes a single value, FIFO. FIFO ranks candidate inventory site first, then receipt date. A kit’s site is the top-level ancestor of the kit’s own location (locationId). Stock at that site ranks ahead of stock anywhere else, whatever its age, and within each site the oldest receivedOrCreatedDate goes first. Off-site stock is drawn on only once stock at the kit’s site can’t cover the line. A kit with no locationId has no site, so its candidates rank by receipt date alone. Eligible inventory is available stock of any part that can fulfill the kit item, net of what is already kitted. Depending on your settings, stock at locations that aren’t marked pickable is excluded.

Generate a pick list

Pass partKitIds to plan a pick across a batch of kits. The response groups inventory into location stops in walk order, and splits each row’s quantity per kit:
Set the variables:
An abridged response for three kits that each need 8 of one part and 2 of another, both stocked in one bin:
quantityToPull is the total to pull from that inventory row across every kit in the request, which is the sum of its kitAllocations. It isn’t the row’s on-hand quantity. No inventory is allocated twice across the kits in one request. Pass partKitId instead to plan a pick for a single kit. That form returns the flat partInventories list, already in walk order, and locations is null. Each entry is the whole inventory record, so read the quantity to pull from the kit item rather than from quantity:
Both forms rank candidates with the same site-first model, so a single-kit pick and a one-kit batch choose the same inventory. Supply exactly one of partKitId or partKitIds. Supplying both, or neither, is a validation error. partKitIds accepts at most 2,000 kits per request by default, and an empty list returns an empty pick list. Add the optional locationId argument to restrict the pick to one location and its sub-locations. Rows are item-major: each row is one inventory record, and kitAllocations splits it across the kits that draw on it, rather than one row per kit. Stops are ordered by the pickSequence on each location, which you set through updateLocation. Locations that carry a sequence come first, in ascending order, followed by locations with no sequence in natural name order, so C-S-Bulk-2 precedes C-S-Bulk-10. Inventory with no location trails every real stop. stopNumber counts from 0.

Check whether a kit can be filled

fillabilityPercent on a part kit is the share of the kit’s remaining need, from 0 to 100, that a pick list can allocate right now. isFullyFillable is true when that share is the whole remaining need. Both are filterable and sortable:
Set the filter variables:
For a kit that the available stock covers only in part, the response reads:
Both fields score one kit on its own. Kits picked together in one request share the same inventory, so a batch can allocate less than the individual scores suggest, and a pick scoped to a locationId can allocate less still because the score counts stock in every location.

List the parts that can fulfill a kit item

acceptablePartIds on a part kit item returns every part that can fulfill it, each tagged with why it qualifies:
A kit item with one mBOM substitute returns:
partIdInformation takes one of four values: For more information about the setting behind the two interchangeable values, see Enable part interchangeability.