Loyalty
Storefront REST API endpoints related to Okendo Loyalty. Both unauthenticated and after customer authentication.
Pre-Requisites
Okendo Partner ID
If you're integrating with Okendo Loyalty using these APIs, send an email to [email protected] to retrieve the value of your okendo-partner-id
header.
Terminology
Earning Rule: a way for a customer to earn points.
Redemption Rule: a way for a customer to redeem points for a reward.
Transaction: an instance of points being awarded or removed from a customer.
Recommended Usage
For anonymous customers, use the Unauthenticated endpoints to display general details about the loyalty program. Once a customer has logged into their Shopify account and you have their user token, you should call POST /stores/{subscriberId}/loyalty/login to exchange this for an Okendo Loyalty customer token (JWT).
Once you have an Okendo Loyalty customer token, you can call the customer-authenticated endpoints which will tailor the response content for that specific customer. For example some earning or redemption rules may only be available to certain customers or they will earn more points if they're on a certain VIP tier. To call these Customer Authenticated endpoints, provide your Okendo Loyalty customer token as Bearer authentication in the request header. Note: A customer that hasn’t enrolled in the loyalty program can still be logged in and shown details like their points balance and earning history. However to redeem points for rewards, be placed in a tier, and more they will need to enrol in the program.
Program Enrolment
Okendo requires each customer to explicitly enrol in the loyalty program. By using these APIs you agree to follow the following steps in compliance with our enrolment flow:
After the POST /stores/{subscriberId}/loyalty/login call, if the customer's
status
ispending
, continue to step 2. If the customer'sstatus
isblocked
, they should not have access to participate in the program. If the customer'sstatus
isenrolled
, the following steps can be skipped as the customer has already agreed to the terms during previous enrolment.Call the GET /stores/{subscriberId}/loyalty/legal_policies endpoint to retrieve the policies and legal texts of the loyalty program (both by Okendo and by the merchant).
These terms must be shown to the customer before they agree to enrol in the loyalty program. The
acceptTermsAndJoinProgramButtonText
is to be used as the button text and thepolicySentence.html
(or equivalent usingpolicySentence.template
,privacyPolicyUrl
andtermsAndConditionsUrl
) is to be displayed below or above the opt-in button. Theversion
of the terms is also provided and will be required in the next step. The following is an example of how the enrol button and terms are to be displayed.When the enrol button is clicked, call the POST /loyalty/customer_activation endpoint with the following body:
{ enrollmentChannel: <your_okendo_partner_id>, legalPoliciesVersionAccepted: <'version' field value from step 3> }
. Note: theokendo-partner-id
header will need to be set to the same value as theenrollmentChannel
.The customer is now enrolled in the loyalty program. Their sign-up points will be awarded and their initial VIP tier will be set.
Unauthenticated
The unique identifier for the store. Available on the Okendo integration settings page.
API version header
A list of earning rules
GET /v1/stores/{subscriberId}/loyalty/earning_rules HTTP/1.1
Host: api.okendo.io
okendo-api-version: 2025-02-01
Accept: */*
A list of earning rules
{
"earningRules": [
{
"earningRuleId": "123e4567-e89b-12d3-a456-426614174000",
"action": "sign-up",
"actionCategory": "account",
"actionLink": "https://example.com",
"dateComponentsToCapture": "day-month",
"icon": "text",
"imageUrl": "https://example.com",
"pointsPerText": "dollar",
"promotion": {
"promotionId": "text",
"title": "text",
"description": "text",
"type": "fixed-point",
"value": 1,
"icon": "text",
"dateStart": "2025-09-15T15:15:10.182Z",
"dateEnd": "2025-09-15T15:15:10.182Z",
"appliesToEarningRules": [
"text"
],
"eligibleVipTiers": [
"text"
]
},
"socialPageLink": "https://example.com",
"title": "text",
"reward": {
"type": "fixed-amount",
"amount": 1
}
}
]
}
The unique identifier for the store. Available on the Okendo integration settings page.
Country code for localisation
Language code for localisation
Currency code for localisation
API version header
A list of redemption rules
GET /v1/stores/{subscriberId}/loyalty/redemption_rules HTTP/1.1
Host: api.okendo.io
okendo-api-version: 2025-02-01
Accept: */*
A list of redemption rules
{
"redemptionRules": [
{
"redemptionRuleId": "text",
"title": "text",
"type": "free-product",
"icon": "text",
"imageUrl": "https://example.com",
"reward": {
"points": 1,
"product": {
"productId": "text",
"name": "text",
"imageUrl": "https://example.com",
"url": "https://example.com",
"price": "text",
"currencyCode": "text"
},
"variants": [
{
"variantRemoteId": "text",
"title": "text",
"price": "text",
"currencyCode": "text"
}
]
},
"appliesToCollections": [
{
"collectionId": "text",
"title": "text",
"url": "https://example.com"
}
],
"expiresAfterDays": 1,
"minimumPurchase": 1,
"purchaseType": "single",
"recurringCycleLimit": 1
}
],
"localisation": {
"currency": {
"code": "text",
"exchangeRate": 1
}
}
}
The unique identifier for the store. Available on the Okendo integration settings page.
API version header
The VIP program details
GET /v1/stores/{subscriberId}/loyalty/vip_program HTTP/1.1
Host: api.okendo.io
okendo-api-version: 2025-02-01
Accept: */*
The VIP program details
{
"vipProgram": {
"vipTiers": [
{
"vipTierId": "text",
"name": "text",
"entryRequirement": {
"spend": 1
},
"style": {
"badge": {
"type": "framed",
"icon": "text",
"color": "text",
"frame": {
"type": "bronze"
},
"svgUrl": "https://example.com"
}
},
"customPerks": [
"text"
],
"earningRules": [
{
"earningRuleId": "123e4567-e89b-12d3-a456-426614174000",
"action": "sign-up",
"actionCategory": "account",
"actionLink": "https://example.com",
"dateComponentsToCapture": "day-month",
"icon": "text",
"imageUrl": "https://example.com",
"pointsPerText": "dollar",
"promotion": {
"promotionId": "text",
"title": "text",
"description": "text",
"type": "fixed-point",
"value": 1,
"icon": "text",
"dateStart": "2025-09-15T15:15:10.182Z",
"dateEnd": "2025-09-15T15:15:10.182Z",
"appliesToEarningRules": [
"text"
],
"eligibleVipTiers": [
"text"
]
},
"socialPageLink": "https://example.com",
"title": "text",
"reward": {
"type": "fixed-amount",
"amount": 1
}
}
],
"redemptionRules": [
{
"redemptionRuleId": "text",
"title": "text",
"type": "free-product",
"icon": "text",
"imageUrl": "https://example.com",
"reward": {
"points": 1,
"product": {
"productId": "text",
"name": "text",
"imageUrl": "https://example.com",
"url": "https://example.com",
"price": "text",
"currencyCode": "text"
},
"variants": [
{
"variantRemoteId": "text",
"title": "text",
"price": "text",
"currencyCode": "text"
}
]
},
"appliesToCollections": [
{
"collectionId": "text",
"title": "text",
"url": "https://example.com"
}
],
"expiresAfterDays": 1,
"minimumPurchase": 1,
"purchaseType": "single",
"recurringCycleLimit": 1
}
]
}
]
}
}
The unique identifier for the store. Available on the Okendo integration settings page.
API version header
A list of FAQ items
GET /v1/stores/{subscriberId}/loyalty/faq HTTP/1.1
Host: api.okendo.io
okendo-api-version: 2025-02-01
Accept: */*
A list of FAQ items
{
"faqItems": [
{
"question": "text",
"answer": "text"
}
]
}
Retrieve legal policies information including terms and conditions, privacy policy URLs, and policy text templates for the loyalty program
The unique identifier for the store. Available on the Okendo integration settings page.
API version header
Legal policies information
GET /v1/stores/{subscriberId}/loyalty/legal_policies HTTP/1.1
Host: api.okendo.io
okendo-api-version: 2025-02-01
Accept: */*
Legal policies information
{
"acceptTermsAndJoinProgramButtonText": "Join & Agree",
"policySentence": {
"template": "By joining you agree to our {{ termsAndConditions }} and {{ privacyPolicy }}.",
"html": "By joining you agree to our <a href=\"https://okendo.io/terms-conditions\" target=\"_blank\">Terms and Conditions</a> and <a href=\"https://okendo.io/privacy-policy\" target=\"_blank\">Privacy Policy</a>."
},
"privacyPolicyUrl": "https://okendo.io/privacy-policy",
"termsAndConditionsUrl": "https://okendo.io/terms-conditions",
"version": "1.0.0"
}
The unique identifier for the store. Available on the Okendo integration settings page.
API version header
Login successful
POST /v1/stores/{subscriberId}/loyalty/login HTTP/1.1
Host: api.okendo.io
okendo-api-version: 2025-02-01
Content-Type: application/json
Accept: */*
Content-Length: 30
{
"customerAccessToken": "text"
}
Login successful
{
"jwt": "text",
"loyaltyCustomerDetails": {
"balance": 1,
"status": "enrolled",
"vipTierId": "text"
}
}
Customer Authenticated
Retrieve detailed information about the authenticated loyalty customer
API version header
Customer details retrieved successfully
Unauthorized - Invalid or missing authentication token
Customer not found
Conflict - Unable to load customer data
GET /v1/loyalty/customer_details HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
okendo-api-version: 2025-02-01
Accept: */*
{
"loyaltyCustomer": {
"email": "[email protected]",
"dateEnrolled": "2025-09-15T15:15:10.182Z",
"dateTierExpires": "2025-09-15T15:15:10.182Z",
"fullName": "text",
"avatarDynamicKey": "text",
"status": "enrolled",
"vipTierId": "text",
"isTierLocked": true,
"minimumVipTierId": "text",
"points": {
"balance": 1,
"dateUpdated": "2025-09-15T15:15:10.182Z",
"pending": 1,
"spent": 1
},
"referralSender": {
"referralSenderId": "text",
"shareableLinkUrl": "https://example.com"
},
"rewardsClaimed": 1,
"birthday": {
"day": 1,
"month": 1,
"year": 1
}
}
}
Enrol a customer into the loyalty program
API version header
The channel through which the customer is enrolling into the loyalty program
Version of legal policies accepted by the customer. To fetch the legal policies to display and their version, call the GET /stores/{subscriberId}/loyalty/legal_policies
endpoint.
Customer activated successfully
Bad Request - Invalid customer identifier or subscriber ID
Unauthorized - Invalid or missing authentication token
Forbidden - Customer blocked, loyalty feature missing, or access denied
Not Found - Loyalty customer not found
Internal Server Error - Failed to activate customer
POST /v1/loyalty/customer_activation HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
okendo-api-version: 2025-02-01
Content-Type: application/json
Accept: */*
Content-Length: 66
{
"enrollmentChannel": "text",
"legalPoliciesVersionAccepted": "text"
}
{
"loyaltyCustomer": {
"dateEnrolled": "2025-09-15T15:15:10.182Z",
"points": {
"balance": 1,
"dateUpdated": "2025-09-15T15:15:10.182Z",
"pending": 1,
"spent": 1
},
"rewardsClaimed": 1,
"status": "enrolled",
"vipTierId": "text"
}
}
Retrieve earning rules for the authenticated customer, including completion status
API version header
Earning rules retrieved successfully
Unauthorized - Invalid or missing authentication token
Customer or subscriber not found
GET /v1/loyalty/earning_rules HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
okendo-api-version: 2025-02-01
Accept: */*
{
"earningRules": [
{
"earningRuleId": "123e4567-e89b-12d3-a456-426614174000",
"action": "sign-up",
"actionCategory": "account",
"actionLink": "https://example.com",
"dateComponentsToCapture": "day-month",
"icon": "text",
"imageUrl": "https://example.com",
"pointsPerText": "dollar",
"promotion": {
"promotionId": "text",
"title": "text",
"description": "text",
"type": "fixed-point",
"value": 1,
"icon": "text",
"dateStart": "2025-09-15T15:15:10.182Z",
"dateEnd": "2025-09-15T15:15:10.182Z",
"appliesToEarningRules": [
"text"
],
"eligibleVipTiers": [
"text"
]
},
"socialPageLink": "https://example.com",
"title": "text",
"reward": {
"type": "fixed-amount",
"amount": 1
},
"isCompleted": true
}
]
}
Trigger a social earning rule to earn points for the authenticated customer
The unique identifier for the earning rule to trigger
API version header
Earning rule triggered successfully
Bad request - Invalid earning rule or customer
Unauthorized - Invalid or missing authentication token
Forbidden - Customer not enrolled or invalid earning rule type
Earning rule not found or inactive
POST /v1/loyalty/earning_rules/{earningRuleId}/trigger HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
okendo-api-version: 2025-02-01
Content-Type: application/json
Accept: */*
Content-Length: 2
{}
{
"pointsEarned": 1
}
Updates the birthday for the given customer.
The day of the month, from 1 to 31.
The month of the year, from 1 to 12.
Successfully updated customer birthday.
No content
Bad Request - Invalid birthday provided.
Not Found - Customer or subscriber not found.
PUT /v1/loyalty/customer_birthday HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
Content-Type: application/json
Accept: */*
Content-Length: 19
{
"day": 1,
"month": 1
}
No content
Retrieve redemption rules for the authenticated customer with localization support
Language code for localization
en
Country code for localization
us
Currency code for localization
USD
API version header
Redemption rules retrieved successfully
Unauthorized - Invalid or missing authentication token
Customer or subscriber not found
GET /v1/loyalty/redemption_rules HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
okendo-api-version: 2025-02-01
Accept: */*
{
"redemptionRules": [
{
"redemptionRuleId": "text",
"title": "text",
"type": "free-product",
"icon": "text",
"imageUrl": "https://example.com",
"reward": {
"points": 1,
"product": {
"productId": "text",
"name": "text",
"imageUrl": "https://example.com",
"url": "https://example.com",
"price": "text",
"currencyCode": "text"
},
"variants": [
{
"variantRemoteId": "text",
"title": "text",
"price": "text",
"currencyCode": "text"
}
]
},
"appliesToCollections": [
{
"collectionId": "text",
"title": "text",
"url": "https://example.com"
}
],
"expiresAfterDays": 1,
"minimumPurchase": 1,
"purchaseType": "single",
"recurringCycleLimit": 1
}
],
"localisation": {
"currency": {
"code": "USD",
"exchangeRate": 1
}
}
}
Redeem loyalty points for rewards using a redemption rule
API version header
The unique identifier of the redemption rule to use
Points redeemed successfully
Bad request - Invalid redemption rule or request
Unauthorized - Invalid or missing authentication token
Forbidden - Customer not enrolled, insufficient points, or ineligible for rule
Customer not found
Unprocessable entity - Currency exchange mismatch
POST /v1/loyalty/redemptions HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
okendo-api-version: 2025-02-01
Content-Type: application/json
Accept: */*
Content-Length: 134
{
"redemptionRuleId": "text",
"variableValue": {
"points": 1,
"value": 1
},
"localisation": {
"currencyCode": "USD",
"clientValue": 1,
"locale": "en"
}
}
{
"reward": {
"rewardType": "coupon",
"result": {
"success": true,
"data": {
"code": "text"
}
}
},
"customerPoints": {
"balance": 1,
"dateUpdated": "2025-09-15T15:15:10.182Z",
"pending": 1,
"spent": 1
}
}
Retrieve paginated list of loyalty transactions for the authenticated customer
Maximum number of transactions to return
25
Token for pagination to get the next page of results
Field and direction to order results by
date desc
Possible values: API version header
Loyalty transactions retrieved successfully
Unauthorized - Invalid or missing authentication token
GET /v1/loyalty/transactions HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
okendo-api-version: 2025-02-01
Accept: */*
{
"transactions": [
{
"loyaltyTransactionId": "text",
"amount": 1,
"notificationText": "text",
"date": "2025-09-15T15:15:10.182Z",
"status": "complete",
"type": "earn",
"bonusPoints": 1
}
],
"nextUrl": "https://example.com"
}
Retrieve the customer's spending amount within the current VIP tier eligibility period
API version header
Customer spend retrieved successfully
Unauthorized - Invalid or missing authentication token
Forbidden - Loyalty program not launched or customer not enrolled
Customer not found
GET /v1/loyalty/customer_spend HTTP/1.1
Host: api.okendo.io
Authorization: Bearer JWT
okendo-api-version: 2025-02-01
Accept: */*
{
"customerSpend": 1,
"dateFrom": "2025-09-15T15:15:10.182Z"
}
Last updated