Search Documentation

Search for a documentation page...

Loyalty API

REST API endpoints for configuring a points-based loyalty program, tiers, and bonus campaigns.

YNS loyalty is a points-based rewards program with three building blocks: settings (how points are earned and redeemed), tiers (membership levels reached by lifetime points, each with its own earning multiplier), and campaigns (time-boxed bonus multipliers scoped to specific products, categories, or collections). Settings and socials live in the store's JSON config, while tiers and campaigns are first-class records.

Get Loyalty Settings

GET /api/v1/loyalty/settings

Returns the store's loyalty config: points rate, redemption rules, and expiry. The loyalty field is null when the program has never been configured.

curl \
-H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/loyalty/settings

Response (200)

{
"loyalty": {
"pointsPerUnit": 1,
"redemptionRate": 100,
"minRedemption": 100,
"maxRedeemPercent": 50,
"pointsExpiryMonths": null
}
}

Update Loyalty Settings

PUT /api/v1/loyalty/settings

Replaces the loyalty config wholesale.

Request Body

FieldTypeDefaultDescription
pointsPerUnitnumber1Points earned per currency unit spent (positive)
redemptionRatenumber100Points required to redeem one currency unit (positive)
minRedemptionnumber100Minimum points a customer must hold to redeem (positive)
maxRedeemPercentnumber50Maximum share of an order payable with points, 1-100 (positive)
pointsExpiryMonthsnumber | nullnullMonths until earned points expire (null = never)
curl -X PUT \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"pointsPerUnit": 1, "redemptionRate": 100, "minRedemption": 100, "maxRedeemPercent": 50, "pointsExpiryMonths": 12}' \
https://your-store.yns.store/api/v1/loyalty/settings

Response (200)

{
"loyalty": {
"pointsPerUnit": 1,
"redemptionRate": 100,
"minRedemption": 100,
"maxRedeemPercent": 50,
"pointsExpiryMonths": 12
}
}

List Loyalty Tiers

GET /api/v1/loyalty/tiers

Returns loyalty tiers. Members reach a tier once their lifetime points exceed its threshold.

Query Parameters

ParameterTypeDefaultDescription
limitnumber50Tiers per page (1-100)
offsetnumber0Tiers to skip
curl \
-H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/loyalty/tiers

Response (200)

{
"data": [
{
"id": "0191abc0-1234-7def-8000-000000000001",
"name": "Gold",
"threshold": 1000,
"multiplier": 1.5,
"color": "#FFD700",
"sortOrder": 2,
"createdAt": "2024-06-15T10:30:00.000Z",
"updatedAt": "2024-06-15T10:30:00.000Z"
}
],
"meta": {
"count": 1
}
}

Create Loyalty Tier

POST /api/v1/loyalty/tiers

Creates a tier. Members reach it once their lifetime points exceed the threshold, after which they earn points at the tier's multiplier.

Request Body

FieldTypeRequiredDescription
namestringYesTier name, e.g. Gold
thresholdnumberYesLifetime points required to reach this tier (integer ≥ 0)
multipliernumberYesPoints-earning multiplier for members in this tier (positive, e.g. 1.5)
colorstringYesBadge color hex, e.g. #FFD700 (must match #RRGGBB)
sortOrdernumberNoDisplay order (integer ≥ 0, default: 0)
curl -X POST \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Gold", "threshold": 1000, "multiplier": 1.5, "color": "#FFD700", "sortOrder": 2}' \
https://your-store.yns.store/api/v1/loyalty/tiers

Response (201)

{
"id": "0191abc0-1234-7def-8000-000000000001",
"name": "Gold",
"threshold": 1000,
"multiplier": 1.5,
"color": "#FFD700",
"sortOrder": 2,
"createdAt": "2024-06-15T10:30:00.000Z",
"updatedAt": "2024-06-15T10:30:00.000Z"
}

Get Loyalty Tier

GET /api/v1/loyalty/tiers/{id}

Returns a single loyalty tier by UUID. Returns 404 if no tier matches.


Update Loyalty Tier

PATCH /api/v1/loyalty/tiers/{id}

Partially updates a loyalty tier. Send only the fields you want to change — all fields accept the same types and constraints as Create Loyalty Tier.

curl -X PATCH \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"threshold": 1500}' \
https://your-store.yns.store/api/v1/loyalty/tiers/0191abc0-1234-7def-8000-000000000001

Response (200)

Returns the updated tier.


Delete Loyalty Tier

DELETE /api/v1/loyalty/tiers/{id}

Deletes a loyalty tier by UUID. At least one tier must always remain — deleting the last tier returns 409.

curl -X DELETE \
-H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/loyalty/tiers/0191abc0-1234-7def-8000-000000000001

Response (200)

{
"ok": true,
"deleted": 1
}

Last Tier (409)

{
"error": "Cannot delete the last remaining tier"
}

List Loyalty Campaigns

GET /api/v1/loyalty/campaigns

Returns loyalty bonus campaigns — time-boxed multipliers that boost points earned on specific products, categories, or collections.

Query Parameters

ParameterTypeDefaultDescription
limitnumber50Campaigns per page (1-100)
offsetnumber0Campaigns to skip
activeOnlybooleanReturn only active campaigns
curl \
-H "Authorization: Bearer your_api_key" \
"https://your-store.yns.store/api/v1/loyalty/campaigns?activeOnly=true"

Response (200)

{
"data": [
{
"id": "0191abc0-1234-7def-8000-000000000010",
"name": "Double Points Weekend",
"earnMultiplier": 2,
"scope": "ALL_PRODUCTS",
"scopeIds": [],
"startsAt": "2024-06-15T00:00:00.000Z",
"endsAt": "2024-06-17T00:00:00.000Z",
"active": true,
"createdAt": "2024-06-14T09:00:00.000Z",
"updatedAt": "2024-06-14T09:00:00.000Z"
}
],
"meta": {
"count": 1
}
}

Create Loyalty Campaign

POST /api/v1/loyalty/campaigns

Creates a bonus points-earning campaign. earnMultiplier boosts points earned, scope (with scopeIds) targets what it applies to, and startsAt/endsAt bound the active window.

Request Body

FieldTypeRequiredDescription
namestringYesCampaign name
earnMultipliernumberYesPoints-earning multiplier during the campaign (positive, e.g. 2 = 2×)
scopestringYesOne of ALL_PRODUCTS, PRODUCT_IDS, CATEGORY_IDS, COLLECTION_IDS
scopeIdsstring[]ConditionalProduct/category/collection UUIDs — required unless scope is ALL_PRODUCTS
startsAtstring | nullNoISO 8601 start (null = active immediately)
endsAtstring | nullNoISO 8601 end (null = no end). Must be after startsAt
activebooleanNoWhether the campaign is active (default: true)
curl -X POST \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Double Points Weekend", "earnMultiplier": 2, "scope": "ALL_PRODUCTS", "startsAt": "2024-06-15T00:00:00.000Z", "endsAt": "2024-06-17T00:00:00.000Z"}' \
https://your-store.yns.store/api/v1/loyalty/campaigns
# Scoped to specific collections
curl -X POST \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "3× on New Arrivals", "earnMultiplier": 3, "scope": "COLLECTION_IDS", "scopeIds": ["0191abc0-0000-7000-8000-000000000200"]}' \
https://your-store.yns.store/api/v1/loyalty/campaigns

Response (201)

{
"id": "0191abc0-1234-7def-8000-000000000010",
"name": "Double Points Weekend",
"earnMultiplier": 2,
"scope": "ALL_PRODUCTS",
"scopeIds": [],
"startsAt": "2024-06-15T00:00:00.000Z",
"endsAt": "2024-06-17T00:00:00.000Z",
"active": true,
"createdAt": "2024-06-14T09:00:00.000Z",
"updatedAt": "2024-06-14T09:00:00.000Z"
}

Get Loyalty Campaign

GET /api/v1/loyalty/campaigns/{id}

Returns a single loyalty campaign by UUID. Returns 404 if no campaign matches.


Update Loyalty Campaign

PATCH /api/v1/loyalty/campaigns/{id}

Partially updates a loyalty campaign. Fields accept the same types and constraints as Create Loyalty Campaign. The same cross-field guards apply: scopeIds is required when changing scope to anything other than ALL_PRODUCTS, and endsAt must be after startsAt.

curl -X PATCH \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"active": false}' \
https://your-store.yns.store/api/v1/loyalty/campaigns/0191abc0-1234-7def-8000-000000000010

Response (200)

Returns the updated campaign.


Delete Loyalty Campaign

DELETE /api/v1/loyalty/campaigns/{id}

Deletes a loyalty campaign by UUID.

curl -X DELETE \
-H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/loyalty/campaigns/0191abc0-1234-7def-8000-000000000010

Response (200)

{
"ok": true,
"deleted": 1
}