Docs
Firmly Agentic Commerce
Set theme to dark (⇧+D)

Update Line Item

PUT https://api.firmly.work/api/v2/domains/{domain}/cart/line-items/{lineItemId}

​​ Overview

The Update Line Item endpoint modifies the quantity of an existing product in the cart. Key features include:

  • Quantity Modification: Update item quantities or remove items by setting quantity to 0
  • Automatic Recalculation: All pricing and shipment information is automatically updated
  • Shipment Preservation: Items remain in their assigned shipments after quantity updates
  • Addon Adjustment: Addon offers may change based on new cart totals

​​ Authentication

  • x-firmly-authorization (string, required) — Device access token from Browser Session

​​ Path Parameters

  • domain (string, required) — Domain of the merchant website (e.g., staging.luma.gift)

  • lineItemId (string, required) — Unique identifier of the line item to update. This is the line_item_id value from line_items[] in the cart (the path segment is camelCase; the field in the cart body is snake_case line_item_id).

​​ Request Body

  • quantity (number, required) — New quantity for the line item (minimum 0, set to 0 to remove the item)

  • variant_handles (string[]) — Optional variant configuration handles, for platforms that identify a line’s variant by a set of handles rather than a single SKU (e.g. ["color:blue", "size:large"]). Passed through to the merchant adapter when resolving which variant to update.

​​ Response

Returns the complete updated shopping cart. See Get Cart for full response schema.

​​ Update Behavior:

  • Quantity > 0: Updates the item quantity and recalculates pricing
  • Quantity = 0: Removes the item from the cart and its shipment
  • Empty Shipments: Shipments with no remaining items are automatically removed

​​ Code Examples


curl --request PUT \
--url https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/line-items/item_01H2XVBR8C8JS5MQSFPJ8HF9SB \
--header 'Content-Type: application/json' \
--header 'x-firmly-authorization: YOUR_TOKEN' \
--data '{
"quantity": 2
}'

const response = await fetch('https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/line-items/item_01H2XVBR8C8JS5MQSFPJ8HF9SB', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'x-firmly-authorization': 'YOUR_TOKEN'
},
body: JSON.stringify({
quantity: 2
})
});
const cart = await response.json();
console.log(cart);

import requests
response = requests.put(
'https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/line-items/item_01H2XVBR8C8JS5MQSFPJ8HF9SB',
headers={
'Content-Type': 'application/json',
'x-firmly-authorization': 'YOUR_TOKEN'
},
json={
'quantity': 2
}
)
cart = response.json()
print(cart)

<?php
$curl = curl_init();
$data = [
'quantity' => 2
];
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/line-items/item_01H2XVBR8C8JS5MQSFPJ8HF9SB",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-firmly-authorization: YOUR_TOKEN"
],
CURLOPT_POSTFIELDS => json_encode($data)
]);
$response = curl_exec($curl);
curl_close($curl);
$cart = json_decode($response, true);
print_r($cart);
?>

​​ Example Scenarios

​​ Increase Quantity

Update an item from quantity 1 to 2.

Request:


{
"quantity": 2
}

Response (truncated — the full cart is returned):


{
"line_items": [
{
"line_item_id": "bd3710bc-97ef-408d-7382-43b7e5de712f",
"platform_line_item_id": "e67bf7d1-ec90-4714-b44c-de044cd7daf7",
"sku": "MH07-XS-Gray",
"base_sku": "MH07",
"description": "Hero Hoodie - Gray XS",
"quantity": 2,
"price": { "currency": "USD", "value": 54.00, "number": 5400, "symbol": "$" },
"line_price": { "currency": "USD", "value": 108.00, "number": 10800, "symbol": "$" },
"msrp": { "currency": "USD", "value": 54.00, "number": 5400, "symbol": "$" },
"image": {
"url": "https://cdn.staging.luma.gift/product/hero-hoodie.jpg",
"type": "default"
},
"requires_shipping": true
}
],
"sub_total": { "currency": "USD", "value": 108.00, "number": 10800, "symbol": "$" }
}

​​ Remove Item

Set quantity to 0 to remove an item.

Request:


{
"quantity": 0
}

Response — line item dropped, totals re-zeroed:


{
"line_items": [],
"shipments": [],
"sub_total": { "currency": "USD", "value": 0, "number": 0, "symbol": "$" }
}

​​ Response Example


{
"cart_id": "a5600193-2c13-3356-d063-711da63b7cd7",
"platform_id": "example_commerce",
"shop_id": "staging.luma.gift",
"display_name": "Luma Store",
"cart_status": "active",
"line_items": [
{
"line_item_id": "bd3710bc-97ef-408d-7382-43b7e5de712f",
"sku": "MH07-XS-Gray",
"base_sku": "MH07",
"description": "Hero Hoodie - Gray XS",
"quantity": 2,
"price": {
"currency": "USD",
"value": 54.0,
"number": 5400,
"symbol": "$"
},
"line_price": {
"currency": "USD",
"value": 108.0,
"number": 10800,
"symbol": "$"
},
"msrp": {
"currency": "USD",
"value": 64.8,
"number": 6480,
"symbol": "$"
},
"image": {
"url": "https://staging.luma.gift/hero-hoodie-gray-xs.jpg",
"alt": "Hero Hoodie - Gray XS",
"type": "default"
}
}
],
"shipments": [
{
"shipment_id": "d22998b9-d331-c3f7-ca55-6d70072dd1fb",
"line_item_ids": [
"bd3710bc-97ef-408d-7382-43b7e5de712f"
],
"fulfillment_type": {
"id": "SHIP_TO_ADDRESS",
"name": "Ship to Address",
"description": "Standard shipping to customer address"
},
"shipping_method": {
"id": "STANDARD_GROUND",
"description": "Standard Ground Shipping",
"price": {
"currency": "USD",
"value": 49.99,
"number": 4999,
"symbol": "$"
},
"estimated_delivery": "5-7 business days"
}
}
],
"addons": {
"offers": [
{
"addon_id": "bulk_discount",
"display": {
"name": "Bulk Purchase Discount",
"description": "Save 5% on orders with 2+ items"
},
"scope": "CART",
"coverage_mode": "PREDEFINED_GROUP",
"price": {
"currency": "USD",
"value": -5.4,
"number": -540,
"symbol": "$"
}
}
],
"selections": []
},
"sub_total": {
"currency": "USD",
"value": 108.0,
"number": 10800,
"symbol": "$"
},
"shipping_total": {
"currency": "USD",
"value": 49.99,
"number": 4999,
"symbol": "$"
},
"tax_total": {
"currency": "USD",
"value": 10.8,
"number": 1080,
"symbol": "$"
},
"fees": [
{
"description": "Recycle fee",
"currency": "USD",
"value": 2.00,
"number": 200,
"symbol": "$"
}
],
"fee_total": {
"currency": "USD",
"value": 2.00,
"number": 200,
"symbol": "$"
},
"addon_total": {
"currency": "USD",
"value": 0.0,
"number": 0,
"symbol": "$"
},
"total": {
"currency": "USD",
"value": 170.79,
"number": 17079,
"symbol": "$"
},
"schema_version": "2.0"
}

​​ Error Responses

Errors return a JSON body with code, error, and description. Program against the error value — descriptions are human-readable and may change.

400 — MissingAuthHeader

The x-firmly-authorization header is missing or empty.


{
"code": 400,
"error": "MissingAuthHeader",
"description": "x-firmly-authorization header is missing or invalid."
}
400 — InvalidToken

The authorization token is not a valid JWT structure.


{
"code": 400,
"error": "InvalidToken",
"description": "Jwt token is invalid."
}
400 — InvalidAPIToken

The API token (server-to-server secret) is invalid or has been revoked.


{
"code": 400,
"error": "InvalidAPIToken",
"description": "API token is invalid."
}
400 — BadRequest

Server-to-server auth was attempted but the required headers (x-firmly-authorization plus x-firmly-device-id) are missing or malformed.


{
"code": 400,
"error": "BadRequest",
"description": "Bad request."
}
401 — Unauthorized

The authorization token was rejected.


{
"code": 401,
"error": "Unauthorized",
"description": "Unauthorized."
}
401 — InvalidJWTToken

The device JWT signature does not verify, or required claims are missing.


{
"code": 401,
"error": "InvalidJWTToken",
"description": "Jwt token is invalid."
}
404 — PartnerNotFound

The appid claim on the device JWT does not map to a known partner / tenant — typically a token from a different environment.


{
"code": 404,
"error": "PartnerNotFound",
"description": "Partner not found."
}
404 — DomainNotFound

The {domain} path parameter does not match any merchant configured with Firmly, or the merchant has been disabled. Verify the domain string (case-sensitive, no protocol or trailing slash).


{
"code": 404,
"error": "DomainNotFound",
"description": "This domain was not found in firmly servers."
}
404 — ProductNotFound

The supplied lineItemId does not map to an item in the current cart. Refresh the cart via Get Cart to obtain current line item IDs and retry.


{
"code": 404,
"error": "ProductNotFound",
"description": "Product not found."
}
409 — NotEnoughStockError

The requested quantity exceeds available inventory for the underlying variant. Reduce the quantity or wait for restock.


{
"code": 409,
"error": "NotEnoughStockError",
"description": "Not enough stock."
}
412 — OperationNotSupported

The merchant’s platform does not support this operation. Check with Firmly whether this endpoint is available for the merchant.


{
"code": 412,
"error": "OperationNotSupported",
"description": "This operation is not supported for this store."
}
412 — ProductNotSupported

The line item references a product type that is not supported by this merchant’s integration (e.g. some merchants reject subscription items or digital goods on update).


{
"code": 412,
"error": "ProductNotSupported",
"description": "Product is not supported."
}
412 — PostalCodeRequired

The merchant requires a postal code before line items can be modified. Call Set Postal Code, then retry.


{
"code": 412,
"error": "PostalCodeRequired",
"description": "Postal code is required."
}
400 — InvalidInputBody

Request body fails schema validation. Ensure quantity is present and is an integer >= 0 (use 0 to remove the line item).


{
"code": 400,
"error": "InvalidInputBody",
"description": "The body is not processable"
}