Inventory Groups

Create, read, update, bulk delete, stock, adjust, and subscribe to inventory groups through the Store API.

Inventory Groups require inventory scopes. Reads use read_inventory; writes use write_inventory. Creating an inventory group requires name and sku; slug is optional and is generated from the name when omitted. Every location visible to the token is immediately part of the group's inventory view and reads as zero until inventory or a threshold is first written; there is no separate location-assignment step. Set, adjust, threshold, and bulk-mutation writes create missing stock levels atomically. Group responses include aggregate stock, linked product counts, and overall low-stock state. Successful stock changes update the movement ledger and fire inventory_levels/update atomically, while a failed write changes nothing. Low-stock alerts fire inventory/low_stock for a location or for the whole group. Subscribing to these events and to inventory_groups/* requires read_inventory. App tokens see merchant-managed locations and their own app-managed locations, never another app's locations. Stock at an app-managed location is writable only by that location's owning active app installation; merchants see those rows for operational context but cannot change them. Single and bulk group deletion never discard stock or detach references: non-zero quantity, reservations, linked products, linked variants, or pending/in-transit transfers block deletion, bulk delete is all-or-nothing, and movement history is preserved.

Endpoints#

Inventory Group limits

GET read_inventory

Fetch inventory group limits and field constraints.

Returns the field lengths, quantity caps, stock thresholds, page-size caps, and sort columns enforced by the inventory service.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

List inventory groups

GET read_inventory

List store inventory groups.

Returns paginated inventory groups with aggregate stock, linked product counts, and low-stock state. quantity is physical on hand. reserved is all held stock, the sum of checkout_held (units shoppers are paying for right now; the hold is released if payment doesn't complete in time), order_committed (units promised to placed orders that haven't shipped yet) and other_held (units set aside for stock transfers between locations). available = quantity - reserved. total counts matching results; store_total counts all inventory groups in the store. Reset page to 1 when filters or sorting change.

Query parameters

Name Type Description
page integer

Page number.

Example: 1
limit integer

Page size.

Example: 50
search string

Search inventory groups by name, slug, or SKU.

Example: BLANK-TEE-POOL
low_stock_only boolean

When true, return only low-stock groups.

Example: false
location_id uuid

Filter to groups with stock at this location.

Example: af720cef-7f1b-40f4-a5f8-8a55ea5b0d84
sort_by string

Sort field from the Inventory Group list contract.

Allowed values
namequantitycreated_at
Example: name
sort_direction string

Sort direction from the Inventory Group list contract.

Allowed values
ascdesc
Example: asc

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page must be at least 1.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit is outside the inventory group contract.

  • 400 VALIDATION_LIST_INVALID_SORT_BY

    Sort field is not allowed for this endpoint.

  • 400 VALIDATION_LIST_INVALID_SORT_DIRECTION

    Sort direction must be asc or desc.

  • 400 VALIDATION_SEARCH_TOO_LONG

    Search exceeds the inventory group search limit.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

Get inventory group

GET read_inventory

Fetch one inventory group by id.

Returns the inventory group, its aggregate stock, linked products and variants count, and per-location stock rows. quantity is physical on hand. reserved is all held stock, the sum of checkout_held (units shoppers are paying for right now; the hold is released if payment doesn't complete in time), order_committed (units promised to placed orders that haven't shipped yet) and other_held (units set aside for stock transfers between locations). available = quantity - reserved.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

List linked products

GET read_inventory + read_products

List simple products linked directly to one inventory group.

Returns simple products whose inventory source is this group. Variable product parents are not repeated here; their linked variants are returned by the linked variants endpoint. Link or unlink a product through the Product create/update inventory fields, not by mutating this read-only relationship list.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Query parameters

Name Type Description
page integer

Page number.

Example: 1
limit integer

Page size.

Example: 50
search string

Search linked products by product title or product SKU.

Example: BLANK-TEE
sort_by string

Sort by title, status, sku, or created_at.

Allowed values
namequantitycreated_at
Example: title
sort_direction string

Sort direction: asc or desc.

Allowed values
ascdesc
Example: asc

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page must be at least 1.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit is outside the inventory group contract.

  • 400 VALIDATION_LIST_INVALID_SORT_BY

    Sort field is not allowed for this endpoint.

  • 400 VALIDATION_LIST_INVALID_SORT_DIRECTION

    Sort direction must be asc or desc.

  • 400 VALIDATION_SEARCH_TOO_LONG

    Search exceeds the inventory group search limit.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

List linked variants

GET read_inventory + read_products

List product variants linked directly to one inventory group.

Returns variants whose inventory source is this group together with their parent product identity. Link or unlink a variant through the Product create/update variant inventory fields, not by mutating this read-only relationship list.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Query parameters

Name Type Description
page integer

Page number.

Example: 1
limit integer

Page size.

Example: 50
search string

Search linked variants by product title, variant title, or variant SKU.

Example: BLANK-TEE-M
sort_by string

Sort by product_title, variant_title, sku, or created_at.

Allowed values
namequantitycreated_at
Example: product_title
sort_direction string

Sort direction: asc or desc.

Allowed values
ascdesc
Example: asc

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page must be at least 1.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit is outside the inventory group contract.

  • 400 VALIDATION_LIST_INVALID_SORT_BY

    Sort field is not allowed for this endpoint.

  • 400 VALIDATION_LIST_INVALID_SORT_DIRECTION

    Sort direction must be asc or desc.

  • 400 VALIDATION_SEARCH_TOO_LONG

    Search exceeds the inventory group search limit.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

Create inventory group

POST write_inventory

Create inventory group.

Creates a stock pool. name and sku are required. slug is optional on create and is generated from the name when omitted. SKU uniqueness is checked across products, variants, and inventory groups.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
name required string

Inventory Group name.

Example: Print Blanks
sku required string

Unique SKU for the stock pool.

Example: BLANK-TEE-POOL
slug string

Optional slug. Omit to generate from name.

Example: print-blanks
description string

Optional internal description.

Example: Shared stock pool for blank T-shirts.
overall_low_stock_threshold integer

Optional threshold for total available stock across all locations. Null disables the overall alert.

Example: 40

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request JSON could not be parsed.

  • 400 INVENTORY_GROUP_NAME_REQUIRED

    Name is empty after normalization.

  • 400 INVENTORY_GROUP_NAME_TOO_LONG

    Name exceeds the Inventory Group contract max length.

  • 400 INVENTORY_GROUP_NAME_INVALID_CHARS

    Name contains invalid characters.

  • 400 INVENTORY_GROUP_SKU_REQUIRED

    SKU is empty after normalization.

  • 400 INVENTORY_GROUP_SKU_TOO_LONG

    SKU exceeds the Inventory Group contract max length.

  • 400 INVENTORY_GROUP_SKU_INVALID_CHARS

    SKU contains invalid characters.

  • 400 INVENTORY_GROUP_SKU_INVALID_FORMAT

    SKU contains characters outside the shared SKU contract.

  • 400 INVENTORY_GROUP_SLUG_REQUIRED

    Slug is empty on update. Blank slug auto-generation is only available on create.

  • 400 INVENTORY_GROUP_SLUG_INVALID_FORMAT

    Slug is not valid for inventory group URLs.

  • 400 INVENTORY_GROUP_SLUG_TOO_LONG

    Slug exceeds the Inventory Group contract max length.

  • 400 INVENTORY_GROUP_SLUG_GENERATION_FAILED

    A slug could not be generated from the name.

  • 409 INVENTORY_GROUP_UNIQUE_SLUG_GENERATION_FAILED

    A unique slug could not be generated for this store.

  • 400 INVENTORY_GROUP_DESCRIPTION_TOO_LONG

    Description exceeds the Inventory Group contract max length.

  • 400 INVENTORY_GROUP_DESCRIPTION_INVALID_CHARS

    Description contains invalid characters.

  • 400 INVENTORY_GROUP_THRESHOLD_NEGATIVE

    Low-stock threshold cannot be negative.

  • 400 INVENTORY_GROUP_THRESHOLD_TOO_LARGE

    Low-stock threshold exceeds the contract maximum.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 409 INVENTORY_GROUP_DUPLICATE

    Another inventory group in this store already uses this slug. SKU conflicts return the SKU_IN_USE codes.

  • 409 SKU_IN_USE_BY_PRODUCT

    SKU is already used by a product.

  • 409 SKU_IN_USE_BY_VARIANT

    SKU is already used by a product variant.

  • 409 SKU_IN_USE_BY_GROUP

    SKU is already used by another inventory group.

  • 409 SKU_IN_USE

    SKU is already used by another SKU-backed resource.

  • 409 INVENTORY_GROUP_LIMIT_REACHED

    Store Inventory Group cap has been reached.

Update inventory group

PUT write_inventory

Update inventory group.

Updates provided fields. Omitted fields stay unchanged. Omit slug to keep the current slug; unlike create, update does not generate a slug. Send null to clear overall_low_stock_threshold; send an empty description to clear it.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
name string

Inventory Group name.

Example: Print Blanks
sku string

Unique SKU for the stock pool.

Example: BLANK-TEE-POOL
slug string

Optional slug. Omit to keep the current slug; an empty string is invalid.

Example: print-blanks
description string

Optional internal description.

Example: Shared stock pool for blank T-shirts.
overall_low_stock_threshold integer

Optional threshold for total available stock across all locations. Null disables the overall alert.

Example: 40

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request JSON could not be parsed.

  • 400 INVENTORY_GROUP_NAME_REQUIRED

    Name is empty after normalization.

  • 400 INVENTORY_GROUP_NAME_TOO_LONG

    Name exceeds the Inventory Group contract max length.

  • 400 INVENTORY_GROUP_NAME_INVALID_CHARS

    Name contains invalid characters.

  • 400 INVENTORY_GROUP_SKU_REQUIRED

    SKU is empty after normalization.

  • 400 INVENTORY_GROUP_SKU_TOO_LONG

    SKU exceeds the Inventory Group contract max length.

  • 400 INVENTORY_GROUP_SKU_INVALID_CHARS

    SKU contains invalid characters.

  • 400 INVENTORY_GROUP_SKU_INVALID_FORMAT

    SKU contains characters outside the shared SKU contract.

  • 400 INVENTORY_GROUP_SLUG_REQUIRED

    Slug is empty on update. Blank slug auto-generation is only available on create.

  • 400 INVENTORY_GROUP_SLUG_INVALID_FORMAT

    Slug is not valid for inventory group URLs.

  • 400 INVENTORY_GROUP_SLUG_TOO_LONG

    Slug exceeds the Inventory Group contract max length.

  • 400 INVENTORY_GROUP_SLUG_GENERATION_FAILED

    A slug could not be generated from the name.

  • 409 INVENTORY_GROUP_UNIQUE_SLUG_GENERATION_FAILED

    A unique slug could not be generated for this store.

  • 400 INVENTORY_GROUP_DESCRIPTION_TOO_LONG

    Description exceeds the Inventory Group contract max length.

  • 400 INVENTORY_GROUP_DESCRIPTION_INVALID_CHARS

    Description contains invalid characters.

  • 400 INVENTORY_GROUP_THRESHOLD_NEGATIVE

    Low-stock threshold cannot be negative.

  • 400 INVENTORY_GROUP_THRESHOLD_TOO_LARGE

    Low-stock threshold exceeds the contract maximum.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 409 INVENTORY_GROUP_DUPLICATE

    Another inventory group in this store already uses this slug. SKU conflicts return the SKU_IN_USE codes.

  • 409 SKU_IN_USE_BY_PRODUCT

    SKU is already used by a product.

  • 409 SKU_IN_USE_BY_VARIANT

    SKU is already used by a product variant.

  • 409 SKU_IN_USE_BY_GROUP

    SKU is already used by another inventory group.

  • 409 SKU_IN_USE

    SKU is already used by another SKU-backed resource.

  • 409 INVENTORY_GROUP_LIMIT_REACHED

    Store Inventory Group cap has been reached.

Delete inventory group

DELETE write_inventory

Delete inventory group.

Deletes the group only when every location has zero quantity and zero reservations and no products, variants, or active transfers still reference it. Stock and reservations are never discarded implicitly; adjust each location to zero first. Movement history is preserved after deletion.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 409 INVENTORY_GROUP_DELETE_HAS_PRODUCTS

    Inventory Group still has linked products.

  • 409 INVENTORY_GROUP_DELETE_HAS_INVENTORY

    Inventory Group still has non-zero quantity or reservations. Adjust every location to zero first.

  • 409 INVENTORY_GROUP_DELETE_HAS_VARIANTS

    Inventory Group still has linked variants.

  • 409 INVENTORY_GROUP_DELETE_HAS_TRANSFERS

    Inventory Group still has pending or in-transit transfers.

Bulk delete inventory groups

POST write_inventory

Delete multiple inventory groups atomically.

Validates and locks every requested group before deleting any. If an id is missing, duplicated, any group has non-zero quantity or reservations, or any group still has linked products, linked variants, or a pending/in-transit transfer, the entire request fails and nothing is detached or deleted. Adjust every location to zero first. Movement history is preserved. Successful deletion releases each group SKU and queues its audit and delete-webhook records in the same transaction.

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
group_ids required array<string>

Store-scoped inventory group ids to delete. Duplicates are rejected.

Example: ["5ff7d4ea-3250-4a4d-9d26-07f64d917d31"]

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request JSON could not be parsed or contains unknown fields.

  • 400 INVENTORY_GROUP_BULK_NO_IDS

    No inventory group ids were provided.

  • 400 INVENTORY_GROUP_BULK_DELETE_TOO_MANY

    Batch exceeds the inventory group bulk-delete cap.

  • 400 INVENTORY_GROUP_BULK_DUPLICATE_ID

    The request contains a duplicate inventory group id.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 409 INVENTORY_GROUP_DELETE_HAS_PRODUCTS

    Inventory Group still has linked products.

  • 409 INVENTORY_GROUP_DELETE_HAS_INVENTORY

    Inventory Group still has non-zero quantity or reservations. Adjust every location to zero first.

  • 409 INVENTORY_GROUP_DELETE_HAS_VARIANTS

    Inventory Group still has linked variants.

  • 409 INVENTORY_GROUP_DELETE_HAS_TRANSFERS

    Inventory Group still has pending or in-transit transfers.

Set inventory group quantity

POST write_inventory

Set absolute stock at one location.

Writes an absolute quantity at a visible location. No location-assignment step is required: a location without stored group inventory reads as zero and this request creates its stock level atomically. App-managed locations are writable only by their owning active installation. The new quantity cannot be below reserved stock. Send expected_quantity to make the write a compare-and-set: when the current on-hand quantity differs the request is refused with 409 STOCK_LEVEL_EXPECTED_QUANTITY_MISMATCH and nothing changes. Successful changes update the stock ledger and aggregate stock together and fire inventory_levels/update — a failure leaves nothing partially written. Send a stable Idempotency-Key when retrying.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Idempotency-Key string

Optional on the first attempt and required for a safe retry. Scoped to the calling app or merchant actor, at most 200 characters. An identical replay within 7 days returns the original result without a second stock write, audit entry or webhook; reuse with different input returns 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT.

Example: group-count-2026-09-27-main

Body parameters

Name Type Description
location_id required uuid

Location id.

Example: af720cef-7f1b-40f4-a5f8-8a55ea5b0d84
quantity required integer

Absolute quantity at the location.

Example: 240
expected_quantity integer

Optional compare-and-set guard: the on-hand quantity you counted against. A mismatch returns 409 and changes nothing.

Example: 236
reason required string

Inventory movement reason.

Example: recount
notes string

Optional movement note.

Example: Initial warehouse count

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request JSON could not be parsed.

  • 400 INVENTORY_GROUP_LOCATION_REQUIRED

    Location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_REQUIRED

    At least one location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_NOT_FOUND

    One or more locations do not exist in this store.

  • 400 INVENTORY_GROUP_LOCATION_DUPLICATE

    The same location appears more than once.

  • 400 INVENTORY_GROUP_QUANTITY_NEGATIVE

    Quantity cannot be negative.

  • 400 INVENTORY_GROUP_QUANTITY_TOO_LARGE

    Quantity exceeds the contract maximum.

  • 400 INVENTORY_GROUP_QUANTITY_BELOW_RESERVED

    Quantity cannot be set below reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_NEGATIVE

    Adjustment would make quantity negative.

  • 400 INVENTORY_GROUP_ADJUST_BELOW_RESERVED

    Adjustment would make quantity lower than reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_TOO_LARGE

    Adjustment would exceed the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_NEGATIVE

    Low-stock threshold cannot be negative.

  • 400 INVENTORY_GROUP_THRESHOLD_TOO_LARGE

    Low-stock threshold exceeds the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_REQUIRED

    Set-threshold was sent without low_stock_threshold. Send null to clear it.

  • 400 INVENTORY_GROUP_REASON_REQUIRED

    Movement reason is required.

  • 400 INVENTORY_GROUP_REASON_INVALID

    Movement reason is not allowed.

  • 400 INVENTORY_GROUP_NOTES_TOO_LONG

    Movement notes exceed the contract max length.

  • 400 INVENTORY_GROUP_NOTES_INVALID_CHARS

    Movement notes contain invalid characters.

  • 403 LOCATION_APP_MANAGED_NO_EDIT

    The location belongs to another app or its owning installation is inactive.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 404 INVENTORY_GROUP_STOCK_NOT_FOUND

    No stock row exists for the requested location.

  • 409 INVENTORY_GROUP_STOCK_EXISTS

    Stock already exists at one of the selected locations.

  • 400 INVENTORY_GROUP_STOCK_MAX_LOCATIONS

    The bulk stock batch exceeds the contract maximum.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_INVALID

    An expected quantity is negative.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_SET_ONLY

    Expected quantities were sent with an action other than set_quantity.

  • 409 STOCK_LEVEL_EXPECTED_QUANTITY_MISMATCH

    The current on-hand quantity differs from the expected quantity; nothing changed.

  • 400 STOCK_WRITE_IDEMPOTENCY_KEY_TOO_LONG

    Idempotency-Key exceeds 200 characters.

  • 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT

    The idempotency key was already used for a different stock write.

  • 409 LOCATION_ARCHIVED_NO_EDIT

    The write would change stock at an archived location.

Adjust inventory group quantity

POST write_inventory

Add or subtract stock at one location.

Applies a signed adjustment at a visible location. No location-assignment step is required: a positive adjustment creates a missing zero stock level atomically; a negative adjustment against zero is rejected. App-managed locations are writable only by their owning active installation. Adjustments cannot make quantity negative or below reserved stock. Successful changes update the stock ledger and aggregate stock together and fire inventory_levels/update — a failure leaves nothing partially written. Send a stable Idempotency-Key when retrying: a replay returns the original result without adjusting twice.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Idempotency-Key string

Optional on the first attempt and required for a safe retry. Scoped to the calling app or merchant actor, at most 200 characters. An identical replay within 7 days returns the original result without a second stock write, audit entry or webhook; reuse with different input returns 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT.

Example: group-damage-2026-09-27-01

Body parameters

Name Type Description
location_id required uuid

Location id.

Example: af720cef-7f1b-40f4-a5f8-8a55ea5b0d84
adjustment required integer

Signed quantity delta.

Example: -5
reason required string

Inventory movement reason.

Example: damaged
notes string

Optional movement note.

Example: Five units damaged during cycle count

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request JSON could not be parsed.

  • 400 INVENTORY_GROUP_LOCATION_REQUIRED

    Location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_REQUIRED

    At least one location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_NOT_FOUND

    One or more locations do not exist in this store.

  • 400 INVENTORY_GROUP_LOCATION_DUPLICATE

    The same location appears more than once.

  • 400 INVENTORY_GROUP_QUANTITY_NEGATIVE

    Quantity cannot be negative.

  • 400 INVENTORY_GROUP_QUANTITY_TOO_LARGE

    Quantity exceeds the contract maximum.

  • 400 INVENTORY_GROUP_QUANTITY_BELOW_RESERVED

    Quantity cannot be set below reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_NEGATIVE

    Adjustment would make quantity negative.

  • 400 INVENTORY_GROUP_ADJUST_BELOW_RESERVED

    Adjustment would make quantity lower than reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_TOO_LARGE

    Adjustment would exceed the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_NEGATIVE

    Low-stock threshold cannot be negative.

  • 400 INVENTORY_GROUP_THRESHOLD_TOO_LARGE

    Low-stock threshold exceeds the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_REQUIRED

    Set-threshold was sent without low_stock_threshold. Send null to clear it.

  • 400 INVENTORY_GROUP_REASON_REQUIRED

    Movement reason is required.

  • 400 INVENTORY_GROUP_REASON_INVALID

    Movement reason is not allowed.

  • 400 INVENTORY_GROUP_NOTES_TOO_LONG

    Movement notes exceed the contract max length.

  • 400 INVENTORY_GROUP_NOTES_INVALID_CHARS

    Movement notes contain invalid characters.

  • 403 LOCATION_APP_MANAGED_NO_EDIT

    The location belongs to another app or its owning installation is inactive.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 404 INVENTORY_GROUP_STOCK_NOT_FOUND

    No stock row exists for the requested location.

  • 409 INVENTORY_GROUP_STOCK_EXISTS

    Stock already exists at one of the selected locations.

  • 400 INVENTORY_GROUP_STOCK_MAX_LOCATIONS

    The bulk stock batch exceeds the contract maximum.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_INVALID

    An expected quantity is negative.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_SET_ONLY

    Expected quantities were sent with an action other than set_quantity.

  • 409 STOCK_LEVEL_EXPECTED_QUANTITY_MISMATCH

    The current on-hand quantity differs from the expected quantity; nothing changed.

  • 400 STOCK_WRITE_IDEMPOTENCY_KEY_TOO_LONG

    Idempotency-Key exceeds 200 characters.

  • 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT

    The idempotency key was already used for a different stock write.

  • 409 LOCATION_ARCHIVED_NO_EDIT

    The write would change stock at an archived location.

Set inventory group low-stock threshold

POST write_inventory

Set or clear the per-location low-stock threshold.

Sets a low-stock threshold at a visible location. No location-assignment step is required; setting a threshold creates the zero stock level atomically when needed. App-managed locations are writable only by their owning active installation. low_stock_threshold is required: send a number to set it or null to clear it; omitting it is refused with INVENTORY_GROUP_THRESHOLD_REQUIRED. Threshold changes fire inventory_levels/update and may trigger low-stock notifications and webhooks.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Body parameters

Name Type Description
location_id required uuid

Location id.

Example: af720cef-7f1b-40f4-a5f8-8a55ea5b0d84
low_stock_threshold required integer

Per-location threshold. Required: send a number to set it or null to clear it; 0 is valid.

Example: 15

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request JSON could not be parsed.

  • 400 INVENTORY_GROUP_LOCATION_REQUIRED

    Location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_REQUIRED

    At least one location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_NOT_FOUND

    One or more locations do not exist in this store.

  • 400 INVENTORY_GROUP_LOCATION_DUPLICATE

    The same location appears more than once.

  • 400 INVENTORY_GROUP_QUANTITY_NEGATIVE

    Quantity cannot be negative.

  • 400 INVENTORY_GROUP_QUANTITY_TOO_LARGE

    Quantity exceeds the contract maximum.

  • 400 INVENTORY_GROUP_QUANTITY_BELOW_RESERVED

    Quantity cannot be set below reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_NEGATIVE

    Adjustment would make quantity negative.

  • 400 INVENTORY_GROUP_ADJUST_BELOW_RESERVED

    Adjustment would make quantity lower than reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_TOO_LARGE

    Adjustment would exceed the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_NEGATIVE

    Low-stock threshold cannot be negative.

  • 400 INVENTORY_GROUP_THRESHOLD_TOO_LARGE

    Low-stock threshold exceeds the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_REQUIRED

    Set-threshold was sent without low_stock_threshold. Send null to clear it.

  • 400 INVENTORY_GROUP_REASON_REQUIRED

    Movement reason is required.

  • 400 INVENTORY_GROUP_REASON_INVALID

    Movement reason is not allowed.

  • 400 INVENTORY_GROUP_NOTES_TOO_LONG

    Movement notes exceed the contract max length.

  • 400 INVENTORY_GROUP_NOTES_INVALID_CHARS

    Movement notes contain invalid characters.

  • 403 LOCATION_APP_MANAGED_NO_EDIT

    The location belongs to another app or its owning installation is inactive.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 404 INVENTORY_GROUP_STOCK_NOT_FOUND

    No stock row exists for the requested location.

  • 409 INVENTORY_GROUP_STOCK_EXISTS

    Stock already exists at one of the selected locations.

  • 400 INVENTORY_GROUP_STOCK_MAX_LOCATIONS

    The bulk stock batch exceeds the contract maximum.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_INVALID

    An expected quantity is negative.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_SET_ONLY

    Expected quantities were sent with an action other than set_quantity.

  • 409 STOCK_LEVEL_EXPECTED_QUANTITY_MISMATCH

    The current on-hand quantity differs from the expected quantity; nothing changed.

  • 400 STOCK_WRITE_IDEMPOTENCY_KEY_TOO_LONG

    Idempotency-Key exceeds 200 characters.

  • 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT

    The idempotency key was already used for a different stock write.

  • 409 LOCATION_ARCHIVED_NO_EDIT

    The write would change stock at an archived location.

List inventory group movements

GET read_inventory

List stock movement history for one inventory group.

Returns the movement ledger used to reconcile inventory_levels/update webhook delivery. Rows are retained for the service retention window returned by the endpoint. Order-backed reference_type and reference_id are included only when the token also has read_orders.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Query parameters

Name Type Description
page integer

Page number.

Example: 1
limit integer

Page size.

Example: 50
search string

Search movement notes or location names.

Example: cycle
location_id uuid

Filter movements to one location.

Example: af720cef-7f1b-40f4-a5f8-8a55ea5b0d84
reason string

Filter by movement reason.

Example: recount
from_date string

Inclusive start date in the store timezone, YYYY-MM-DD. Cannot be in the future.

Example: 2026-07-01
to_date string

Inclusive end date in the store timezone, YYYY-MM-DD. Cannot be in the future or before from_date.

Example: 2026-07-31
sort_by string

Sort by created_at, quantity_change, or location_name.

Allowed values
namequantitycreated_at
Example: created_at
sort_direction string

Sort direction.

Allowed values
ascdesc
Example: desc

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page must be at least 1.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit is outside the inventory group contract.

  • 400 VALIDATION_LIST_INVALID_SORT_BY

    Sort field is not allowed for this endpoint.

  • 400 VALIDATION_LIST_INVALID_SORT_DIRECTION

    Sort direction must be asc or desc.

  • 400 VALIDATION_SEARCH_TOO_LONG

    Search exceeds the inventory group search limit.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 400 INVENTORY_GROUP_REASON_INVALID

    Movement reason is not allowed.

  • 400 INVENTORY_FROM_DATE_INVALID

    From date must use YYYY-MM-DD and cannot be in the future.

  • 400 INVENTORY_TO_DATE_INVALID

    To date must use YYYY-MM-DD and cannot be in the future.

  • 400 INVENTORY_DATE_RANGE_INVALID

    From date is after to date.

List current inventory group commitments

GET read_inventory

List open order-inventory commitments for one inventory group.

Returns open, successfully applied reservation slices at locations visible to the token, newest first. Each row is stock held for one order line at one location: state provisional while the shopper is paying (it counts in checkout_held until expires_at) or committed once the order is placed and paid or confirmed (it counts in order_committed). state is the authoritative applied state, not a pending desired state. Released and fulfilled stock is not listed; read commitment activity for that history. While an order's stock change is still being applied its rows are left out, so the rows add up to a location's checkout_held and order_committed once it applies. source_type (product, variant or group), source_id and sku name the item. Pages are keyed: pass the response's next_cursor as cursor to read the next page with the same filters; an empty next_cursor means there are no more rows. Order ids, item ids, and order numbers are included only when the token also has read_orders; internal transition status, errors, and operation ids are never exposed through the Store API. App tokens see merchant-managed locations and their own app-managed locations, never another app's locations.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Query parameters

Name Type Description
cursor string

Opaque next_cursor of the previous page. Omit it for the first page.

Example: eyJ0IjoiMjAyNi0wNy0wNlQxMDoyNTowMFoifQ
limit integer

Page size, 1 to 100. Defaults to 50.

Example: 50
location_id uuid

Filter commitments to one visible location.

Example: af720cef-7f1b-40f4-a5f8-8a55ea5b0d84

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit must be between 1 and 100.

  • 400 INVALID_INPUT

    A filter is invalid: the error names cursor or location_id.

List inventory group commitment activity

GET read_inventory

List applied order-inventory commitment activity for one inventory group.

Returns the append-only lifecycle ledger for successfully applied provisional holds, commitments, releases, reacquisitions, fulfillment consumption, and cancelled fulfillments, newest first. Filter dates resolve in the store timezone. event_type is provisional_held (a checkout hold started), committed (units committed to a placed order), released (held units became available again), reacquired (released units were held again), fulfilled (units left stock with a fulfillment) or fulfillment_reversed (a cancelled fulfillment put its units back). reason says why: order_created (an order was placed or an edit added units), payment_captured (the payment completed; with reacquired, a late payment held the same units again after its hold had been released), payment_retry (the shopper retried a payment), payment_failed or provider_init_failed (the payment failed or could not be started), checkout_hold_expired (the checkout hold duration ran out), order_released (the order was cancelled or removed), order_edited (an order edit or refund removed units), order_edit_abandoned (an unsaved order edit was discarded), order_create_failed (an order that could not be completed returned units sold on commit), order_fulfilled (units shipped), sold_without_shipping (items that don't need shipping left stock when the order was committed) or fulfillment_cancelled (a fulfillment was cancelled). reserved_after, checkout_held_after and order_committed_after are the location's numbers right after the event. source_type, source_id and sku name the item. Pages are keyed: pass the response's next_cursor as cursor to read the next page with the same filters; an empty next_cursor means there are no more rows. This is separate from physical stock movement history. Order ids, item ids, and order numbers are included only when the token also has read_orders; internal pending-operation and error details are never exposed through the Store API. App tokens see merchant-managed locations and their own app-managed locations, never another app's locations.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Query parameters

Name Type Description
cursor string

Opaque next_cursor of the previous page. Omit it for the first page.

Example: eyJ0IjoiMjAyNi0wNy0wNlQxMDoyNTowMFoifQ
limit integer

Page size, 1 to 100. Defaults to 50.

Example: 50
location_id uuid

Filter activity to one visible location.

Example: af720cef-7f1b-40f4-a5f8-8a55ea5b0d84
event_type string

Filter by provisional_held, committed, released, reacquired, fulfilled, or fulfillment_reversed.

Example: committed
from_date string

Inclusive start date, YYYY-MM-DD in the store timezone.

Example: 2026-07-01
to_date string

Inclusive end date, YYYY-MM-DD in the store timezone.

Example: 2026-07-31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit must be between 1 and 100.

  • 400 INVALID_INPUT

    A filter is invalid: the error names cursor, location_id, event_type, from_date or to_date.

List inventory group stock

GET read_inventory

List inventory at each visible location for one inventory group.

Returns every active location visible to the token, plus inactive locations that retain stored stock. Locations without a persisted level are returned with zero quantity and reservations; there is no separate assignment step. quantity is physical on hand. reserved is all held stock, the sum of checkout_held (units shoppers are paying for right now; the hold is released if payment doesn't complete in time), order_committed (units promised to placed orders that haven't shipped yet) and other_held (units set aside for stock transfers between locations). available = quantity - reserved. App tokens see merchant-managed locations and their own app-managed locations, never another app's locations. Ownership fields let clients render non-writable app-managed rows correctly.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Query parameters

Name Type Description
page integer

Page number.

Example: 1
limit integer

Page size.

Example: 50
search string

Search stock rows by location name.

Example: Main Warehouse
sort_by string

Sort by location_name, quantity, or available.

Allowed values
namequantitycreated_at
Example: location_name
sort_direction string

Sort direction.

Allowed values
ascdesc
Example: asc

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 400 VALIDATION_LIST_INVALID_PAGE

    Page must be at least 1.

  • 400 VALIDATION_LIST_INVALID_LIMIT

    Limit is outside the inventory group contract.

  • 400 VALIDATION_LIST_INVALID_SORT_BY

    Sort field is not allowed for this endpoint.

  • 400 VALIDATION_LIST_INVALID_SORT_DIRECTION

    Sort direction must be asc or desc.

  • 400 VALIDATION_SEARCH_TOO_LONG

    Search exceeds the inventory group search limit.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

Initialize inventory group inventory at locations

POST write_inventory

Create initial stored stock levels at multiple locations.

Initializes locations that do not yet have persisted group stock. This endpoint is an optional batch-create convenience, not an assignment prerequisite; GET .../stock already returns visible missing levels as zero, and normal set/adjust/threshold writes create them automatically. A location with persisted state cannot be initialized again. App tokens may target merchant-managed locations and locations owned by their own active installation, never another app's location. The batch validates every target and commits atomically. Send a stable Idempotency-Key when retrying.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Idempotency-Key string

Optional on the first attempt and required for a safe retry. Scoped to the calling app or merchant actor, at most 200 characters. An identical replay within 7 days returns the original result without a second stock write, audit entry or webhook; reuse with different input returns 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT.

Example: group-init-2026-09-27-01

Body parameters

Name Type Description
stock required array<object>

Stock rows to create. Each row needs location_id and quantity; low_stock_threshold is optional.

Example: [{"location_id":"af720cef-7f1b-40f4-a5f8-8a55ea5b0d84","quantity":240,"low_stock_threshold":15}]

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request JSON could not be parsed.

  • 400 INVENTORY_GROUP_LOCATION_REQUIRED

    Location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_REQUIRED

    At least one location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_NOT_FOUND

    One or more locations do not exist in this store.

  • 400 INVENTORY_GROUP_LOCATION_DUPLICATE

    The same location appears more than once.

  • 400 INVENTORY_GROUP_QUANTITY_NEGATIVE

    Quantity cannot be negative.

  • 400 INVENTORY_GROUP_QUANTITY_TOO_LARGE

    Quantity exceeds the contract maximum.

  • 400 INVENTORY_GROUP_QUANTITY_BELOW_RESERVED

    Quantity cannot be set below reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_NEGATIVE

    Adjustment would make quantity negative.

  • 400 INVENTORY_GROUP_ADJUST_BELOW_RESERVED

    Adjustment would make quantity lower than reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_TOO_LARGE

    Adjustment would exceed the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_NEGATIVE

    Low-stock threshold cannot be negative.

  • 400 INVENTORY_GROUP_THRESHOLD_TOO_LARGE

    Low-stock threshold exceeds the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_REQUIRED

    Set-threshold was sent without low_stock_threshold. Send null to clear it.

  • 400 INVENTORY_GROUP_REASON_REQUIRED

    Movement reason is required.

  • 400 INVENTORY_GROUP_REASON_INVALID

    Movement reason is not allowed.

  • 400 INVENTORY_GROUP_NOTES_TOO_LONG

    Movement notes exceed the contract max length.

  • 400 INVENTORY_GROUP_NOTES_INVALID_CHARS

    Movement notes contain invalid characters.

  • 403 LOCATION_APP_MANAGED_NO_EDIT

    The location belongs to another app or its owning installation is inactive.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 404 INVENTORY_GROUP_STOCK_NOT_FOUND

    No stock row exists for the requested location.

  • 409 INVENTORY_GROUP_STOCK_EXISTS

    Stock already exists at one of the selected locations.

  • 400 INVENTORY_GROUP_STOCK_MAX_LOCATIONS

    The bulk stock batch exceeds the contract maximum.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_INVALID

    An expected quantity is negative.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_SET_ONLY

    Expected quantities were sent with an action other than set_quantity.

  • 409 STOCK_LEVEL_EXPECTED_QUANTITY_MISMATCH

    The current on-hand quantity differs from the expected quantity; nothing changed.

  • 400 STOCK_WRITE_IDEMPOTENCY_KEY_TOO_LONG

    Idempotency-Key exceeds 200 characters.

  • 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT

    The idempotency key was already used for a different stock write.

  • 409 LOCATION_ARCHIVED_NO_EDIT

    The write would change stock at an archived location.

Bulk manage inventory group inventory

POST write_inventory

Apply one inventory action to selected locations.

Atomically applies set_quantity, adjust_quantity, or set_threshold to every selected location and creates missing zero levels on first write. Every location is validated with the same ownership rules as a single write; a duplicate, invisible location, another app's managed location, inactive owning installation, limit violation, or below-reserved result aborts the entire request. Quantity actions require a reason. With set_quantity, expected_quantities maps location ids to the on-hand quantity you counted against; any mismatch refuses the whole request with 409 STOCK_LEVEL_EXPECTED_QUANTITY_MISMATCH. Use clear_threshold: true to clear thresholds. Send a stable Idempotency-Key when retrying.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Idempotency-Key string

Optional on the first attempt and required for a safe retry. Scoped to the calling app or merchant actor, at most 200 characters. An identical replay within 7 days returns the original result without a second stock write, audit entry or webhook; reuse with different input returns 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT.

Example: group-bulk-count-2026-09-27

Body parameters

Name Type Description
location_ids required array<string>

Selected location ids. Duplicates are rejected.

Example: ["af720cef-7f1b-40f4-a5f8-8a55ea5b0d84"]
action required string

One of set_quantity, adjust_quantity, or set_threshold.

Example: set_quantity
quantity integer

Absolute quantity used by set_quantity.

Example: 240
expected_quantities object

Optional with set_quantity: location id → on-hand quantity you counted against. A mismatch at any location returns 409 and changes nothing.

Example: {"af720cef-7f1b-40f4-a5f8-8a55ea5b0d84":236}
adjustment integer

Signed delta used by adjust_quantity.

Example: -5
low_stock_threshold integer

Threshold used by set_threshold; 0 is valid.

Example: 15
clear_threshold boolean

Set true with set_threshold to clear selected thresholds.

Example: false
reason string

Required movement reason for quantity actions.

Example: recount
notes string

Optional movement note for quantity actions.

Example: Bulk cycle count

Errors

  • 400 STORE_API_INVALID_REQUEST_BODY

    Request JSON could not be parsed.

  • 400 INVENTORY_GROUP_LOCATION_REQUIRED

    Location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_REQUIRED

    At least one location is required.

  • 400 INVENTORY_GROUP_LOCATIONS_NOT_FOUND

    One or more locations do not exist in this store.

  • 400 INVENTORY_GROUP_LOCATION_DUPLICATE

    The same location appears more than once.

  • 400 INVENTORY_GROUP_QUANTITY_NEGATIVE

    Quantity cannot be negative.

  • 400 INVENTORY_GROUP_QUANTITY_TOO_LARGE

    Quantity exceeds the contract maximum.

  • 400 INVENTORY_GROUP_QUANTITY_BELOW_RESERVED

    Quantity cannot be set below reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_NEGATIVE

    Adjustment would make quantity negative.

  • 400 INVENTORY_GROUP_ADJUST_BELOW_RESERVED

    Adjustment would make quantity lower than reserved stock.

  • 400 INVENTORY_GROUP_ADJUST_TOO_LARGE

    Adjustment would exceed the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_NEGATIVE

    Low-stock threshold cannot be negative.

  • 400 INVENTORY_GROUP_THRESHOLD_TOO_LARGE

    Low-stock threshold exceeds the contract maximum.

  • 400 INVENTORY_GROUP_THRESHOLD_REQUIRED

    Set-threshold was sent without low_stock_threshold. Send null to clear it.

  • 400 INVENTORY_GROUP_REASON_REQUIRED

    Movement reason is required.

  • 400 INVENTORY_GROUP_REASON_INVALID

    Movement reason is not allowed.

  • 400 INVENTORY_GROUP_NOTES_TOO_LONG

    Movement notes exceed the contract max length.

  • 400 INVENTORY_GROUP_NOTES_INVALID_CHARS

    Movement notes contain invalid characters.

  • 403 LOCATION_APP_MANAGED_NO_EDIT

    The location belongs to another app or its owning installation is inactive.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 404 INVENTORY_GROUP_STOCK_NOT_FOUND

    No stock row exists for the requested location.

  • 409 INVENTORY_GROUP_STOCK_EXISTS

    Stock already exists at one of the selected locations.

  • 400 INVENTORY_GROUP_STOCK_MAX_LOCATIONS

    The bulk stock batch exceeds the contract maximum.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_INVALID

    An expected quantity is negative.

  • 400 STOCK_LEVEL_EXPECTED_QUANTITY_SET_ONLY

    Expected quantities were sent with an action other than set_quantity.

  • 409 STOCK_LEVEL_EXPECTED_QUANTITY_MISMATCH

    The current on-hand quantity differs from the expected quantity; nothing changed.

  • 400 STOCK_WRITE_IDEMPOTENCY_KEY_TOO_LONG

    Idempotency-Key exceeds 200 characters.

  • 409 STOCK_WRITE_IDEMPOTENCY_CONFLICT

    The idempotency key was already used for a different stock write.

  • 409 LOCATION_ARCHIVED_NO_EDIT

    The write would change stock at an archived location.

Clear stored inventory group inventory state

DELETE write_inventory

Clear an empty persisted stock level at one location.

Deletes only the empty storage row and its threshold; it does not remove the location from the group's inventory view. A subsequent stock read still returns that visible location with zero quantity, and the next write recreates the level. Quantity and reservations must both be zero. App-managed locations are writable only by their owning active installation; merchants and other apps cannot clear their state.

Path parameters

Name Type Description
groupId required uuid

Inventory Group id.

Example: 5ff7d4ea-3250-4a4d-9d26-07f64d917d31
locationId required uuid

Location id.

Example: af720cef-7f1b-40f4-a5f8-8a55ea5b0d84

Headers

Name Type Description
Authorization required string

Bearer Store API token.

Errors

  • 403 LOCATION_APP_MANAGED_NO_EDIT

    The location belongs to another app or its owning installation is inactive.

  • 404 INVENTORY_GROUP_NOT_FOUND

    Inventory Group does not exist in this store.

  • 404 INVENTORY_GROUP_STOCK_NOT_FOUND

    No stock row exists for the requested location.

  • 409 INVENTORY_GROUP_STOCK_HAS_QUANTITY

    Stock location still has quantity or reservations.

Fields#

Field

Type

Create

Update

Required

Translatable

name

text

Yes

Yes

create

No

slug

slug

Yes

Yes

No

sku

text

Yes

Yes

create

No

description

textarea

Yes

Yes

No

overall_low_stock_threshold

integer

Yes

Yes

No

quantity

integer

No

No

No

reserved

integer

No

No

No

checkout_held

integer

No

No

No

order_committed

integer

No

No

No

other_held

integer

No

No

No

available

integer

No

No

No

is_low_stock

boolean

No

No

No

product_count

integer

No

No

No

variant_count

integer

No

No

No

location_count

integer

No

No

No

created_at

datetime

No

No

No

updated_at

datetime

No

No

No

Webhook events#

Subscribe to these events to keep your integration in sync with inventory groups. Each event shows the required Store API scope and store permission, the available payload fields, and an example payload. Subscription setup is validated against those permissions; delivery is always restricted to the subscription's store.

Inventory group created

EVENT inventory_groups/create App scope: read_inventory Staff permission: inventory:write

Fired when an inventory group is created.

Payload fields

Field Type Description
resource_type string Always present
resource_id string Always present
occurred_at string Always present
previous.id string Always present
previous.name string Selectable in the Payload builder
previous.slug string Selectable in the Payload builder
previous.sku string Selectable in the Payload builder
previous.description string Selectable in the Payload builder
previous.quantity integer Selectable in the Payload builder
previous.reserved integer Selectable in the Payload builder
previous.checkout_held integer Selectable in the Payload builder
previous.order_committed integer Selectable in the Payload builder
previous.other_held integer Selectable in the Payload builder
previous.low_stock_threshold integer Selectable in the Payload builder
previous.overall_low_stock_threshold integer Selectable in the Payload builder
current.id string Always present
current.name string Selectable in the Payload builder
current.slug string Selectable in the Payload builder
current.sku string Selectable in the Payload builder
current.description string Selectable in the Payload builder
current.quantity integer Selectable in the Payload builder
current.reserved integer Selectable in the Payload builder
current.checkout_held integer Selectable in the Payload builder
current.order_committed integer Selectable in the Payload builder
current.other_held integer Selectable in the Payload builder
current.low_stock_threshold integer Selectable in the Payload builder
current.overall_low_stock_threshold integer Selectable in the Payload builder
changed_fields array Selectable in the Payload builder

Inventory group updated

EVENT inventory_groups/update App scope: read_inventory Staff permission: inventory:write

Fired when an inventory group's fields change, including the group-wide low-stock threshold that follows a per-location threshold change. Stock quantity changes fire the stock level event, not this one.

Payload fields

Field Type Description
resource_type string Always present
resource_id string Always present
occurred_at string Always present
previous.id string Always present
previous.name string Selectable in the Payload builder
previous.slug string Selectable in the Payload builder
previous.sku string Selectable in the Payload builder
previous.description string Selectable in the Payload builder
previous.quantity integer Selectable in the Payload builder
previous.reserved integer Selectable in the Payload builder
previous.checkout_held integer Selectable in the Payload builder
previous.order_committed integer Selectable in the Payload builder
previous.other_held integer Selectable in the Payload builder
previous.low_stock_threshold integer Selectable in the Payload builder
previous.overall_low_stock_threshold integer Selectable in the Payload builder
current.id string Always present
current.name string Selectable in the Payload builder
current.slug string Selectable in the Payload builder
current.sku string Selectable in the Payload builder
current.description string Selectable in the Payload builder
current.quantity integer Selectable in the Payload builder
current.reserved integer Selectable in the Payload builder
current.checkout_held integer Selectable in the Payload builder
current.order_committed integer Selectable in the Payload builder
current.other_held integer Selectable in the Payload builder
current.low_stock_threshold integer Selectable in the Payload builder
current.overall_low_stock_threshold integer Selectable in the Payload builder
changed_fields array Selectable in the Payload builder

Inventory group deleted

EVENT inventory_groups/delete App scope: read_inventory Staff permission: inventory:write

Fired when an inventory group is deleted.

Payload fields

Field Type Description
resource_type string Always present
resource_id string Always present
occurred_at string Always present
previous.id string Always present
previous.name string Selectable in the Payload builder
previous.slug string Selectable in the Payload builder
previous.sku string Selectable in the Payload builder
previous.description string Selectable in the Payload builder
previous.quantity integer Selectable in the Payload builder
previous.reserved integer Selectable in the Payload builder
previous.checkout_held integer Selectable in the Payload builder
previous.order_committed integer Selectable in the Payload builder
previous.other_held integer Selectable in the Payload builder
previous.low_stock_threshold integer Selectable in the Payload builder
previous.overall_low_stock_threshold integer Selectable in the Payload builder
current.id string Always present
current.name string Selectable in the Payload builder
current.slug string Selectable in the Payload builder
current.sku string Selectable in the Payload builder
current.description string Selectable in the Payload builder
current.quantity integer Selectable in the Payload builder
current.reserved integer Selectable in the Payload builder
current.checkout_held integer Selectable in the Payload builder
current.order_committed integer Selectable in the Payload builder
current.other_held integer Selectable in the Payload builder
current.low_stock_threshold integer Selectable in the Payload builder
current.overall_low_stock_threshold integer Selectable in the Payload builder
changed_fields array Selectable in the Payload builder