Skip to main content

Migrating to Inventory Item Instances

For questions, please reach out to support@quartzy.com.

Overview

Quartzy is introducing inventory item instances to support tracking quantity, lot number, expiration date, and location for each physical unit of an inventory item. In the Public API, instances appear as an instances array on inventory item payloads.

If your integration reads inventory item data or updates quantities via the Public API, you will need to update it when your lab is migrated. This includes integrations that sync quantities, lot numbers, expiration dates, or locations.

When this applies

Labs are migrated to instances gradually by Quartzy. All labs will be migrated over time. To help you migrate your integration, lab payloads include a temporary uses_instances field you can use to detect whether a lab has been migrated. It is available on GET /labs, GET /labs/{id}, and the nested lab object on inventory item responses (GET /inventory-items and GET /inventory-items/{id}). This field will be removed once all labs have been migrated to instances.

uses_instancesMeaning
falseNot yet migrated. All labs will be migrated over time; continue using the legacy item-level API until then.
trueMigrated permanently. Once you see true, you can assume the lab uses instances from that point forward.
Do not use the instances array to detect migration status

The presence of the instances array on an inventory item does not indicate whether a lab has been migrated. Always use lab.uses_instances instead.

Non-migrated labs always include an empty instances array and migrated labs will return an empty instances array for an item that has no instances yet.

Payload changes

Lab

Lab responses from GET /labs, GET /labs/{id}, and the nested lab object on inventory item responses include:

FieldTypeDescription
uses_instancesbooleanTemporary field. Whether the lab has been migrated to inventory item instances.

Inventory item

Inventory item responses include an instances array. Each instance has the following fields:

FieldTypeDescription
iduuidThe instance ID. Use this when updating an instance (e.g. quantity).
quantitystringThe quantity for this instance.
lot_numberstring, nullableLot number for this instance.
expiration_datedate, nullableExpiration date for this instance.
locationobject, nullableLocation for this instance. name is the leaf (most specific) location; pathNames is the full location chain from root to leaf.

Example:

{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Nitrile Gloves",
"quantity": "150",
"catalog_number": "GLV-100",
"lab": {
"id": "d4e5f6a7-b8c9-0123-def4-567890abcdef",
"name": "Main Lab",
"uses_instances": true,
"organization": {
"id": "e5f6a7b8-c9d0-1234-ef56-7890abcdef01",
"name": "Research Organization"
}
},
"instances": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"quantity": "100",
"lot_number": "LOT-2024-001",
"expiration_date": "2027-06-30",
"location": {
"name": "Shelf A",
"pathNames": ["Main Lab", "Supply Cabinet", "Shelf A"]
}
},
{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"quantity": "50",
"lot_number": "LOT-2025-003",
"expiration_date": "2028-01-15",
"location": {
"name": "Freezer B",
"pathNames": ["Main Lab", "Freezer B"]
}
}
]
}

The parent item's quantity field is the sum of all instance quantities.

Deprecated parent-level fields

On migrated labs, the following fields on the parent inventory item are deprecated. Read them from instances instead:

  • lot_number
  • expiration_date
  • location
  • sublocation

These fields will be empty on migrated labs even when the data exists on an instance. They will be removed entirely in a later update.

Location

Before migration, location data lived on the parent inventory item as two optional fields:

  • location — a Location object with a name
  • sublocation — a separate Location object with a name

This was a two-level placement model on the item.

After migration, each entry in instances has a single location object:

  • name — the leaf location (the most specific placement)
  • pathNames — an ordered array of location names from the root of the hierarchy through the leaf (inclusive)

When pathNames is present, name matches the last entry in the array.

If your integration previously stored parent location and sublocation separately, read instances[].location on migrated labs instead. Use name for the leaf location and pathNames when you need the full hierarchy — this replaces joining the two legacy fields.

Before migration (parent item):

{
"location": { "name": "Supply Cabinet" },
"sublocation": { "name": "Shelf A" }
}

After migration (instance):

{
"location": {
"name": "Shelf A",
"pathNames": ["Main Lab", "Supply Cabinet", "Shelf A"]
}
}

Updating quantities on migrated labs

When a lab's uses_instances is true, always update quantity on a specific instance. Read instance IDs from the item's instances array:

curl -X PUT \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"quantity": "25"}' \
https://api.quartzy.com/inventory-items/{itemId}/instances/{itemInstanceId}
  • {itemId} is the parent inventory item ID.
  • {itemInstanceId} is the id of the instance you want to update, taken from the instances array.

See Update inventory item instance quantity in the API reference.

The response returns the full parent inventory item, including the updated instances array.

Choosing the right endpoint

ConditionEndpoint to use
uses_instances is falseUpdate inventory item quantity
uses_instances is trueUpdate inventory item instance quantity

Error responses

The instance endpoint may return the following errors:

StatusWhen
400The quantity value is not numeric, or the request failed validation (for example, a negative quantity).
404The instance ID does not exist, or the instance does not belong to the specified item.

Migration checklist

  1. Detect migration — check uses_instances on lab payloads until it is true for each lab; once true, assume the lab uses instances from that point forward.
  2. Parse instances on GET /inventory-items and GET /inventory-items/{id} responses when the lab is migrated.
  3. Store instance IDs alongside parent item IDs in your system.
  4. Route quantity updates to PUT /inventory-items/{itemId}/instances/{itemInstanceId} on migrated labs.
  5. Read lot number, expiration date, and location (name and pathNames) from instances rather than the parent item on migrated labs.