# Validate a promo code without applying Checks if a promo code is valid for this cart without applying it. Returns a discount preview (estimated amount, description, applicable items) for valid codes, or a rejection reason and message for invalid codes. Use this endpoint to show the customer what discount they would receive before they commit to applying the code. Note: The discount preview is an estimate. The actual discount is computed when the code is applied via POST /carts/{cart_id}/promo-codes. Endpoint: GET /carts/{cart_id}/promo-codes/validate Version: 1.0.0 Security: oauth2 ## Path parameters: - `cart_id` (string, required) Unique identifier for the cart. ## Query parameters: - `code` (string, required) The promo code to validate (case-insensitive). Example: "SUMMER25" ## Response 200 fields (application/json): - `code` (string, required) The promo code, normalized to uppercase. Always returned as uppercase regardless of input casing. Example: "SUMMER25" - `valid` (boolean, required) Whether the code is valid for this cart. When true, discount_preview contains the estimated discount. When false, rejection_reason and rejection_message explain why. - `discount_preview` (object,null) Estimated discount this code would provide if applied. Present when valid is true. Null when valid is false. - `discount_preview.estimated_discount` (object) Estimated discount amount in cents. - `discount_preview.estimated_discount.amount` (integer, required) Monetary value in the smallest currency unit (cents for USD). Example: 1299 = $12.99. Example: 1299 - `discount_preview.estimated_discount.currency` (string, required) ISO 4217 currency code. Example: "USD" - `discount_preview.description` (string) Human-readable description of the discount. Example: "25% off your order (up to $10)" - `discount_preview.applicable_items` (array) Cart item IDs this discount applies to. An empty array means the discount applies to the entire cart (cart-level discount). - `rejection_reason` (string,null) Machine-readable reason why the code is invalid. Present when valid is false. Null when valid is true. - INVALID_CODE: The code does not exist or is not recognized. - EXPIRED: The code has passed its expiration date. - ALREADY_USED: The code has already been redeemed (single-use codes). - MINIMUM_NOT_MET: The cart does not meet the minimum order amount for this code. - NOT_APPLICABLE: No items in the cart are eligible for this code. - ALREADY_APPLIED: A promo code is already active on this cart. Remove it first. Enum: "INVALID_CODE", "EXPIRED", "ALREADY_USED", "MINIMUM_NOT_MET", "NOT_APPLICABLE", "ALREADY_APPLIED", null - `rejection_message` (string,null) Human-readable rejection message. Present when valid is false. Safe to display to the end user. Example: "This promo code has expired." ## 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 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"