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
statusispending, continue to step 2. If the customer'sstatusisblocked, they should not have access to participate in the program. If the customer'sstatusisenrolled, 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
acceptTermsAndJoinProgramButtonTextis to be used as the button text and thepolicySentence.html(or equivalent usingpolicySentence.template,privacyPolicyUrlandtermsAndConditionsUrl) is to be displayed below or above the opt-in button. Theversionof 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-idheader 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": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"type": "fixed-point",
"value": 1,
"icon": "text",
"dateStart": "2025-11-08T01:42:16.514Z",
"dateEnd": "2025-11-08T01:42:16.514Z",
"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": "123e4567-e89b-12d3-a456-426614174000",
"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": "123e4567-e89b-12d3-a456-426614174000",
"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": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"type": "fixed-point",
"value": 1,
"icon": "text",
"dateStart": "2025-11-08T01:42:16.514Z",
"dateEnd": "2025-11-08T01:42:16.514Z",
"appliesToEarningRules": [
"text"
],
"eligibleVipTiers": [
"text"
]
},
"socialPageLink": "https://example.com",
"title": "text",
"reward": {
"type": "fixed-amount",
"amount": 1
}
}
],
"redemptionRules": [
{
"redemptionRuleId": "123e4567-e89b-12d3-a456-426614174000",
"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": "123e4567-e89b-12d3-a456-426614174000"
}
}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 YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Accept: */*
{
"loyaltyCustomer": {
"email": "[email protected]",
"dateEnrolled": "2025-11-08T01:42:16.514Z",
"dateTierExpires": "2025-11-08T01:42:16.514Z",
"fullName": "text",
"avatarDynamicKey": "text",
"status": "enrolled",
"vipTierId": "123e4567-e89b-12d3-a456-426614174000",
"isTierLocked": true,
"minimumVipTierId": "123e4567-e89b-12d3-a456-426614174000",
"points": {
"balance": 1,
"dateUpdated": "2025-11-08T01:42:16.514Z",
"pending": 1,
"spent": 1
},
"referralSender": {
"referralSenderId": "123e4567-e89b-12d3-a456-426614174000",
"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 YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Content-Type: application/json
Accept: */*
Content-Length: 66
{
"enrollmentChannel": "text",
"legalPoliciesVersionAccepted": "text"
}{
"loyaltyCustomer": {
"dateEnrolled": "2025-11-08T01:42:16.514Z",
"points": {
"balance": 1,
"dateUpdated": "2025-11-08T01:42:16.514Z",
"pending": 1,
"spent": 1
},
"rewardsClaimed": 1,
"status": "enrolled",
"vipTierId": "123e4567-e89b-12d3-a456-426614174000"
}
}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 YOUR_SECRET_TOKEN
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": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"description": "text",
"type": "fixed-point",
"value": 1,
"icon": "text",
"dateStart": "2025-11-08T01:42:16.514Z",
"dateEnd": "2025-11-08T01:42:16.514Z",
"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 YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Content-Type: application/json
Accept: */*
Content-Length: 2
{}{
"pointsEarned": 1
}Updates the birthday for the given customer.
API version header
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 YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
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
enCountry code for localization
usCurrency code for localization
USDAPI 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 YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Accept: */*
{
"redemptionRules": [
{
"redemptionRuleId": "123e4567-e89b-12d3-a456-426614174000",
"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 YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Content-Type: application/json
Accept: */*
Content-Length: 166
{
"redemptionRuleId": "123e4567-e89b-12d3-a456-426614174000",
"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-11-08T01:42:16.514Z",
"pending": 1,
"spent": 1
}
}Retrieve paginated list of loyalty transactions for the authenticated customer
Maximum number of transactions to return
25Token for pagination to get the next page of results
Field and direction to order results by
date descPossible 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 YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Accept: */*
{
"transactions": [
{
"loyaltyTransactionId": "123e4567-e89b-12d3-a456-426614174000",
"amount": 1,
"notificationText": "text",
"date": "2025-11-08T01:42:16.514Z",
"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 YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Accept: */*
{
"customerSpend": 1,
"dateFrom": "2025-11-08T01:42:16.514Z"
}Loyalty x Referrals
Sends a referral request to the specified email address
API version header
The email of the person being referred to the loyalty program
The Referral Sender ID of the loyalty member. This can be found in the response from the Get Customer Details authenticated endpoint.
Successfully sent referral request.
No content
Bad Request - Unable to create referral.
POST /v1/loyalty/referrals HTTP/1.1
Host: api.okendo.io
Authorization: Bearer YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Content-Type: application/json
Accept: */*
Content-Length: 84
{
"email": "[email protected]",
"referralSenderId": "123e4567-e89b-12d3-a456-426614174000"
}No content
Retrieves the referral history for the authenticated customer
Token for pagination to get the next page of results
API version header
Referral history retrieved successfully
GET /v1/loyalty/referrals HTTP/1.1
Host: api.okendo.io
Authorization: Bearer YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Accept: */*
Referral history retrieved successfully
{
"referrals": [
{
"dateCreated": "text",
"recipient": {
"email": "[email protected]"
},
"status": "complete"
}
],
"nextUrl": "https://example.com"
}Retrieves the number of referrals by an authenticated customer
API version header
Referral count retrieved successfully
GET /v1/loyalty/referral_aggregate HTTP/1.1
Host: api.okendo.io
Authorization: Bearer YOUR_SECRET_TOKEN
okendo-api-version: 2025-02-01
Accept: */*
Referral count retrieved successfully
{
"referralsTotal": 1
}Last updated