# Calculate cart prices Returns an itemized price breakdown for the cart without creating or modifying an order. This is a read-only preview -- it computes prices at request time based on the current menu, tax configuration, and applicable discounts. Important: Prices may change between calculate and checkout if the menu or tax configuration is updated. Always call calculate immediately before checkout to show the customer the most accurate total. This endpoint is analogous to Square's CalculateOrder and Toast's /prices endpoint. Endpoint: POST /carts/{cart_id}/calculate Version: 1.0.0 Security: oauth2 ## Path parameters: - `cart_id` (string, required) Unique identifier for the cart. ## Response 200 fields (application/json): - `cart_id` (string, required) - `currency` (string, required) ISO 4217 currency code. - `line_items` (array, required) Price breakdown for each cart item. - `line_items.cart_item_id` (string, required) Reference to the cart item. - `line_items.menu_item_id` (string, required) Reference to the menu item. - `line_items.name` (string, required) Display name of the item. - `line_items.quantity` (integer, required) - `line_items.base_price` (object, required) Base price per unit. - `line_items.base_price.amount` (integer, required) Monetary value in the smallest currency unit (cents for USD). Example: 1299 = $12.99. Example: 1299 - `line_items.modifier_total` (object, required) Total modifier cost per unit. - `line_items.discounts` (array) Item-level discounts applied to this line item. - `line_items.discounts.id` (string, required) Unique identifier for this discount. Server-generated opaque string for reconciliation and tracking. - `line_items.discounts.name` (string, required) Display name of the discount (e.g., "10% Off First Order", "$2 Off Subs"). - `line_items.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" - `line_items.discounts.value` (string,null) For PERCENTAGE discounts, the percentage value as a decimal string (e.g., "10.00" for 10%). Null for FIXED discounts. - `line_items.discounts.amount` (object, required) The calculated discount amount deducted (always positive, in cents). - `line_items.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" - `line_items.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" - `line_items.item_subtotal` (object, required) Subtotal for this line: (base_price + modifier_total) * quantity - item-level discounts. Item-level discounts are already deducted here, so the cart-level total_discount on PriceCalculation does not include them. - `line_items.item_tax` (object, required) Tax amount for this line item. - `line_items.item_total` (object, required) Total for this line item including tax: item_subtotal + item_tax. - `discounts` (array) Cart-level discounts applied to the order. Item-level discounts appear on each line item in the line_items array, not here. Each discount is listed as a separate line item with name, type, source, and amount deducted. - `promo_codes` (array) Promo codes active on the cart. Their discounts appear in the discounts array with source: PROMO_CODE. - `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. - `member_pricing_applied` (boolean) Whether member-specific pricing was applied during this calculation. True when the cart has a customer_id and the server found matching member pricing rules. False when the cart is anonymous or when the customer_id has no associated member pricing. Use this field to show customers whether they are receiving member prices (e.g., "Member pricing applied" badge in your UI). - `fees` (array) Fees applied to this order (delivery, service, bag, small order surcharge). Each fee is a separate line item. Display all fees to the customer. - `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. - `subtotal` (object, required) Sum of all line item subtotals (before tax, after item-level discounts). - `total_tax` (object, required) Total tax for the entire cart. - `total_discount` (object, required) Sum of cart-level discount amounts. Item-level discounts are already deducted from each line item's item_subtotal and are NOT included in this field. This avoids double-counting. - `total_fees` (object, required) Sum of all fee amounts. Included in the total formula. - `taxable_amount` (object) The amount on which tax was computed. Equals subtotal minus any pre-tax cart-level discounts plus taxable fee amounts. Exposed for transparency so partners can verify tax calculations independently. - `total` (object, required) Grand total: subtotal + total_tax + total_fees - total_discount. - `age_verification_required` (boolean) True if any item in the cart requires age verification. This is informational -- the consumer will be verified at pickup or delivery. - `calculated_at` (string, required) When this calculation was performed. Prices are computed at request time and may change if the menu or tax configuration is updated. Always call calculate immediately before checkout for the most accurate total. ## 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 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"