Appearance
Loyalty points, levels, and rewards
Read point balances, levels, and transaction history, or claim an earned reward. v1 implements the existing loyalty behavior locally; v2 delegates to the separate loyalty service.
Access labels such as Origin + Brand key + Customer are defined in Headers and access. Each endpoint ends in a Try it console; set the host and keys once in its Settings tab or on the overview.
Get the loyalty points leaderboard
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/user-point/leaderboard | Origin + Brand key |
GET | /api/v1/user/user-point/leaderboard | Origin + Brand key + Customer |
Request fields: no body, query, or path fields are read by this controller. Context comes from the headers/middleware above.
Example (first URL):
bash
curl -X GET "$BASE_URL/api/v1/user-point/leaderboard" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY"Response: JSON with success: true and result containing the operation’s service data.
Source: app/v1/controller/customer_controller.js:1341 → getUserPointLeaderboards; routes: routes/v1/customer_route.js:497; service: _getUserPointLeaderboards (app/v1/service/customer_service.js:2962).
Get loyalty user
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/user/loyalty/customer | Origin + Brand key + Customer |
Request fields: no body, query, or path fields are read by this controller. Context comes from the headers/middleware above.
Example:
bash
curl -X GET "$BASE_URL/api/v1/user/loyalty/customer" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: JSON with success: true and result containing the operation’s service data.
Source: app/v1/controller/loyalty_controller.js:66 → getLoyaltyUser; routes: routes/v1/loyalty_route.js:274; service: _getLoyaltyCustomer (app/v1/service/loyalty_service.js:125).
Get loyalty brand
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/user/loyalty/brand | Origin + Brand key + Customer |
Request fields: no body, query, or path fields are read by this controller. Context comes from the headers/middleware above.
Example:
bash
curl -X GET "$BASE_URL/api/v1/user/loyalty/brand" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: JSON with success: true and result containing the operation’s service data.
Source: app/v1/controller/loyalty_controller.js:256 → getLoyaltyBrand; routes: routes/v1/loyalty_route.js:264; service: _getBrandLoyalty (app/v1/service/loyalty_service.js:496).
Get loyalty product
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/brand/loyalty/:productId | Origin + Brand key |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
path.productId | number | yes | — |
Example:
bash
curl -X GET "$BASE_URL/api/v1/brand/loyalty/1" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY"Response: JSON with success: true and result containing the operation’s service data.
Source: app/v1/controller/loyalty_controller.js:39 → getLoyaltyProduct; routes: routes/v1/loyalty_route.js:29.
Get all loyalty products
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/brand/loyalty | Origin + Brand key |
Request fields: no body, query, or path fields are read by this controller. Context comes from the headers/middleware above.
Example:
bash
curl -X GET "$BASE_URL/api/v1/brand/loyalty" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY"Response: JSON with success: true and result containing the operation’s service data.
Source: app/v1/controller/loyalty_controller.js:22 → getAllLoyaltyProducts; routes: routes/v1/loyalty_route.js:39.
Get user points
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/user/loyalty/points | Origin + Brand key + Customer |
Request fields: no body, query, or path fields are read by this controller. Context comes from the headers/middleware above.
Example:
bash
curl -X GET "$BASE_URL/api/v1/user/loyalty/points" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: JSON with success: true and result containing the operation’s service data. Result fields/details: total; points_earned, total_order, and brand_level on the configured loyalty branch.
Source: app/v1/controller/loyalty_controller.js:84 → getUserPoints; routes: routes/v1/loyalty_route.js:49; service: _getLoyaltyUserPoints (app/v1/service/loyalty_service.js:250).
List loyalty point transactions
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/user/loyalty/point_transaction | Origin + Brand key + Customer |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
query.limit | number | optional | Integer; Minimum (1) |
query.offset | number | optional | Integer; Minimum (0) |
Example:
bash
curl -X GET "$BASE_URL/api/v1/user/loyalty/point_transaction?limit=10&offset=0" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: JSON with success: true and result containing the operation’s service data. Result fields/details: count, limit, offset, transactions.
Source: app/v1/controller/loyalty_controller.js:102 → getUserPointTransaction; routes: routes/v1/loyalty_route.js:254; service: _getLoyaltyUserPointTransaction (app/v1/service/loyalty_service.js:307).
List product scan transactions
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/user/loyalty/scan_transaction | Origin + Brand key + Customer |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
query.limit | number | optional | Integer; Minimum (1) |
query.offset | number | optional | Integer; Minimum (0) |
Example:
bash
curl -X GET "$BASE_URL/api/v1/user/loyalty/scan_transaction?limit=10&offset=0" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: JSON with success: true and result containing the operation’s service data. Result fields/details: count, limit, offset, transactions.
Source: app/v1/controller/loyalty_controller.js:136 → getUserScanTransaction; routes: routes/v1/loyalty_route.js:167; service: _getUserScanTransaction (app/v1/service/loyalty_service.js:815).
List scanned products or strains
| Method | URL path | Required access |
|---|---|---|
GET | /api/v1/user/loyalty/scanned_products | Origin + Brand key + Customer |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
query.limit | number | optional | Integer; Minimum (1) |
query.offset | number | optional | Integer; Minimum (0) |
query.group_by | string | optional | Whitespace trimmed; Allowed values ("strain") |
Example:
bash
curl -X GET "$BASE_URL/api/v1/user/loyalty/scanned_products?limit=10&offset=0" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: JSON with success: true and result containing the operation’s service data. Result fields/details: count, limit, offset, and products or strains according to group_by.
Source: app/v1/controller/loyalty_controller.js:170 → getUserScannedProducts; routes: routes/v1/loyalty_route.js:177; service: _getUserScannedProducts (app/v1/service/loyalty_service.js:989).
Claim a campaign step reward
| Method | URL path | Required access |
|---|---|---|
PUT | /api/v1/user/loyalty/milestone/redeem/:milestoneId/:claimed | Origin + Brand key + Customer |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
path.milestoneId | number | yes | — |
path.claimed | number | yes | — |
body.collectibles | array of number | optional | — |
milestoneId and claimed are URL parameters, despite their names: the controller passes milestoneId to _redeemCampaignReward as the campaign ID and claimed as the step's reward ID. collectibles, when used, is a top-level JSON property, not body.payload.
Example:
bash
curl -X PUT "$BASE_URL/api/v1/user/loyalty/milestone/redeem/1/1" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H 'Content-Type: application/json' \
--data-raw '{"collectibles":[1]}'Response: JSON with success: true and result containing the operation’s service data. Result fields/details: message, discountCode.
Source: app/v1/controller/loyalty_controller.js:274 → redeemMilestoneReward; routes: routes/v1/loyalty_route.js:284; service: _redeemCampaignReward (app/v1/service/loyalty_campaign_service.ts:1285).
Add loyalty points for WP loyalty
| Method | URL path | Required access |
|---|---|---|
POST | /api/v1/brand/wp-loyalty/user/points/add | Origin + Brand key |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
body.payload | object | yes | — |
body.payload.email | string | yes | Email address; Converted to lowercase; Whitespace trimmed |
body.payload.authCode | string | yes | — |
query.source | string | optional | Whitespace trimmed; Allowed values ("organic", "scan", "referral", "promotion", "shopify_plugin", "other") |
query.medium | string | optional | Whitespace trimmed; Allowed values ("ios", "android", "website", "plugin", "other") |
query.device | string | optional | Whitespace trimmed; Allowed values ("mobile", "desktop", "ipad", "tablet", "other", "laptop") |
Example:
bash
curl -X POST "$BASE_URL/api/v1/brand/wp-loyalty/user/points/add" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H 'Content-Type: application/json' \
--data-raw '{"payload":{"email":"alex@example.com","authCode":"<AUTH_CODE>"}}'Response: JSON with success: true and result containing the operation’s service data.
Source: app/v1/controller/loyalty_controller.js:351 → addLoyaltyPointsForWPLoyalty; routes: routes/v1/loyalty_route.js:118; service: _addLoyaltyPointsForWPLoyalty (app/v1/service/loyalty_service.js:688).
Create a loyalty point transaction
| Method | URL path | Required access |
|---|---|---|
POST | /api/v1/brand/loyalty/create-user-point-transaction | Origin + Brand key + Customer |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
body.payload | object | yes | Exactly one of ("points_used" , "points_earned" , "amount_spend" , "amount_earned") |
body.payload.points_used | number | optional | — |
body.payload.points_earned | number | optional | — |
body.payload.amount_spend | number | optional | — |
body.payload.amount_earned | number | optional | — |
body.payload.reason | string | yes | Whitespace trimmed |
body.payload.type | string | optional | — |
body.payload.note | string | optional | — |
body.payload.reason_id | string | optional | — |
This route registers no middleware and still receives the automatic Origin check. Its controller reads customer and tenant context that this route does not establish; a normal standalone request can fail.
Example:
bash
curl -X POST "$BASE_URL/api/v1/brand/loyalty/create-user-point-transaction" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H 'Content-Type: application/json' \
--data-raw '{"payload":{"reason":"example","points_used":1}}'Response: JSON with success: true and result containing the operation’s service data.
Source: app/v1/controller/loyalty_controller.js:414 → createUserPointTransaction; routes: routes/v1/loyalty_route.js:236; service: _createUserPointTransaction (app/v1/service/loyalty_service.js:777).
Create Tremendous reward
| Method | URL path | Required access |
|---|---|---|
POST | /api/v1/user/tremendous/reward | Origin + Brand key + Customer |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
body.payload | object | yes | — |
body.payload.rewardValue | number | yes | — |
Example:
bash
curl -X POST "$BASE_URL/api/v1/user/tremendous/reward" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN" \
-H 'Content-Type: application/json' \
--data-raw '{"payload":{"rewardValue":1}}'Response: JSON with success: true and result containing the operation’s service data.
Source: app/v1/controller/tremendous_controller.ts:6 → createTremendousReward; routes: routes/v1/tremendous_route.ts:20; service: _createTremendousReward (app/v1/service/tremendous_service.ts:7).
Get user points (v2)
| Method | URL path | Required access |
|---|---|---|
GET | /api/v2/brand/loyalty/points | Origin + Brand key + Customer |
Request fields: no body, query, or path fields are read by this controller. Context comes from the headers/middleware above.
Example:
bash
curl -X GET "$BASE_URL/api/v2/brand/loyalty/points" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: Upstream/service JSON is returned directly, without an extra envelope. The response schema belongs to the separate loyalty service; local service failures return {"success":false,"error":"..."}.
Source: app/v2/controller/loyalty_controller.ts:13 → getUserPoints; routes: routes/v2/loyalty_route.ts:38; service: _getUserPoints (app/v2/service/loyalty_service.ts:29).
Get user transactions (v2)
| Method | URL path | Required access |
|---|---|---|
GET | /api/v2/brand/loyalty/transactions | Origin + Brand key + Customer |
Request fields:
| Field | Type | Required | Rules / meaning |
|---|---|---|---|
query | object | optional | — |
query.limit | number | optional | — |
query.offset | number | optional | — |
Example:
bash
curl -X GET "$BASE_URL/api/v2/brand/loyalty/transactions?limit=10&offset=0" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: Upstream/service JSON is returned directly, without an extra envelope. The response schema belongs to the separate loyalty service; local service failures return {"success":false,"error":"..."}.
Source: app/v2/controller/loyalty_controller.ts:27 → getUserTransactions; routes: routes/v2/loyalty_route.ts:45; service: _getUserTransactions (app/v2/service/loyalty_service.ts:53).
Get brand levels (v2)
| Method | URL path | Required access |
|---|---|---|
GET | /api/v2/brand/loyalty/brand-levels | Origin + Brand key + Customer |
Request fields: no body, query, or path fields are read by this controller. Context comes from the headers/middleware above.
Example:
bash
curl -X GET "$BASE_URL/api/v2/brand/loyalty/brand-levels" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: Upstream/service JSON is returned directly, without an extra envelope. The response schema belongs to the separate loyalty service; local service failures return {"success":false,"error":"..."}.
Source: app/v2/controller/loyalty_controller.ts:56 → getBrandLevels; routes: routes/v2/loyalty_route.ts:52; service: _getBrandLevels (app/v2/service/loyalty_service.ts:86).
Init user (v2)
| Method | URL path | Required access |
|---|---|---|
POST | /api/v2/brand/loyalty/init | Origin + Brand key + Customer |
Request fields: no body, query, or path fields are read by this controller. Context comes from the headers/middleware above.
Example:
bash
curl -X POST "$BASE_URL/api/v2/brand/loyalty/init" \
-H "Origin: $ORIGIN" \
-H "api-key: $API_KEY" \
-H "Authorization: Bearer $CUSTOMER_TOKEN"Response: Upstream/service JSON is returned directly, without an extra envelope. The response schema belongs to the separate loyalty service; local service failures return {"success":false,"error":"..."}.
Source: app/v2/controller/loyalty_controller.ts:70 → initUser; routes: routes/v2/loyalty_route.ts:59; service: _initUser (app/v2/service/loyalty_service.ts:110).