# Inventory overview Overview of the concepts related to inventory management. Inventory tracks sellable stock per SKU across supply locations. It enables you to manage stock levels, enforce purchase limits, and reserve stock to ensure availability during the checkout process. ## General concepts ### Inventory modes [InventoryMode](/urn?urn=ctp%3Aapi%3Atype%3AInventoryMode) defines how stock is managed when Line Items are added to a Cart. The following table summarizes the available inventory modes: | Inventory Mode | Description | Use Cases | | --- | --- | --- | | `None` | The default inventory mode. Stock levels are not checked or updated when Line Items are added to the Cart. | - Products that are always in stock (for example: digital goods).- Businesses that do not require inventory management.- Businesses that manage their inventory externally. | | `TrackOnly` | Stock levels are checked when Line Items are added to the Cart, but stock is only updated when the Order is created.Allows Orders to be placed even if the required stock is not available at that moment. | - Products with high stock levels where reservations are unnecessary. - Businesses that want to monitor stock without reserving it. - Allows for overselling scenarios and accepting backorders. | | `ReserveOnOrder` | Stock levels are checked when Line Items are added to the Cart, but stock is only reserved and updated when the Order is created.Prevents Orders from being placed if the required stock is not available at that moment. | - Standard inventory management where stock is only deducted upon Order creation. - Businesses that want to avoid holding stock before the order is finalized. | | `ReserveOnCart` | Stock levels are checked and reserved when Line Items are added to the Cart. Reservations expire after a set time. | - High-demand products where stock needs to be secured during checkout. - Businesses that want to minimize the risk of stockouts during checkout. | Inventory modes can be set at the Cart level and/or individually for each Line Item. The Line Item's inventory mode takes precedence over the Cart's mode. ### Manage inventory with InventoryEntry An [InventoryEntry](/urn?urn=ctp%3Aapi%3Atype%3AInventoryEntry) represents stock for a single SKU in an optional supply [Channel](/api/projects/channels.md). Only one InventoryEntry exists for each SKU and supply Channel pair. #### Quantity limits To restrict the quantity of a SKU that can be added to a Cart, you can set minimum and maximum limits on the [InventoryEntry](/urn?urn=ctp%3Aapi%3Atype%3AInventoryEntry): - `minCartQuantity`: the minimum allowed quantity for a Line Item in the Cart. This prevents customers from adding quantities below the specified threshold. - `maxCartQuantity`: the maximum allowed quantity for a Line Item in the Cart. This caps the quantity a customer can purchase at once. These limits are enforced when you create or update a Cart, and the Line Item's SKU and supply channel match the Inventory Entry. You set these limits when creating an InventoryEntry using the [InventoryEntryDraft](/urn?urn=ctp%3Aapi%3Atype%3AInventoryEntryDraft), or update them on an existing InventoryEntry using the [Set Inventory Limits](/api/projects/inventory.md#set-inventory-limits) update action. The following applies: - **Quantity limits are independent of InventoryMode**: the `minCartQuantity` and `maxCartQuantity` limits are enforced regardless of which [InventoryMode](/api/inventory-overview.md#inventory-modes) is used (None, TrackOnly, ReserveOnOrder, or ReserveOnCart). The inventory mode controls when and how stock is reserved or updated, but does not affect quantity limit enforcement. - **Each Line Item is evaluated independently**: each Line Item that matches an InventoryEntry record is evaluated independently against that InventoryEntry's defined quantity limits, regardless of whether other Line Items in the Cart use the same SKU, Product Variant, or supply Channel. This applies both when you have multiple Line Items for the same SKU and supply Channel (for example, distinguished by Custom Fields) and when you have Line Items for the same SKU across different supply Channels, allowing you to enforce distinct quantity constraints per Line Item context. When you introduce or change limits, it can potentially affect Line Items that are already present in Carts. For more information, see the [Set Inventory Limits](/api/projects/inventory.md#set-inventory-limits) update action documentation. ##### Enforcement scenarios The following table details when quantity limits are enforced: | Scenario | Enforcement | Notes | | --- | --- | --- | | **Cart creation** | Yes | If any Line Item exceeds its quantity limits, the Cart creation fails. | | **Cart update** | Yes | If any Cart update action results in a Line Item violating quantity limits, the entire request fails. | | **Order creation from Cart** | Yes | Quantity limits are enforced when creating an Order from a Cart. If any Line Item in the Cart violates the current limits (for example, after limits change or for Frozen Carts), the order creation fails. | | **Order Edits** | No | Quantity limits are not enforced during order edits. | | **Order Imports** | No | Quantity limits are not enforced during order imports. | While quantity limits are enforced on the backend, it is recommended that your application performs client-side checks using the [Inventory API](/api/projects/inventory.md) or [ProductVariantAvailability](/urn?urn=ctp%3Aapi%3Atype%3AProductVariantAvailability) object to fetch and display quantity limits to customers. This prevents failed cart updates or order creations and improves the customer experience. ##### Workarounds If a customer needs to purchase more than the `maxCartQuantity` for a single Product Variant, consider the following options: - **Custom field workaround**: add custom fields with different values to Line Items. This allows creating multiple Line Items for the same Product Variant, each subject to the quantity limits individually. The total quantity across all Line Items can exceed the limit of a single Line Item. - **Adjust or remove quantity limits**: modify the `minCartQuantity` or `maxCartQuantity` values on the [InventoryEntry](/urn?urn=ctp%3Aapi%3Atype%3AInventoryEntry), or remove the limits entirely. - **Use another InventoryEntry**: create or use a different InventoryEntry for the same SKU without quantity limits, potentially with a different supply channel. #### Stock level notifications To stay informed about inventory changes, you can set up stock level notifications. These notifications alert you when the `quantityOnStock` amount of an [InventoryEntry](/urn?urn=ctp%3Aapi%3Atype%3AInventoryEntry) falls below or rises above certain thresholds. To get notified, set your required threshold amounts on the `stockLevels` field of each InventoryEntry. | Field | Purpose | Typical use cases | Message sent | | --- | --- | --- | --- | | `reorderPoint` | Early-warning threshold indicating stock is low and should be replenished before running out during lead time. | - Trigger notifications or automations (ERP/OMS) to create purchase orders. - Show "low stock" messaging on the storefront. - Highlight low stock levels in internal dashboards. | [InventoryEntryReorderPoint](/api/projects/messages/product-catalog-messages.md#inventoryentry-reorder-point) | | `safetyStock` | Critical minimum threshold showing that inventory has reached an urgent, buffer-level quantity. | - Signal a critical low-stock situation. - Allow OMS/ERP to limit or stop selling. - Display "very low stock" or hide items on certain sales channels. | [InventoryEntrySafetyStock](/api/projects/messages/product-catalog-messages.md#inventoryentry-safety-stock) | #### Inventory checks and consistency While [InventoryEntry](/urn?urn=ctp%3Aapi%3Atype%3AInventoryEntry) is the source of truth for stock levels, the time it takes for changes to be reflected depends on where those changes originate: - Direct updates to InventoryEntry using the [Inventory API](/api/projects/inventory.md) are [strongly consistent](/api/general-concepts.md#strong-consistency) and immediately visible. - Order operations using the `ReserveOnOrder` or `TrackOnly` inventory modes are [eventually consistent](/api/general-concepts.md#eventual-consistency). This means that changes to the `availableQuantity` and `quantityOnStock` fields of the corresponding InventoryEntry may take up to 10 seconds to appear. - Reservation-based updates to resources using the `ReserveOnCart` inventory mode are [eventually consistent](/api/general-concepts.md#eventual-consistency). This means that changes to the `availableQuantity` and `quantityOnStock` fields of the corresponding InventoryEntry may take up to 10 seconds to appear. The following endpoint and update actions are affected if the Cart or Line Items use the `ReserveOnCart` inventory mode: - [Create Order from Cart](/urn?urn=ctp%3Aapi%3Aendpoint%3A%2F%7BprojectKey%7D%2Forders%3APOST) - [Cart update actions](/urn?urn=ctp%3Aapi%3Aendpoint%3A%2F%7BprojectKey%7D%2Fcarts%2F%7Bid%7D%3APOST) `changeLineItemQuantity`, `addLineItem`, `removeLineItem`, and `setLineItemInventoryMode`. Reservations are guaranteed regardless of the eventual consistency delay. The reservation logic acquires stock from an internal real-time SKU availability collection, which ensures that stock checks and reservations are accurate at the time they are made. The `availableQuantity` and `quantityOnStock` fields on the InventoryEntry are eventually aligned with this internal collection, but the delay does not affect reservation guarantees or cause failed Order placements due to stockouts. To obtain the most accurate stock data (for example, when adding items to a cart, performing fulfillment checks, etc.), query the corresponding InventoryEntry. We recommend that you only fetch the data that you need. For example, avoid loading all InventoryEntries for a SKU when you only need supply channel availability or specific stock details. For non-critical availability checks, such as for displaying a quantity on a product listing page, you can use the `availability` field in [ProductVariant](/urn?urn=ctp%3Aapi%3Atype%3AProductVariant). This provides an overview of stock levels which may lag behind real-time stock levels by a few seconds. However, checking inventory in this manner reduces the need to query the Inventory API directly. Learn more about InventoryEntry, including querying best practices in our self-paced [Inventory modeling](/learning-model-your-product-catalog/inventory-modeling/overview.md) module. #### Supply channels versus distribution channels Supply channels (where stock is held) are distinct from distribution channels (used for price selection). An InventoryEntry optionally links to a supply channel through the `supplyChannel` field. A Cart bound to a [Store](/api/projects/stores.md) filters available stock and prices using the Store's configured channels. To fulfill a single SKU from multiple inventory locations, you can add multiple Line Items to the Cart, each specifying a different supply channel. ## Reservations A [Reservation](/urn?urn=ctp%3Aapi%3Atype%3AReservation) temporarily holds stock for an individual Line Item in a Cart. Reservations are created automatically if the [Project-level reservation expiration](/api/projects/project.md#set-reservation-expiration-in-minutes) is set, and one of the following occurs: - The Cart's inventory mode is `ReserveOnCart`. - One or more Line Item's inventory mode is set to `ReserveOnCart` but the Cart has a different inventory mode. When a reservation is created, the `availableQuantity` of the corresponding [InventoryEntry](/urn?urn=ctp%3Aapi%3Atype%3AInventoryEntry) is decreased by the reserved amount. When a reservation expires, or is released, the `availableQuantity` is increased accordingly. Deleting a Cart also removes all associated reservations and releases the reserved quantity back to the corresponding InventoryEntries. Reservations apply to both regular Line Items and Gift Line Items. Gift Line Items follow the same reservation behavior as regular Line Items. Reservation-based changes to InventoryEntry are eventually consistent. For more information, see [Inventory checks and consistency](/api/inventory-overview.md#inventory-checks-and-consistency). ### Set the default expiration To use reservations, you must first [set the Project-level reservation expiration time](/api/projects/project.md#set-reservation-expiration-in-minutes). After you set this default, you'll be able to use the `ReserveOnCart` [InventoryMode](/urn?urn=ctp%3Aapi%3Atype%3AInventoryMode) on Carts or individual Line Items. This step ensures that stock is not held indefinitely. You only have to set this once per Project. You can optionally set the default expiration time for individual InventoryEntries using the [Set Reservation Expiration In Minutes](/api/projects/inventory.md#set-reservation-expiration-in-minutes) update action. ### Reserve items [Reservations](/api/projects/reservations.md#reservation) expire based on the `reservationExpirationInMinutes` value set in the corresponding [InventoryEntry](/urn?urn=ctp%3Aapi%3Atype%3AInventoryEntry), or if absent, the Project-level reservation expiration time. Reserved Line Items include a `reservation` field containing the reservation reference, which you can then [expand](/api/general-concepts.md#reference-expansion) to view additional details. There is no dedicated API endpoint to query or manage Reservation resources directly; they are only accessible through reference expansion on a Cart's Line Items. #### Reserve all items in a Cart To reserve stock for all Line Items in a Cart, set the Cart's inventory mode to `ReserveOnCart` during Cart creation. The following applies: - If all items could be reserved, the Cart creation succeeds, and no warnings are present in the response. - If some items could not be reserved, the Cart creation succeeds, however, those items are not added to the Cart. The response will contain a [CannotCreateReservation](/api/types.md#cannotcreatereservation-warning) warning for each Line Item that could not be reserved/added. - If no Line Items could be reserved, the Cart creation fails. #### Reserve individual Line Items To reserve stock for individual Line Items in a Cart, set the Line Item's inventory mode to `ReserveOnCart`. You can do this when adding items to a Cart, or for existing items, using the [Set LineItem InventoryMode](/api/projects/carts.md#set-lineitem-inventorymode) update action. The following applies: - When changing an existing Line Item's inventory mode to `ReserveOnCart` and there is insufficient stock available, the response contains a [CannotCreateReservation](/api/types.md#cannotcreatereservation-warning) warning. The Line Item remains in the Cart and the inventory mode remains unchanged. - When adding a new Line Item with the inventory mode set to `ReserveOnCart`, and there is insufficient stock available, the response contains a [CannotCreateReservation](/api/types.md#cannotcreatereservation-warning) warning, and the Line Item is not added to the Cart. ### Update a reservation The following scenarios illustrate how to update an existing reservation: #### Change the reserved quantity To change the quantity of a reserved Line Item, use the [Change LineItem Quantity](/api/projects/carts.md#change-lineitem-quantity) update action on the Cart. If successful, the platform updates the `availableQuantity` of the associated InventoryEntry and extends the reservation expiration time. Because changing the quantity also updates the expiration time, you may want to synchronize the expiration across all Line Items in the Cart. To do this, use the [Set Reservation Expiration in Minutes](/api/projects/carts.md#set-reservation-expiration-in-minutes) update action on the Cart after updating the quantity. #### Extend the reservation expiration To extend the expiration time of all reservations in a Cart, use the [Set Reservation Expiration in Minutes](/api/projects/carts.md#set-reservation-expiration-in-minutes) update action on the Cart. If successful, all reservations will have the same expiration time, based on the new value provided. If a reservation cannot be updated, the response will contain a [CannotChangeReservationExpiryWarning](/api/types.md#cannotchangereservationexpiry-warning) which provides details about the failure. When this occurs, the expiration time of the affected reservation remains unchanged. To prevent Order creation failures due to a last-second expiration, the platform automatically attempts to renew expired Cart reservations during the Order creation process. ### Release a reservation To release a reservation, change the Line Item's inventory mode from `ReserveOnCart` to another inventory mode using the [Set LineItem InventoryMode](/api/projects/carts.md#set-lineitem-inventorymode) update action. This action increases the `availableQuantity` of the associated InventoryEntries accordingly. ### Handle reservation warnings The following warnings may appear in Cart responses when working with reservations: | Warning | Appearance | | --- | --- | | [CannotCreateReservationWarning](/api/types.md#cannotcreatereservation-warning) | Appears when creating a Cart with `ReserveOnCart` but one or more Line Items lack sufficient stock. No reservation is created. See [Reserve items](/api/inventory-overview.md#reserve-items). | | [CannotUpdateReservationWarning](/api/types.md#cannotupdatereservation-warning) | Appears when updating a Line Item's quantity but the reservation cannot be updated (usually due to insufficient stock). The Line Item quantity remains unchanged. | | [CannotChangeReservationExpiryWarning](/api/types.md#cannotchangereservationexpiry-warning) | Appears when trying to extend an expired reservation but insufficient stock prevents reacquiring it. The action succeeds, but the reservation expiry cannot be extended. | ### Further reading To learn more about implementing reservations, see the following tutorials: - [Reserve stock on Cart](/tutorials/reserve-stock-on-cart.md): learn how to automatically reserve items in a Cart. - [Reserve stock on demand and freeze prices](/tutorials/reserve-stock-on-demand.md): learn how to reserve items on demand while freezing all prices. ## Related pages - [Area overview page with navigation](/api.md) - [Next page: Inventory](/api/projects/inventory.md)