App API
Checkouts and redemptions
Find out which rewards and codes apply to a cart, then hold one while the guest pays. The hold becomes final when you send the paid order.
Available at launch
The flow is preview, redeem, pay, order. The Checkout and orders guide walks through it with retries and timeouts. Every endpoint can also return the common errors listed on Errors.
The examples on this page follow the order from the guide. Maya Lopez has 420 Beans. On Thursday, November 5 at 8:06 am in Austin she orders pickup at South Congress in the brand's app: an oat latte ($5.75), a drip coffee ($3.25) and a butter croissant ($3.50). She has a "Fall pastry on us" offer in her wallet and types WELCOME10.
Reason codes#
Every not_applicable entry has one reason. The message is written for guests and filled in with the real numbers, so you can show it without mapping codes yourself. Use reason when you want your own wording or logic. The list may grow, so handle a reason you don't know by showing the message.
reason | Why it doesn't apply | Example message |
|---|---|---|
below_minimum_subtotal | Subtotal is under rules.min_subtotal_cents. | Add $2.50 more to use this reward. |
wrong_channel | The reward or code doesn't work on this channel. | This reward works in the app only. |
wrong_location | Not valid at this location. | This reward isn't available at Riverside. |
wrong_fulfillment | Not valid for this fulfillment. | This code works on pickup orders only. |
outside_available_times | Outside every available_times window, in the location's time zone. | This code works 7 to 11 am. |
item_not_in_cart | No cart line matches the reward's items or categories. | Add a pastry to use this reward. |
tier_required | The member's tier isn't in rules.tier_ids. | This reward is for Gold members. |
not_enough_points | The member can't afford points_cost. | You need 80 more Beans for this reward. |
per_member_limit_reached | The member has used this offer as many times as it allows. | You've already used this offer. |
budget_exhausted | The offer has reached its total budget. | This offer is no longer available. |
not_started | Before starts_at. | This code starts Nov 10. |
expired | After ends_at, or the wallet item expired. | This code expired Oct 31. |
already_used | A unique code or wallet item was already used. | This code has already been used. |
Redemption statuses#
| From | To | When |
|---|---|---|
| (new) | reserved | POST /v1/redemptions succeeds. |
reserved | captured | An order that lists it in redemption_ids is credited. Points are spent; the wallet item or code is used. |
reserved | canceled | You call cancel. Everything held is released. |
reserved | expired | 15 minutes pass with no order. Everything held is released. |
captured | reversed | The order is fully refunded. Points spent come back, and an unexpired wallet item or unique code returns to the member. A partial refund keeps the redemption captured. |
canceled, expired and reversed are final. A reward.redeemed webhook fires on capture.