# Check out a cart Converts an ACTIVE cart into an order. The cart must have at least one item and a handoff mode must be available (either stored on the cart via PUT /carts/{cart_id}/handoff, or provided as an override in the request body). Validation performed at checkout: - Cart is in ACTIVE status - Cart has at least one item - All items are still available in the current menu - Modifier selections satisfy group constraints (min/max) - Handoff mode exists (stored on cart OR provided in request body) Age verification: If the cart contains age-restricted items, checkout succeeds but the response includes age_verification_required: true and an age_verification_notice explaining that the consumer will be verified at pickup or delivery. Price changes: If expected_total is provided and the current total differs, the server returns 409 Conflict. Omit expected_total to accept the current price. After successful checkout, the cart status changes to CHECKED_OUT and can no longer be modified. The created order is returned with status PENDING. Idempotency: This endpoint supports idempotent requests. Include an Idempotency-Key header (UUID v4) to safely retry requests. If the cart has already been checked out with the same idempotency key, the original order is returned. Endpoint: POST /carts/{cart_id}/checkout Version: 1.0.0 Security: oauth2 ## Path parameters: - `cart_id` (string, required) Unique identifier for the cart. ## Header parameters: - `Idempotency-Key` (string, required) A unique key (UUID v4) to ensure idempotent request processing. Required on all POST, PUT, and DELETE requests. If a request is retried with the same key within 24 hours, the server returns the cached success response without re-processing. Error responses are NOT cached -- retrying after an error with the same key will re-execute the request. Generate a new UUID v4 for each unique operation. Reuse the same key only when retrying a failed or timed-out request. Example: "d7a8fbb3-07d4-4e3c-b5f2-9a6c8b1e0f23" ## Request fields (application/json): - `handoff_mode` (any) - `expected_total` (integer,null) Optional optimistic concurrency check. If provided (in cents), the server compares this against the current calculated total. If they don't match (e.g., prices changed since the last calculate call), the server returns 409 Conflict instead of proceeding with checkout. Omit this field to skip the total verification and proceed with the current price. - `notes` (string,null) Optional order notes from the customer (e.g., "No onions please"). ## Response 201 fields (application/json): - `id` (string, required) Unique identifier for the order. - `cart_id` (string, required) The cart this order was created from. - `location_id` (string, required) The location (store) this order belongs to. - `customer_id` (string,null) Customer identifier from the cart at checkout time. Null for anonymous orders. Locked at checkout -- cannot be changed after the order is created. Example: "CUST-12345" - `status` (string, required) Order lifecycle status. Tracks the high-level state of the order from creation through completion or cancellation. - PENDING: Order created from cart checkout, awaiting payment. - CONFIRMED: At least one payment completed; order accepted by the store. - COMPLETED: Order fulfilled and closed. - FAILED: Order could not be processed (e.g., all payments failed). - VOIDED: Order voided before any fulfillment began. - CANCELLED: Order cancelled by customer or system. State transitions: - PENDING -> CONFIRMED, FAILED, VOIDED, CANCELLED - CONFIRMED -> COMPLETED, CANCELLED - COMPLETED, FAILED, VOIDED, CANCELLED are terminal (no further transitions) Enum: "PENDING", "CONFIRMED", "COMPLETED", "FAILED", "VOIDED", "CANCELLED" - `payment_status` (string, required) Aggregate payment status across all payments on the order. This is a server-computed summary -- do not set directly. - UNPAID: No payments submitted yet. - PROCESSING: At least one payment is in a non-terminal state (PENDING or AUTHORIZED). - PARTIALLY_PAID: Some payments completed but total paid = order total. The order is fully covered. State transitions: - UNPAID -> PROCESSING, PARTIALLY_PAID, PAID - PROCESSING -> PARTIALLY_PAID, PAID, UNPAID (if all payments fail) - PARTIALLY_PAID -> PROCESSING, PAID - PAID is terminal for forward flow (refunds revert to PARTIALLY_PAID or UNPAID) Enum: "UNPAID", "PROCESSING", "PARTIALLY_PAID", "PAID" - `fulfillment_status` (string, required) Fulfillment lifecycle status. Tracks the physical preparation and handoff of the order. Maps directly from the backend fulfillment state machine. - PENDING: Order created, not yet accepted by store. - IN_PROGRESS: Store accepted the order and is queuing it. - PREPARING: Store staff actively assembling the order. - READY_FOR_PICKUP: Order assembled and waiting for customer (pickup/curbside). - FULFILLED: Customer received the order (pickup/curbside/kiosk). - DELIVERED: Order delivered to customer address (delivery orders). - RETURNED: Order returned after fulfillment. - CANCELLED: Fulfillment cancelled before completion. State transitions: - PENDING -> IN_PROGRESS, CANCELLED - IN_PROGRESS -> PREPARING, CANCELLED - PREPARING -> READY_FOR_PICKUP, CANCELLED - READY_FOR_PICKUP -> FULFILLED, DELIVERED, CANCELLED - FULFILLED -> RETURNED - DELIVERED -> RETURNED - RETURNED, CANCELLED are terminal (no further transitions) Cancellation restriction: Orders can only be cancelled via POST /orders/{order_id}/cancel when fulfillment_status is PENDING or IN_PROGRESS. Once preparation begins, cancellation requires store intervention. Enum: "PENDING", "IN_PROGRESS", "PREPARING", "READY_FOR_PICKUP", "FULFILLED", "DELIVERED", "RETURNED", "CANCELLED" - `items` (array, required) Line items in the order (locked at checkout). - `items.id` (string, required) Unique identifier for this order item. - `items.menu_item_id` (string, required) Reference to the original menu item. - `items.name` (string, required) Display name of the item (locked at checkout). - `items.quantity` (integer, required) Number of this item in the order. - `items.base_price` (object, required) Base price per unit (locked at checkout). - `items.base_price.amount` (integer, required) Monetary value in the smallest currency unit (cents for USD). Example: 1299 = $12.99. Example: 1299 - `items.base_price.currency` (string, required) ISO 4217 currency code. Example: "USD" - `items.modifier_total` (object, required) Total price of all selected modifiers per unit (locked at checkout). - `items.item_total` (object, required) Total for this line item: (base_price + modifier_total) * quantity. Locked at checkout. - `items.modifier_selections` (array, required) Modifiers selected for this item (locked at checkout). - `items.modifier_selections.modifier_group_id` (string, required) ID of the modifier group this selection belongs to. - `items.modifier_selections.modifier_id` (string, required) ID of the selected modifier within the group. - `items.modifier_selections.quantity` (integer) Quantity of this modifier. Relevant for modifier groups with allows_duplicates: true (e.g., "Extra Cheese x2"). - `items.modifier_selections.nested_selections` (array) Selections for nested modifier groups. For example, selecting "Steak" as a protein, then choosing "Medium" from the steak preparation sub-group. Supports up to 3 nesting levels, matching the menu's modifier group depth. - `items.special_instructions` (string,null) Customer's special instructions for this item, locked at checkout. Null if none were provided. - `items.age_verification_required` (boolean) True if this item requires age verification. Copied from the menu item at checkout time. - `items.minimum_age` (integer,null) Minimum age required to purchase this item (e.g., 21 for alcohol). Null if age verification is not required. - `payments` (array, required) Payments attached to this order. Empty array until the first payment is submitted via POST /orders/{order_id}/payments. - `payments.id` (string, required) Unique identifier for the payment. - `payments.order_id` (string, required) The order this payment is attached to. - `payments.status` (string, required) Payment processing status. The typical online ordering flow is: PENDING -> COMPLETED (immediate capture). For pre-authorization flows: PENDING -> AUTHORIZED -> CAPTURED -> COMPLETED. Terminal states: COMPLETED, VOIDED, REFUNDED, FAILED. State transitions: - PENDING -> AUTHORIZED, COMPLETED, FAILED - AUTHORIZED -> CAPTURED, VOIDED, FAILED - CAPTURED -> COMPLETED, REFUNDED, PARTIALLY_REFUNDED - COMPLETED -> REFUNDED, PARTIALLY_REFUNDED - VOIDED, REFUNDED, FAILED are terminal (no further transitions) - PARTIALLY_REFUNDED -> REFUNDED (when remaining amount is refunded) Enum: "PENDING", "AUTHORIZED", "CAPTURED", "COMPLETED", "VOIDED", "REFUNDED", "PARTIALLY_REFUNDED", "FAILED" - `payments.payment_method` (string, required) The payment method used. These are the API-facing values; the server maps them to internal payment processing types. - CREDIT_CARD: Visa, Mastercard, Amex, Discover credit cards - DEBIT_CARD: Debit cards with PIN or signature - CASH: Customer pays cash at the pickup counter. Only meaningful for PICKUP and DINE_IN handoff modes. The order is submitted online but payment is collected in-store. - GIFT_CARD: Store gift cards or third-party gift cards - LOYALTY_POINTS: Loyalty program points redeemed as payment - DIGITAL_WALLET: Apple Pay, Google Pay, or other digital wallets - EBT: SNAP/EBT card. Item eligibility applies -- only SNAP-eligible items (generally food items, excluding hot prepared foods and tobacco) can be paid with EBT. Check allowed_tenders on each menu item. Tolerant Reader: New payment method values may be added in future API versions. Your integration should handle unknown enum values gracefully (e.g., log a warning and skip) rather than failing. Enum: "CREDIT_CARD", "DEBIT_CARD", "CASH", "GIFT_CARD", "LOYALTY_POINTS", "DIGITAL_WALLET", "EBT" - `payments.amount` (object, required) The payment amount in cents. - `payments.tip_amount` (any) Tip amount included in this payment, if any. Null if no tip. - `payments.payment_details` (object,null) Method-specific details. Shape varies by payment_method: - CREDIT_CARD / DEBIT_CARD: { "last_four": "4242", "brand": "visa", "exp_month": 12, "exp_year": 2027 } - GIFT_CARD: { "last_four": "7890", "balance_remaining": { "amount": 1500, "currency": "USD" } } - LOYALTY_POINTS: { "points_used": 500, "points_remaining": 1200 } - DIGITAL_WALLET: { "wallet_type": "apple_pay" } - `payments.idempotency_key` (string) The idempotency key used when this payment was submitted. - `payments.created_at` (string, required) When the payment was created. - `payments.updated_at` (string, required) When the payment status was last updated. - `discounts` (array) Discounts applied to the order (locked at checkout). - `discounts.id` (string, required) Unique identifier for this discount. Server-generated opaque string for reconciliation and tracking. - `discounts.name` (string, required) Display name of the discount (e.g., "10% Off First Order", "$2 Off Subs"). - `discounts.type` (string, required) Whether this discount is a percentage off or a fixed amount. PERCENTAGE: the value field contains the percentage (e.g., "10.00" for 10%). FIXED: the amount field contains the fixed discount in cents. Enum: "PERCENTAGE", "FIXED" - `discounts.value` (string,null) For PERCENTAGE discounts, the percentage value as a decimal string (e.g., "10.00" for 10%). Null for FIXED discounts. - `discounts.amount` (object, required) The calculated discount amount deducted (always positive, in cents). - `discounts.source` (string, required) Where this discount originated. - AUTOMATIC: Discount applied automatically by the server based on rules (happy hour, spend threshold, item combo, location-specific). - PROMO_CODE: Discount from a promo or coupon code entered by the customer. - LOYALTY_REWARD: Discount from a loyalty program reward redemption. - MANUAL: Discount applied manually by store staff or POS override. Enum: "AUTOMATIC", "PROMO_CODE", "LOYALTY_REWARD", "MANUAL" - `discounts.application_scope` (string, required) Whether this discount is applied before or after tax calculation. PRE_TAX discounts reduce the taxable amount. POST_TAX discounts reduce the total after tax. Most discounts are PRE_TAX. Enum: "PRE_TAX", "POST_TAX" - `promo_codes` (array) Promo codes that were active on the cart at checkout (locked at checkout). - `promo_codes.code` (string, required) The promo code string, normalized to uppercase. Codes are case-insensitive on input ("summer25" and "SUMMER25" are treated identically) but always returned as uppercase in responses. Example: "SUMMER25" - `promo_codes.status` (string, required) Current status of this promo code on the cart. - ACTIVE: The code is applied and its discount is reflected in totals. - EXPIRED: The code expired after being applied (e.g., time-limited promo). - REDEEMED: The code was already used (single-use codes) and locked at checkout. Enum: "ACTIVE", "EXPIRED", "REDEEMED" - `promo_codes.discount_preview` (object) Estimated discount this promo code provides. Present when the code is ACTIVE. The actual discount amount appears in the PriceCalculation discounts array with source: PROMO_CODE. - `promo_codes.discount_preview.estimated_discount` (object) Estimated discount amount in cents. - `promo_codes.discount_preview.description` (string) Human-readable description of the discount. Example: "25% off your order (up to $10)" - `promo_codes.applied_at` (string, required) When this promo code was applied to the cart. - `handoff` (any) - `notes` (string,null) Customer notes from checkout (e.g., "No onions please"). Null if no notes were provided. - `subtotal` (object, required) Sum of all item totals before tax and discounts. - `total_tax` (object, required) Total tax amount for the order. - `total_discount` (object) Total of cart-level discounts applied to the order (locked at checkout). Item-level discounts are reflected in each item's total. - `fees` (array) Fees applied to this order (locked at checkout). - `fees.id` (string, required) Unique identifier for this fee. Server-generated opaque string used for reconciliation and tracking. - `fees.name` (string, required) Display name of the fee (e.g., "Delivery Fee", "Service Fee", "Bag Fee"). Use this for detailed receipt views. - `fees.fee_type` (string, required) Category of the fee. - DELIVERY: Fee for delivering the order to the customer. - SERVICE: Platform or convenience service fee. - BAG: Per-bag charge required by local regulations. - SMALL_ORDER: Surcharge applied when the cart subtotal is below the location's minimum order amount. The fee covers the shortfall. - OTHER: Fees that do not fit the above categories. Enum: "DELIVERY", "SERVICE", "BAG", "SMALL_ORDER", "OTHER" - `fees.label` (string, required) Short display label for UI rendering (e.g., "Delivery", "Service", "Bag fee"). Use this for compact summary views. - `fees.type` (string) How the fee amount was calculated. - FLAT: A fixed amount regardless of cart contents. - PERCENTAGE: Calculated as a percentage of the subtotal. Enum: "FLAT", "PERCENTAGE" - `fees.value` (string,null) For PERCENTAGE fees, the percentage as a decimal string (e.g., "5.00" for 5%). Null for FLAT fees. - `fees.amount` (object, required) The calculated fee amount in cents (always positive). For PERCENTAGE fees, this is the result of applying the percentage to the subtotal. - `fees.taxable` (boolean, required) Whether tax applies to this fee. The server decides per fee based on local tax rules. When true, this fee's amount is included in the taxable_amount on the PriceCalculation response. - `total_fees` (object) Sum of all fee amounts (locked at checkout). - `total` (object, required) Grand total: subtotal + total_tax + total_fees - total_discount. Locked at checkout. - `total_paid` (object, required) Sum of all completed payment amounts. Updated as payments reach COMPLETED status. - `balance_due` (object, required) Remaining amount to be paid (total - total_paid). Zero when the order is fully paid. - `age_verification_required` (boolean) True if any item requires age verification. When true, the consumer will be verified at pickup or delivery (offline verification). - `age_verification_notice` (string,null) Human-readable notice about age verification requirements. Null when no age-restricted items are in the order. - `estimated_ready_at` (string,null) Estimated time the order will be ready for pickup or delivery, as an ISO 8601 datetime (e.g., "2026-03-15T14:30:00-05:00"). Null when the estimate is not yet available (e.g., before the order is confirmed by the store). Updated as the order progresses -- poll the order or listen for order.status.changed webhooks to get updated estimates. - `created_at` (string, required) When the order was created (checkout time). - `updated_at` (string, required) When the order was last modified. ## Response 400 fields (application/json): - `error` (object, required) - `error.code` (string, required) Machine-readable error category. Use this field for programmatic error handling (e.g., retry on RATE_LIMIT_ERROR, re-authenticate on AUTHENTICATION_ERROR). Enum: "AUTHENTICATION_ERROR", "INVALID_REQUEST_ERROR", "RATE_LIMIT_ERROR", "NOT_FOUND_ERROR", "CONFLICT_ERROR", "INTERNAL_ERROR" - `error.message` (string, required) Human-readable error description. Safe to display to developers in logs or debugging tools. Do not display to end users. - `error.detail` (string) Additional context about the error, including suggestions for resolution. May include specific field values or limits that were exceeded. - `error.request_id` (string, required) Unique identifier for this request. Include this value when contacting Tote Developer Support for troubleshooting. - `error.field` (string,null) JSON pointer to the field that caused the error. Null if the error is not field-specific. Example: "items[0].modifier_groups[1].modifiers" - `error.change_reasons` (array) Machine-readable reasons why the resource state changed, causing the conflict. Present on checkout 409 responses when expected_total does not match the current total. Clients should re-fetch the cart and call POST /carts/{cart_id}/calculate to get the updated total before retrying checkout. Enum: "PROMO_EXPIRED", "DISCOUNT_CHANGED", "ITEM_PRICE_CHANGED", "ITEM_UNAVAILABLE", "FEE_CHANGED" ## Response 401 fields (application/json): - `error` (object, required) - `error.code` (string, required) Machine-readable error category. Use this field for programmatic error handling (e.g., retry on RATE_LIMIT_ERROR, re-authenticate on AUTHENTICATION_ERROR). Enum: "AUTHENTICATION_ERROR", "INVALID_REQUEST_ERROR", "RATE_LIMIT_ERROR", "NOT_FOUND_ERROR", "CONFLICT_ERROR", "INTERNAL_ERROR" - `error.message` (string, required) Human-readable error description. Safe to display to developers in logs or debugging tools. Do not display to end users. - `error.detail` (string) Additional context about the error, including suggestions for resolution. May include specific field values or limits that were exceeded. - `error.request_id` (string, required) Unique identifier for this request. Include this value when contacting Tote Developer Support for troubleshooting. - `error.field` (string,null) JSON pointer to the field that caused the error. Null if the error is not field-specific. Example: "items[0].modifier_groups[1].modifiers" - `error.change_reasons` (array) Machine-readable reasons why the resource state changed, causing the conflict. Present on checkout 409 responses when expected_total does not match the current total. Clients should re-fetch the cart and call POST /carts/{cart_id}/calculate to get the updated total before retrying checkout. Enum: "PROMO_EXPIRED", "DISCOUNT_CHANGED", "ITEM_PRICE_CHANGED", "ITEM_UNAVAILABLE", "FEE_CHANGED" ## Response 404 fields (application/json): - `error` (object, required) - `error.code` (string, required) Machine-readable error category. Use this field for programmatic error handling (e.g., retry on RATE_LIMIT_ERROR, re-authenticate on AUTHENTICATION_ERROR). Enum: "AUTHENTICATION_ERROR", "INVALID_REQUEST_ERROR", "RATE_LIMIT_ERROR", "NOT_FOUND_ERROR", "CONFLICT_ERROR", "INTERNAL_ERROR" - `error.message` (string, required) Human-readable error description. Safe to display to developers in logs or debugging tools. Do not display to end users. - `error.detail` (string) Additional context about the error, including suggestions for resolution. May include specific field values or limits that were exceeded. - `error.request_id` (string, required) Unique identifier for this request. Include this value when contacting Tote Developer Support for troubleshooting. - `error.field` (string,null) JSON pointer to the field that caused the error. Null if the error is not field-specific. Example: "items[0].modifier_groups[1].modifiers" - `error.change_reasons` (array) Machine-readable reasons why the resource state changed, causing the conflict. Present on checkout 409 responses when expected_total does not match the current total. Clients should re-fetch the cart and call POST /carts/{cart_id}/calculate to get the updated total before retrying checkout. Enum: "PROMO_EXPIRED", "DISCOUNT_CHANGED", "ITEM_PRICE_CHANGED", "ITEM_UNAVAILABLE", "FEE_CHANGED" ## Response 409 fields (application/json): - `error` (object, required) - `error.code` (string, required) Machine-readable error category. Use this field for programmatic error handling (e.g., retry on RATE_LIMIT_ERROR, re-authenticate on AUTHENTICATION_ERROR). Enum: "AUTHENTICATION_ERROR", "INVALID_REQUEST_ERROR", "RATE_LIMIT_ERROR", "NOT_FOUND_ERROR", "CONFLICT_ERROR", "INTERNAL_ERROR" - `error.message` (string, required) Human-readable error description. Safe to display to developers in logs or debugging tools. Do not display to end users. - `error.detail` (string) Additional context about the error, including suggestions for resolution. May include specific field values or limits that were exceeded. - `error.request_id` (string, required) Unique identifier for this request. Include this value when contacting Tote Developer Support for troubleshooting. - `error.field` (string,null) JSON pointer to the field that caused the error. Null if the error is not field-specific. Example: "items[0].modifier_groups[1].modifiers" - `error.change_reasons` (array) Machine-readable reasons why the resource state changed, causing the conflict. Present on checkout 409 responses when expected_total does not match the current total. Clients should re-fetch the cart and call POST /carts/{cart_id}/calculate to get the updated total before retrying checkout. Enum: "PROMO_EXPIRED", "DISCOUNT_CHANGED", "ITEM_PRICE_CHANGED", "ITEM_UNAVAILABLE", "FEE_CHANGED" ## Response 422 fields (application/json): - `error` (object, required) - `error.code` (string, required) Machine-readable error category. Use this field for programmatic error handling (e.g., retry on RATE_LIMIT_ERROR, re-authenticate on AUTHENTICATION_ERROR). Enum: "AUTHENTICATION_ERROR", "INVALID_REQUEST_ERROR", "RATE_LIMIT_ERROR", "NOT_FOUND_ERROR", "CONFLICT_ERROR", "INTERNAL_ERROR" - `error.message` (string, required) Human-readable error description. Safe to display to developers in logs or debugging tools. Do not display to end users. - `error.detail` (string) Additional context about the error, including suggestions for resolution. May include specific field values or limits that were exceeded. - `error.request_id` (string, required) Unique identifier for this request. Include this value when contacting Tote Developer Support for troubleshooting. - `error.field` (string,null) JSON pointer to the field that caused the error. Null if the error is not field-specific. Example: "items[0].modifier_groups[1].modifiers" - `error.change_reasons` (array) Machine-readable reasons why the resource state changed, causing the conflict. Present on checkout 409 responses when expected_total does not match the current total. Clients should re-fetch the cart and call POST /carts/{cart_id}/calculate to get the updated total before retrying checkout. Enum: "PROMO_EXPIRED", "DISCOUNT_CHANGED", "ITEM_PRICE_CHANGED", "ITEM_UNAVAILABLE", "FEE_CHANGED" ## Response 429 fields (application/json): - `error` (object, required) - `error.code` (string, required) Machine-readable error category. Use this field for programmatic error handling (e.g., retry on RATE_LIMIT_ERROR, re-authenticate on AUTHENTICATION_ERROR). Enum: "AUTHENTICATION_ERROR", "INVALID_REQUEST_ERROR", "RATE_LIMIT_ERROR", "NOT_FOUND_ERROR", "CONFLICT_ERROR", "INTERNAL_ERROR" - `error.message` (string, required) Human-readable error description. Safe to display to developers in logs or debugging tools. Do not display to end users. - `error.detail` (string) Additional context about the error, including suggestions for resolution. May include specific field values or limits that were exceeded. - `error.request_id` (string, required) Unique identifier for this request. Include this value when contacting Tote Developer Support for troubleshooting. - `error.field` (string,null) JSON pointer to the field that caused the error. Null if the error is not field-specific. Example: "items[0].modifier_groups[1].modifiers" - `error.change_reasons` (array) Machine-readable reasons why the resource state changed, causing the conflict. Present on checkout 409 responses when expected_total does not match the current total. Clients should re-fetch the cart and call POST /carts/{cart_id}/calculate to get the updated total before retrying checkout. Enum: "PROMO_EXPIRED", "DISCOUNT_CHANGED", "ITEM_PRICE_CHANGED", "ITEM_UNAVAILABLE", "FEE_CHANGED" ## Response 500 fields (application/json): - `error` (object, required) - `error.code` (string, required) Machine-readable error category. Use this field for programmatic error handling (e.g., retry on RATE_LIMIT_ERROR, re-authenticate on AUTHENTICATION_ERROR). Enum: "AUTHENTICATION_ERROR", "INVALID_REQUEST_ERROR", "RATE_LIMIT_ERROR", "NOT_FOUND_ERROR", "CONFLICT_ERROR", "INTERNAL_ERROR" - `error.message` (string, required) Human-readable error description. Safe to display to developers in logs or debugging tools. Do not display to end users. - `error.detail` (string) Additional context about the error, including suggestions for resolution. May include specific field values or limits that were exceeded. - `error.request_id` (string, required) Unique identifier for this request. Include this value when contacting Tote Developer Support for troubleshooting. - `error.field` (string,null) JSON pointer to the field that caused the error. Null if the error is not field-specific. Example: "items[0].modifier_groups[1].modifiers" - `error.change_reasons` (array) Machine-readable reasons why the resource state changed, causing the conflict. Present on checkout 409 responses when expected_total does not match the current total. Clients should re-fetch the cart and call POST /carts/{cart_id}/calculate to get the updated total before retrying checkout. Enum: "PROMO_EXPIRED", "DISCOUNT_CHANGED", "ITEM_PRICE_CHANGED", "ITEM_UNAVAILABLE", "FEE_CHANGED"