data-src=../../../../includes/saas-only.md
setNominatedSourceOnCartItems mutation
The setNominatedSourceOnCartItems mutation is the single canonical write path for a nomination. Specify a source_code to set a nomination, or null or an empty string to clear it.
Domain validation failures are returned for each item in rejected_items, which allows valid nominations in the same request to succeed. An invalid or foreign cart_item_uid, or any other malformed input, fails the entire operation with a GraphQL input error before any nomination is written.
Reference
The setNominatedSourceOnCartItems reference provides detailed information about the types and fields defined in this mutation.
Configure the storefront query
By default, this inventory information is not accessible on the storefront. To enable it, complete the following steps.
Enable the per-source availability query
The per-source portion of the sourceAvailability query is disabled by default because it discloses which sources stock a SKU. Enable it for each store view.
-
In the Admin, go to Stores > Settings > Configuration > Catalog > Inventory > Per-Source Availability (Storefront).
-
Set Enable
sourceAvailabilityGraphQL Query toYesand save the configuration.
While this setting is disabled, the sourceAvailability query returns an empty list. The stockAvailability query does not disclose sources and is not affected by this setting.
For more information, see Global options and Inventory configuration.
Make a source visible on the storefront
Even when the query is enabled, a source is reported only if it is explicitly flagged.
-
In the Admin, go to Stores > Inventory > Sources and edit a source.
-
Enable Visible on Storefront and save the source.
A source is reported on the storefront only when it is assigned to the stock of the current sales channel.
For more information, see Add a source in the Adobe Commerce Admin Systems Guide.
Get the cart item UID
The mutation requires the masked cart ID and the UID of each cart item to nominate. Create a cart with the createGuestCart mutation or retrieve one with the customerCart query, add products to it, and then query the cart items.
Request:
query GetCartItems($cartId: String!) {
cart(cart_id: $cartId) {
itemsV2 {
items {
uid
product { sku name }
quantity
}
}
}
}
Response:
{
"data": {
"cart": {
"itemsV2": {
"items": [
{ "uid": "OTk=", "product": { "sku": "24-MB01", "name": "Joust Duffle Bag" }, "quantity": 1
}
]
}
}
}
}
Set the nominated source
The following mutation nominates the store_nyc_001 source for one cart item.
Request:
mutation SetSource($cartId: String!) {
setNominatedSourceOnCartItems(
input: {
cart_id: $cartId
items: [{ cart_item_uid: "OTk=", source_code: "store_nyc_001" }]
}
) {
cart {
itemsV2 {
items {
uid
nominated_source { source_code name is_in_stock available_qty }
nominated_source_errors { code message }
}
}
}
rejected_items {
cart_item_uid
code
message
requested_qty
available_qty
}
}
}
Response:
{
"data": {
"setNominatedSourceOnCartItems": {
"cart": {
"itemsV2": {
"items": [
{
"uid": "OTk=",
"nominated_source": {
"source_code": "store_nyc_001",
"name": "NYC Flagship Store",
"is_in_stock": true,
"available_qty": null
},
"nominated_source_errors": []
}
]
}
},
"rejected_items": []
}
}
}
data-variant=info
data-slots=text
pickup_location_code with the setShippingAddressesOnCart mutation automatically nominates that location as the source for every cart item. In-store pickup reuses this write path internally, so no separate call is required.Handle rejected items
When a nomination fails domain validation, the item is returned in rejected_items and the remaining nominations in the request are applied. The following response shows one item that does not have the necessary quantity available at the selected source.
{
"data": {
"setNominatedSourceOnCartItems": {
"cart": { "itemsV2": { "items": [ <...> ] } },
"rejected_items": [
{
"cart_item_uid": "MTAw",
"code": "NOT_ENOUGH_QTY",
"message": "Not enough quantity at the selected source.",
"requested_qty": 5,
"available_qty": 2
}
]
}
}
}
The code field returns one of the following NominatedSourceErrorCode values.
UNKNOWN_SOURCEsource_code value does not exist.SOURCE_DISABLEDNOT_ENOUGH_QTYSKU_SOURCE_CONFLICTReview nominated sources in the Admin
After orders begin to carry nominations, you can review each nomination and receive early validation in the Admin:
-
Sales > Orders > [order] > Items Ordered - Each nominated line displays a Nominated source label. Lines without a nomination are unchanged.
-
Ship > Source Selection - On a multi-source order, each nominated line displays its nominated source, so you can ship the item from the correct location.
-
Ship > Source Selection validation - Before submission, nominated lines are validated against the source that is selected for deduction. A mismatch returns an inline error that names each SKU and its required source.
data-variant=info
data-slots=text
Read availability and saleability
Two queries report availability, and you can request both in a single GraphQL request:
- The
stockAvailabilityquery returns the stock-level salable quantity and Add to Cart eligibility for each requested SKU. It accounts for every open reservation, including orders placed without a nominated source. - The
sourceAvailabilityquery returns per-source availability when per-source disclosure is enabled. Per-source availability is calculated the same way as the order placement guard, as physical quantity net of open source-level reservations.
Each query accepts a maximum of 100 skus values. The sourceAvailability query also accepts a maximum of 100 source_codes values. Consider splitting larger lists into batches that stay within these limits.
Request:
query Availability {
stockAvailability(skus: ["24-MB01"]) {
sku
salable_qty
is_in_stock
is_salable # authoritative Add to Cart gate (backorders considered)
backorder_message # pre-order notice, or null
}
sourceAvailability(skus: ["24-MB01"], only_in_stock: true) {
sku
sources {
source_code
name
is_in_stock
available_qty
is_pickup_location_active
}
}
}
Response:
{
"data": {
"stockAvailability": [
{
"sku": "24-MB01",
"salable_qty": null,
"is_in_stock": true,
"is_salable": true,
"backorder_message": null
}
],
"sourceAvailability": [
{
"sku": "24-MB01",
"sources": [
{
"source_code": "store_nyc_001",
"name": "NYC Flagship Store",
"is_in_stock": true,
"available_qty": null,
"is_pickup_location_active": true
}
]
}
]
}
}
For the full argument and type reference, see the stockAvailability and sourceAvailability queries.
Gate Add to Cart on is_salable
Use the stockAvailability is_salable field, not is_in_stock, to determine whether a shopper can add a product to the cart. The is_salable field is the authoritative purchase-eligibility signal and accounts for backorders, the minimum sale quantity, and quantity increments. It is true when the SKU is in stock, or when the SKU is out of stock but backorders are enabled, which indicates a pre-order.
The per-source is_in_stock field is a physical-inventory statement about a single source. It can be false for a SKU that remains purchasable through backorder, so gating the Add to Cart button on it incorrectly hides pre-order products. The stockAvailability query returns is_salable for every visible SKU, regardless of the per-source disclosure setting for the store.
Identify pre-order products
The stockAvailability backorder_message field only populates when the SKU is salable solely because notify-mode backorders are enabled, meaning the SKU is salable but not in stock. The field is null when the SKU is in stock, when backorders are silent, or when the SKU is not salable. Use the presence of a message to render a pre-order label next to the Add to Cart button.
Interpret quantities
The available_qty and salable_qty fields return an exact quantity only when the quantity is at or below the Only X left Threshold setting. Above the threshold, the fields return null. The threshold defaults to 0, so by default every positive quantity is masked and the boolean fields carry the information.
Control source visibility
The sourceAvailability query returns results only when per-source disclosure is enabled, and the sources list is narrowed to the storefront-visible sources in the stock of the current sales channel. When disclosure is disabled, the query returns an empty list. Use stockAvailability for per-SKU availability on those stores.
Specify source_codes to restrict the report to named sources. A requested source that is not visible on the storefront, or that is not assigned to the stock of the sales channel, is silently omitted. Omit only_in_stock, which defaults to false, to include out-of-stock sources.
Read nomination fields on cart items
Any cart query can read the live state of the nomination on an item through the following fields:
-
nominated_source: SourceAvailabilityreturns the nominated source with a live availability snapshot. The field isnullwhen the item has no nomination, or when the source no longer resolves or is disabled. -
nominated_source_errors: [NominatedSourceError!]!returns live validation of the current nomination, which can beUNKNOWN_SOURCE,SOURCE_DISABLED, orNOT_ENOUGH_QTYif availability has dropped since the nomination. The list is empty when the nomination is valid.SKU_SOURCE_CONFLICTnever appears in this list, because it is enforced only on the write path.
Order lifecycle
After an order that contains nominations is placed, the reservation lifecycle runs automatically.
-
Quote to order. The nomination is copied from the quote item to the order item and persisted as the source of truth for the line.
-
Placement. A hold is recorded at the nominated source for each nominated line, and the stock-level reservation is suppressed for that line so the hold is not counted twice. A placement validation rule rejects the order if the nominated source cannot cover the line. The open hold is also included in the shared salable quantity total, so both the displayed quantity and the Add to Cart guard account for it while the order is unshipped.
-
Shipment. A release is recorded at the nominated source, and the physical deduction is forced to that same source. A mismatched source is rejected before any decrement occurs. The hold and the release net to zero.
-
Cancellation. For each nominated line that has an open hold, a release is recorded at the nominated source. Only the unshipped quantity is compensated, because quantity that was already shipped was released during shipment. Cancellation is an alternative to shipment, not a later step.
-
Cleanup. A daily cron job removes fully compensated rows from the append-only reservation ledger.