Skip to content

Earn-and-spend flow (web) ​

Two halves. Earn: the rewards page reads campaign progress, which the server moves in reaction to scans, orders and profile events, and the customer claims a step's reward. Spend: a claimed reward is a discount, so spending it is a cart call, not a loyalty one.

Play the flow ​

1 / 6
shop.example.com/rewards
shop · rewards · scan
campaigns
Scan 3 products2 of 3 steps›
Place your first ordernot started›
500 ◉ your points balance
your rewards1 ready›

Page not designed yet — drawn from what the documented flow requires.

States ​

When a step counts as ready, why a claim is refused, and how a periodic campaign starts over, is the campaign step's lifecycle on Loyalty campaigns. The algorithm that moves progress is in campaign progress tracking.

API calls by stage ​

StageActionAPI callAccess
1Campaigns with progressGET /api/v1/user/loyalty/campaignsOrigin + Brand key + Customer
1Points balanceGET /api/v1/user/loyalty/customerOrigin + Brand key + Customer
2What did that event move?POST /api/v1/brand/user/loyalty/campaigns/almost-completed — event_item at the top of the bodyOrigin + Brand key + Customer
3One campaignGET /api/v1/brand/user/loyalty/campaigns/:idOrigin + Brand key + Customer
4Claim the stepPUT /api/v1/user/loyalty/milestone/redeem/:milestoneId/:claimed — campaign id, then the step's reward idOrigin + Brand key + Customer
5Rewards heldGET /api/v1/user/discount/rewardOrigin + Brand key + Customer
6Which apply to this bagPOST /api/v1/user/discount/applicableOrigin + Brand key + Customer
7ApplyPUT /api/v1/explicitDiscount — discounts[]Origin + Brand key + Hub selected + Customer
8OrderPOST /api/v1/user/createOrder — the same discounts[]Origin + Brand key + Hub selected + Customer

Two naming traps on the claim ​

  • The path says milestone; it claims a campaign step. :milestoneId is the campaign id and :claimed is the step's reward id. A campaign's steps are stored as its rewards[].
  • Its body skips the payload wrapper. A collectible campaign requires { "collectibles": [1, 2] } at the top level — one collectible id per step that has a collectible constraint, no duplicates. Other campaign types do not read it.

Batch platform, Shopify app and API documentation