# Loyalty

## Pre-Requisites

### Okendo Partner ID

If you're integrating with Okendo Loyalty using these APIs, send an email to <solutions@okendo.io> 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](#unauthenticated "mention") 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](#post-stores-subscriberid-loyalty-login "mention") 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](#customer-authenticated "mention") 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:

1. After the [#post-stores-subscriberid-loyalty-login](#post-stores-subscriberid-loyalty-login "mention") call, if the customer's `status` is `pending`, continue to step 2. If the customer's `status` is `blocked`, they should not have access to participate in the program. If the customer's `status` is `enrolled`, the following steps can be skipped as the customer has already agreed to the terms during previous enrolment.
2. Call the [#get-stores-subscriberid-loyalty-legal\_policies](#get-stores-subscriberid-loyalty-legal_policies "mention") endpoint to retrieve the policies and legal texts of the loyalty program (both by Okendo and by the merchant).
3. 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 the `policySentence.html` (or equivalent using `policySentence.template`, `privacyPolicyUrl` and `termsAndConditionsUrl`) is to be displayed below or above the opt-in button. The `version` 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.

   <figure><img src="/files/oYlDGMY0nMTO0XvD1hv9" alt="" width="322"><figcaption></figcaption></figure>
4. When the enrol button is clicked, call the [#post-loyalty-customer\_activation](#post-loyalty-customer_activation "mention") endpoint with the following body: `{ enrollmentChannel: <your_okendo_partner_id>, legalPoliciesVersionAccepted: <'version' field value from step 3> }`. *Note*: the `okendo-partner-id` header will need to be set to the same value as the `enrollmentChannel`.
5. 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

## GET /stores/{subscriberId}/loyalty/earning\_rules

> Get Earning Rules

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"paths":{"/stores/{subscriberId}/loyalty/earning_rules":{"get":{"summary":"Get Earning Rules","tags":["loyalty"],"parameters":[{"name":"subscriberId","in":"path","required":true,"schema":{"type":"string"},"description":"The unique identifier for the store. Available on the Okendo integration settings page."},{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of earning rules","content":{"application/json":{"schema":{"type":"object","properties":{"earningRules":{"type":"array","items":{"type":"object","properties":{"earningRuleId":{"type":"string","format":"uuid","description":"Unique identifier for the earning rule"},"action":{"type":"string","enum":["sign-up","anniversary","birthday","custom-fixed","custom-points-per","purchase","answer-question","referral-invite","submit-review","facebook-like","facebook-share","instagram-follow","tiktok-follow","twitter-follow","twitter-post","submit-survey"],"description":"The specific action that triggers this earning rule"},"actionCategory":{"type":"string","enum":["account","custom","order","profile-question","referral","review","social","survey"],"description":"The category of action for this earning rule"},"actionLink":{"type":"string","format":"uri","description":"URL link for custom actions"},"dateComponentsToCapture":{"type":"string","enum":["day-month","day-month-year"],"description":"The parts of the date to capture in order to complete this rule (valid on birthday action only)"},"icon":{"description":"Icon for the earning rule - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"imageUrl":{"type":"string","format":"uri","description":"Image URL for the earning rule"},"pointsPerText":{"type":"string","description":"Text description for points-per rewards. In the format 'x points per {pointsPerText}'"},"promotion":{"description":"Associated promotion details if applicable","type":"object","properties":{"promotionId":{"type":"string","format":"uuid","description":"Unique identifier for the promotion"},"title":{"type":"string","description":"Display title for the promotion"},"description":{"type":"string","description":"Description of the promotion"},"type":{"type":"string","enum":["fixed-point","point-multiplier"],"description":"Type of promotion - fixed-point adds a fixed number of points, point-multiplier multiplies earned points"},"value":{"type":"number","description":"The promotion value - either fixed points to add or multiplier factor"},"icon":{"description":"Icon for the promotion - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"dateStart":{"type":"string","format":"date-time","description":"ISO date-time string when the promotion starts"},"dateEnd":{"type":"string","format":"date-time","description":"ISO date-time string when the promotion ends (optional for ongoing promotions)"},"appliesToEarningRules":{"type":"array","items":{"type":"string"},"description":"Array of earning rule IDs that this promotion applies to","minItems":1},"eligibleVipTiers":{"type":"array","items":{"type":"string"},"description":"Array of VIP tier IDs that are eligible for this promotion (optional - if not specified, applies to all tiers)"}},"required":["promotionId","title","description","type","value","icon","dateStart","appliesToEarningRules"]},"socialPageLink":{"type":"string","format":"uri","description":"Social media page link for social actions"},"title":{"type":"string","description":"Display title for the earning rule"},"reward":{"type":"object","required":["type"],"discriminator":{"propertyName":"type","mapping":{"fixed-amount":"./fixed-amount-reward.yaml","points-per":"./points-per-reward.yaml","points-per-spend":"./points-per-spend-reward.yaml","submit-review":"./submit-review-reward.yaml"}},"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["fixed-amount"]},"amount":{"type":"integer","minimum":1,"description":"Number of points awarded"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["points-per"]},"amount":{"type":"number","minimum":0.01,"description":"Points awarded per unit"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["points-per-spend"]},"amount":{"type":"number","minimum":0.01,"description":"Points awarded per currency unit spent"},"waitTimeDays":{"type":"integer","minimum":0,"description":"Waiting period in days before points are awarded"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["submit-review"]},"amountForReview":{"type":"integer","minimum":0,"description":"Points awarded for submitting a review"},"amountForSocialLogin":{"type":"integer","minimum":0,"description":"Points awarded for social login during review"},"amountForImage":{"type":"integer","minimum":0,"description":"Points awarded for including an image in review"},"amountForVideo":{"type":"integer","minimum":0,"description":"Points awarded for including a video in review"},"capPerOrder":{"type":"integer","minimum":0,"description":"Maximum points that can be earned per order"},"earnEachAmountOncePer":{"type":"string","enum":["order","review"],"description":"Whether each amount can be earned once per order or per review"}},"required":["type","amountForReview","amountForSocialLogin","amountForImage","amountForVideo","capPerOrder","earnEachAmountOncePer"]}],"description":"Reward configuration for this earning rule"}},"required":["earningRuleId","action","actionCategory","icon","title","reward"]}}}}}}}}}}}}
```

## GET /stores/{subscriberId}/loyalty/redemption\_rules

> Get Redemption Rules

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"paths":{"/stores/{subscriberId}/loyalty/redemption_rules":{"get":{"summary":"Get Redemption Rules","tags":["loyalty"],"parameters":[{"name":"subscriberId","in":"path","required":true,"schema":{"type":"string"},"description":"The unique identifier for the store. Available on the Okendo integration settings page."},{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string"},"description":"Country code for localisation"},{"name":"languageCode","in":"query","required":false,"schema":{"type":"string"},"description":"Language code for localisation"},{"name":"currencyCode","in":"query","required":false,"schema":{"type":"string"},"description":"Currency code for localisation"}],"responses":{"200":{"description":"A list of redemption rules","content":{"application/json":{"schema":{"type":"object","properties":{"redemptionRules":{"type":"array","items":{"type":"object","properties":{"redemptionRuleId":{"type":"string","format":"uuid","description":"Unique identifier for the redemption rule"},"title":{"type":"string","description":"Display title for the redemption rule"},"type":{"type":"string","enum":["free-product","free-shipping","fixed-value","percentage-coupon","variable-value"],"description":"Type of redemption rule"},"icon":{"description":"Icon for the redemption rule - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"imageUrl":{"type":"string","format":"uri","description":"Image URL for the redemption rule"},"reward":{"oneOf":[{"type":"object","description":"Free product reward","properties":{"points":{"type":"integer"},"product":{"type":"object","properties":{"productId":{"type":"string"},"name":{"type":"string"},"imageUrl":{"type":"string","format":"uri"},"url":{"type":"string","format":"uri"},"price":{"type":"string"},"currencyCode":{"type":"string"}},"required":["productId","name"]},"variants":{"type":"array","items":{"type":"object","properties":{"variantRemoteId":{"type":"string"},"title":{"type":"string"},"price":{"type":"string"},"currencyCode":{"type":"string"}},"required":["variantRemoteId","title"]}}},"required":["points","product"]},{"type":"object","description":"A redemption for a percentage-off coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"}},"required":["points","value"]},{"type":"object","description":"A fixed-value redemption for store credit or a coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"},"awardVia":{"type":"string","enum":["store-credit","coupon"]},"localised":{"type":"object","properties":{"value":{"type":"number"},"formattedValue":{"type":"string"}},"required":["value","formattedValue"]}},"required":["points","value"]},{"type":"object","description":"A variable-value redemption for store credit or a coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"},"awardVia":{"type":"string","enum":["store-credit","coupon"]},"minimumPoints":{"type":"number"},"maximumPoints":{"type":"number"},"localised":{"type":"object","properties":{"value":{"type":"number"},"formattedValue":{"type":"string"}},"required":["value","formattedValue"]}},"required":["points","value"]},{"type":"object","description":"Free shipping reward","properties":{"points":{"type":"integer"},"maximumShipping":{"type":"number"}},"required":["points"]}]},"appliesToCollections":{"type":"array","items":{"type":"object","properties":{"collectionId":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["collectionId","title"]},"description":"Collections this reward coupon will apply to"},"expiresAfterDays":{"type":"integer","description":"Number of days after which the reward expires"},"minimumPurchase":{"type":"number","description":"Minimum purchase amount required for the reward coupon to be valid in cart"},"purchaseType":{"type":"string","enum":["single","subscription","both"],"description":"Type of purchase that the reward coupon will apply to"},"recurringCycleLimit":{"type":"integer","description":"The number of recurring payments that the reward coupon will apply to for subscription purchases"}},"required":["redemptionRuleId","title","type","icon","reward"]}},"localisation":{"type":"object","description":"Optional localisation information for currency conversion","properties":{"currency":{"type":"object","properties":{"code":{"type":"string","description":"Currency code for localised values"},"exchangeRate":{"type":"number","description":"Exchange rate used for currency conversion"}},"required":["code","exchangeRate"]}},"required":["currency"]}},"required":["redemptionRules"]}}}}}}}}}
```

## GET /stores/{subscriberId}/loyalty/vip\_program

> Get VIP Program

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"paths":{"/stores/{subscriberId}/loyalty/vip_program":{"get":{"summary":"Get VIP Program","tags":["loyalty"],"parameters":[{"name":"subscriberId","in":"path","required":true,"schema":{"type":"string"},"description":"The unique identifier for the store. Available on the Okendo integration settings page."},{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The VIP program details","content":{"application/json":{"schema":{"type":"object","properties":{"vipProgram":{"type":"object","properties":{"vipTiers":{"type":"array","items":{"type":"object","properties":{"vipTierId":{"type":"string","format":"uuid"},"name":{"type":"string"},"entryRequirement":{"type":"object","properties":{"spend":{"type":"integer"}},"required":["spend"]},"style":{"type":"object","properties":{"badge":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["framed"]},"icon":{"type":"string","description":"FontAwesome icon name"},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"HexColorCode"},"frame":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["bronze","silver","gold","diamond","platinum"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["custom"]},"style":{"type":"object","properties":{"backgroundColor":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"HexColorCode"},"borderColor":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"HexColorCode"},"shineEffect":{"type":"boolean"}},"required":["backgroundColor","borderColor","shineEffect"]}},"required":["type","style"]}]},"svgUrl":{"type":"string","format":"uri"}},"required":["type","icon","color","frame","svgUrl"]},{"type":"object","properties":{"type":{"type":"string","enum":["uploaded"]},"url":{"type":"string","format":"uri"},"width":{"type":"integer","minimum":1},"height":{"type":"integer","minimum":1}},"required":["type","url","width","height"]}]}},"required":["badge"]},"customPerks":{"type":"array","description":"Legacy custom perks represented as simple strings","items":{"type":"string"}},"structuredCustomPerks":{"type":"array","description":"Structured custom perks with full details including name, value type, value, and icon.","items":{"type":"object","properties":{"name":{"type":"string"},"valueType":{"type":"string","enum":["text","is-included"]},"value":{"oneOf":[{"type":"string"},{"type":"boolean","enum":[true]}]},"icon":{"oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Uploaded image","properties":{"url":{"type":"string","format":"uri"},"width":{"type":"integer","minimum":1},"height":{"type":"integer","minimum":1}},"required":["url","width","height"]}]}},"required":["name","valueType","value","icon"]}},"earningRules":{"type":"array","items":{"type":"object","properties":{"earningRuleId":{"type":"string","format":"uuid","description":"Unique identifier for the earning rule"},"action":{"type":"string","enum":["sign-up","anniversary","birthday","custom-fixed","custom-points-per","purchase","answer-question","referral-invite","submit-review","facebook-like","facebook-share","instagram-follow","tiktok-follow","twitter-follow","twitter-post","submit-survey"],"description":"The specific action that triggers this earning rule"},"actionCategory":{"type":"string","enum":["account","custom","order","profile-question","referral","review","social","survey"],"description":"The category of action for this earning rule"},"actionLink":{"type":"string","format":"uri","description":"URL link for custom actions"},"dateComponentsToCapture":{"type":"string","enum":["day-month","day-month-year"],"description":"The parts of the date to capture in order to complete this rule (valid on birthday action only)"},"icon":{"description":"Icon for the earning rule - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"imageUrl":{"type":"string","format":"uri","description":"Image URL for the earning rule"},"pointsPerText":{"type":"string","description":"Text description for points-per rewards. In the format 'x points per {pointsPerText}'"},"promotion":{"description":"Associated promotion details if applicable","type":"object","properties":{"promotionId":{"type":"string","format":"uuid","description":"Unique identifier for the promotion"},"title":{"type":"string","description":"Display title for the promotion"},"description":{"type":"string","description":"Description of the promotion"},"type":{"type":"string","enum":["fixed-point","point-multiplier"],"description":"Type of promotion - fixed-point adds a fixed number of points, point-multiplier multiplies earned points"},"value":{"type":"number","description":"The promotion value - either fixed points to add or multiplier factor"},"icon":{"description":"Icon for the promotion - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"dateStart":{"type":"string","format":"date-time","description":"ISO date-time string when the promotion starts"},"dateEnd":{"type":"string","format":"date-time","description":"ISO date-time string when the promotion ends (optional for ongoing promotions)"},"appliesToEarningRules":{"type":"array","items":{"type":"string"},"description":"Array of earning rule IDs that this promotion applies to","minItems":1},"eligibleVipTiers":{"type":"array","items":{"type":"string"},"description":"Array of VIP tier IDs that are eligible for this promotion (optional - if not specified, applies to all tiers)"}},"required":["promotionId","title","description","type","value","icon","dateStart","appliesToEarningRules"]},"socialPageLink":{"type":"string","format":"uri","description":"Social media page link for social actions"},"title":{"type":"string","description":"Display title for the earning rule"},"reward":{"type":"object","required":["type"],"discriminator":{"propertyName":"type","mapping":{"fixed-amount":"./fixed-amount-reward.yaml","points-per":"./points-per-reward.yaml","points-per-spend":"./points-per-spend-reward.yaml","submit-review":"./submit-review-reward.yaml"}},"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["fixed-amount"]},"amount":{"type":"integer","minimum":1,"description":"Number of points awarded"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["points-per"]},"amount":{"type":"number","minimum":0.01,"description":"Points awarded per unit"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["points-per-spend"]},"amount":{"type":"number","minimum":0.01,"description":"Points awarded per currency unit spent"},"waitTimeDays":{"type":"integer","minimum":0,"description":"Waiting period in days before points are awarded"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["submit-review"]},"amountForReview":{"type":"integer","minimum":0,"description":"Points awarded for submitting a review"},"amountForSocialLogin":{"type":"integer","minimum":0,"description":"Points awarded for social login during review"},"amountForImage":{"type":"integer","minimum":0,"description":"Points awarded for including an image in review"},"amountForVideo":{"type":"integer","minimum":0,"description":"Points awarded for including a video in review"},"capPerOrder":{"type":"integer","minimum":0,"description":"Maximum points that can be earned per order"},"earnEachAmountOncePer":{"type":"string","enum":["order","review"],"description":"Whether each amount can be earned once per order or per review"}},"required":["type","amountForReview","amountForSocialLogin","amountForImage","amountForVideo","capPerOrder","earnEachAmountOncePer"]}],"description":"Reward configuration for this earning rule"}},"required":["earningRuleId","action","actionCategory","icon","title","reward"]}},"redemptionRules":{"type":"array","items":{"type":"object","properties":{"redemptionRuleId":{"type":"string","format":"uuid","description":"Unique identifier for the redemption rule"},"title":{"type":"string","description":"Display title for the redemption rule"},"type":{"type":"string","enum":["free-product","free-shipping","fixed-value","percentage-coupon","variable-value"],"description":"Type of redemption rule"},"icon":{"description":"Icon for the redemption rule - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"imageUrl":{"type":"string","format":"uri","description":"Image URL for the redemption rule"},"reward":{"oneOf":[{"type":"object","description":"Free product reward","properties":{"points":{"type":"integer"},"product":{"type":"object","properties":{"productId":{"type":"string"},"name":{"type":"string"},"imageUrl":{"type":"string","format":"uri"},"url":{"type":"string","format":"uri"},"price":{"type":"string"},"currencyCode":{"type":"string"}},"required":["productId","name"]},"variants":{"type":"array","items":{"type":"object","properties":{"variantRemoteId":{"type":"string"},"title":{"type":"string"},"price":{"type":"string"},"currencyCode":{"type":"string"}},"required":["variantRemoteId","title"]}}},"required":["points","product"]},{"type":"object","description":"A redemption for a percentage-off coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"}},"required":["points","value"]},{"type":"object","description":"A fixed-value redemption for store credit or a coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"},"awardVia":{"type":"string","enum":["store-credit","coupon"]},"localised":{"type":"object","properties":{"value":{"type":"number"},"formattedValue":{"type":"string"}},"required":["value","formattedValue"]}},"required":["points","value"]},{"type":"object","description":"A variable-value redemption for store credit or a coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"},"awardVia":{"type":"string","enum":["store-credit","coupon"]},"minimumPoints":{"type":"number"},"maximumPoints":{"type":"number"},"localised":{"type":"object","properties":{"value":{"type":"number"},"formattedValue":{"type":"string"}},"required":["value","formattedValue"]}},"required":["points","value"]},{"type":"object","description":"Free shipping reward","properties":{"points":{"type":"integer"},"maximumShipping":{"type":"number"}},"required":["points"]}]},"appliesToCollections":{"type":"array","items":{"type":"object","properties":{"collectionId":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["collectionId","title"]},"description":"Collections this reward coupon will apply to"},"expiresAfterDays":{"type":"integer","description":"Number of days after which the reward expires"},"minimumPurchase":{"type":"number","description":"Minimum purchase amount required for the reward coupon to be valid in cart"},"purchaseType":{"type":"string","enum":["single","subscription","both"],"description":"Type of purchase that the reward coupon will apply to"},"recurringCycleLimit":{"type":"integer","description":"The number of recurring payments that the reward coupon will apply to for subscription purchases"}},"required":["redemptionRuleId","title","type","icon","reward"]}}},"required":["vipTierId","name","entryRequirement","style"]}}}}}}}}}}}}}}
```

## GET /stores/{subscriberId}/loyalty/faq

> Get FAQ

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"paths":{"/stores/{subscriberId}/loyalty/faq":{"get":{"summary":"Get FAQ","tags":["loyalty"],"parameters":[{"name":"subscriberId","in":"path","required":true,"schema":{"type":"string"},"description":"The unique identifier for the store. Available on the Okendo integration settings page."},{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"A list of FAQ items","content":{"application/json":{"schema":{"type":"object","properties":{"faqItems":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}}}}}}}}}}}}}}
```

## Get Legal Policies

> Retrieve legal policies information including terms and conditions, privacy policy URLs, and policy text templates for the loyalty program

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"paths":{"/stores/{subscriberId}/loyalty/legal_policies":{"get":{"summary":"Get Legal Policies","description":"Retrieve legal policies information including terms and conditions, privacy policy URLs, and policy text templates for the loyalty program","tags":["loyalty"],"parameters":[{"name":"subscriberId","in":"path","required":true,"schema":{"type":"string"},"description":"The unique identifier for the store. Available on the Okendo integration settings page."},{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Legal policies information","content":{"application/json":{"schema":{"type":"object","properties":{"acceptTermsAndJoinProgramButtonText":{"type":"string","description":"Text to display on the button for accepting terms and joining the program"},"policySentence":{"type":"object","description":"Policy sentence with template and HTML versions","properties":{"template":{"type":"string","description":"Template version of the policy sentence with placeholders"},"html":{"type":"string","description":"HTML version of the policy sentence with actual links"}},"required":["template","html"]},"privacyPolicyUrl":{"type":"string","format":"uri","description":"URL to the privacy policy"},"termsAndConditionsUrl":{"type":"string","format":"uri","description":"URL to the terms and conditions"},"version":{"type":"string","description":"Version of the legal policies"}},"required":["acceptTermsAndJoinProgramButtonText","policySentence","privacyPolicyUrl","termsAndConditionsUrl","version"]}}}}}}}}}
```

## POST /stores/{subscriberId}/loyalty/login

> Login

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"paths":{"/stores/{subscriberId}/loyalty/login":{"post":{"summary":"Login","tags":["loyalty"],"parameters":[{"name":"subscriberId","in":"path","required":true,"schema":{"type":"string"},"description":"The unique identifier for the store. Available on the Okendo integration settings page."},{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"customerAccessToken":{"type":"string"}}},{"type":"object","properties":{"storefrontAccessToken":{"type":"string","description":"The Shopify Storefront API access token that was used to generate the `storefrontCustomerAccessToken`. Created via the [storefrontAccessTokenCreate mutation](https://shopify.dev/docs/api/admin-graphql/latest/mutations/storefrontAccessTokenCreate) or another equivalent method."},"storefrontCustomerAccessToken":{"type":"string","description":"A customer access token retrieved via the Shopify Storefront API using the [customerAccessTokenCreate mutation](https://shopify.dev/docs/api/storefront/latest/mutations/customeraccesstokencreate) or another equivalent method."}},"required":["storefrontAccessToken","storefrontCustomerAccessToken"]}]}}}},"responses":{"200":{"description":"Login successful","content":{"application/json":{"schema":{"type":"object","properties":{"jwt":{"type":"string","description":"A session token for this customer. Provide this in calls to our customer-authenticated endpoints to get responses tailored to this customer."},"loyaltyCustomerDetails":{"type":"object","properties":{"balance":{"type":"integer","description":"The customer's points balance"},"status":{"type":"string","enum":["enrolled","pending","blocked"],"description":"The customer's loyalty program status"},"vipTierId":{"type":"string","format":"uuid","description":"The customer's VIP Tier identifier"}},"required":["balance","status"]}}}}}}}}}}}
```

## Customer Authenticated

## Get Customer Details

> Retrieve detailed information about the authenticated loyalty customer

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/customer_details":{"get":{"summary":"Get Customer Details","tags":["loyalty"],"description":"Retrieve detailed information about the authenticated loyalty customer","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Customer details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"loyaltyCustomer":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Customer's email address"},"dateEnrolled":{"type":"string","format":"date-time","description":"Date when customer enrolled in loyalty program"},"dateTierExpires":{"type":"string","format":"date-time","description":"Date when current VIP tier expires"},"fullName":{"type":"string","description":"Customer's full name"},"avatarDynamicKey":{"type":"string","description":"Dynamic key for customer avatar image"},"status":{"type":"string","enum":["enrolled","pending","blocked"],"description":"The customer's loyalty program status"},"vipTierId":{"type":"string","format":"uuid","description":"The customer's VIP Tier identifier"},"isTierLocked":{"type":"boolean","description":"Whether the customer's tier is locked"},"minimumVipTierId":{"type":"string","format":"uuid","description":"The customer's minimum VIP Tier identifier. The customer cannot be moved below this tier."},"points":{"type":"object","properties":{"balance":{"type":"integer","description":"The customer's points balance"},"dateUpdated":{"type":"string","format":"date-time","description":"Date when points were last updated"},"pending":{"type":"integer","description":"Points that are pending a cool-off period"},"spent":{"type":"integer","description":"Total points spent by customer"}},"required":["balance","dateUpdated","pending","spent"]},"referralSender":{"type":"object","properties":{"referralSenderId":{"type":"string","format":"uuid","description":"Referral sender identifier"},"shareableLinkUrl":{"type":"string","format":"uri","description":"Shareable referral link URL"}},"required":["referralSenderId","shareableLinkUrl"]},"rewardsClaimed":{"type":"number","description":"Number of rewards claimed by customer"},"birthday":{"type":"object","properties":{"day":{"type":"integer","minimum":1,"maximum":31,"description":"Day of birth"},"month":{"type":"integer","minimum":1,"maximum":12,"description":"Month of birth"},"year":{"type":"integer","minimum":1900,"maximum":2025,"description":"Year of birth"}},"required":["day","month"]}},"required":["points","rewardsClaimed","status"]}},"required":["loyaltyCustomer"]}}}},"401":{"description":"Unauthorized - Invalid or missing authentication token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"404":{"description":"Customer not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"409":{"description":"Conflict - Unable to load customer data","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Activate (Enrol) Loyalty Customer

> Enrol a customer into the loyalty program

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/customer_activation":{"post":{"summary":"Activate (Enrol) Loyalty Customer","tags":["loyalty"],"description":"Enrol a customer into the loyalty program","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enrollmentChannel":{"type":"string","description":"The channel through which the customer is enrolling into the loyalty program"},"legalPoliciesVersionAccepted":{"type":"string","description":"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."}},"required":["enrollmentChannel","legalPoliciesVersionAccepted"]}}}},"responses":{"200":{"description":"Customer activated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"loyaltyCustomer":{"type":"object","properties":{"dateEnrolled":{"type":"string","format":"date-time","description":"Date when customer enrolled in loyalty program"},"points":{"type":"object","properties":{"balance":{"type":"integer","description":"The customer's points balance"},"dateUpdated":{"type":"string","format":"date-time","description":"Date when points were last updated"},"pending":{"type":"integer","description":"Points that are pending a cool-off period"},"spent":{"type":"integer","description":"Total points spent by customer"}},"required":["balance","dateUpdated","pending","spent"]},"rewardsClaimed":{"type":"number","description":"Number of rewards claimed by customer"},"status":{"type":"string","enum":["enrolled","pending","blocked"],"description":"The customer's loyalty program status"},"vipTierId":{"type":"string","format":"uuid","description":"The customer's VIP Tier identifier"}},"required":["dateEnrolled","points","rewardsClaimed","status","vipTierId"]}},"required":["loyaltyCustomer"]}}}},"400":{"description":"Bad Request - Invalid customer identifier or subscriber ID","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"401":{"description":"Unauthorized - Invalid or missing authentication token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"403":{"description":"Forbidden - Customer blocked, loyalty feature missing, or access denied","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"404":{"description":"Not Found - Loyalty customer not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"500":{"description":"Internal Server Error - Failed to activate customer","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Get Earning Rules For Customer

> Retrieve earning rules for the authenticated customer, including completion status

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/earning_rules":{"get":{"summary":"Get Earning Rules For Customer","tags":["loyalty"],"description":"Retrieve earning rules for the authenticated customer, including completion status","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Earning rules retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"earningRules":{"type":"array","items":{"allOf":[{"type":"object","properties":{"earningRuleId":{"type":"string","format":"uuid","description":"Unique identifier for the earning rule"},"action":{"type":"string","enum":["sign-up","anniversary","birthday","custom-fixed","custom-points-per","purchase","answer-question","referral-invite","submit-review","facebook-like","facebook-share","instagram-follow","tiktok-follow","twitter-follow","twitter-post","submit-survey"],"description":"The specific action that triggers this earning rule"},"actionCategory":{"type":"string","enum":["account","custom","order","profile-question","referral","review","social","survey"],"description":"The category of action for this earning rule"},"actionLink":{"type":"string","format":"uri","description":"URL link for custom actions"},"dateComponentsToCapture":{"type":"string","enum":["day-month","day-month-year"],"description":"The parts of the date to capture in order to complete this rule (valid on birthday action only)"},"icon":{"description":"Icon for the earning rule - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"imageUrl":{"type":"string","format":"uri","description":"Image URL for the earning rule"},"pointsPerText":{"type":"string","description":"Text description for points-per rewards. In the format 'x points per {pointsPerText}'"},"promotion":{"description":"Associated promotion details if applicable","type":"object","properties":{"promotionId":{"type":"string","format":"uuid","description":"Unique identifier for the promotion"},"title":{"type":"string","description":"Display title for the promotion"},"description":{"type":"string","description":"Description of the promotion"},"type":{"type":"string","enum":["fixed-point","point-multiplier"],"description":"Type of promotion - fixed-point adds a fixed number of points, point-multiplier multiplies earned points"},"value":{"type":"number","description":"The promotion value - either fixed points to add or multiplier factor"},"icon":{"description":"Icon for the promotion - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"dateStart":{"type":"string","format":"date-time","description":"ISO date-time string when the promotion starts"},"dateEnd":{"type":"string","format":"date-time","description":"ISO date-time string when the promotion ends (optional for ongoing promotions)"},"appliesToEarningRules":{"type":"array","items":{"type":"string"},"description":"Array of earning rule IDs that this promotion applies to","minItems":1},"eligibleVipTiers":{"type":"array","items":{"type":"string"},"description":"Array of VIP tier IDs that are eligible for this promotion (optional - if not specified, applies to all tiers)"}},"required":["promotionId","title","description","type","value","icon","dateStart","appliesToEarningRules"]},"socialPageLink":{"type":"string","format":"uri","description":"Social media page link for social actions"},"title":{"type":"string","description":"Display title for the earning rule"},"reward":{"type":"object","required":["type"],"discriminator":{"propertyName":"type","mapping":{"fixed-amount":"./fixed-amount-reward.yaml","points-per":"./points-per-reward.yaml","points-per-spend":"./points-per-spend-reward.yaml","submit-review":"./submit-review-reward.yaml"}},"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["fixed-amount"]},"amount":{"type":"integer","minimum":1,"description":"Number of points awarded"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["points-per"]},"amount":{"type":"number","minimum":0.01,"description":"Points awarded per unit"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["points-per-spend"]},"amount":{"type":"number","minimum":0.01,"description":"Points awarded per currency unit spent"},"waitTimeDays":{"type":"integer","minimum":0,"description":"Waiting period in days before points are awarded"}},"required":["type","amount"]},{"type":"object","properties":{"type":{"type":"string","enum":["submit-review"]},"amountForReview":{"type":"integer","minimum":0,"description":"Points awarded for submitting a review"},"amountForSocialLogin":{"type":"integer","minimum":0,"description":"Points awarded for social login during review"},"amountForImage":{"type":"integer","minimum":0,"description":"Points awarded for including an image in review"},"amountForVideo":{"type":"integer","minimum":0,"description":"Points awarded for including a video in review"},"capPerOrder":{"type":"integer","minimum":0,"description":"Maximum points that can be earned per order"},"earnEachAmountOncePer":{"type":"string","enum":["order","review"],"description":"Whether each amount can be earned once per order or per review"}},"required":["type","amountForReview","amountForSocialLogin","amountForImage","amountForVideo","capPerOrder","earnEachAmountOncePer"]}],"description":"Reward configuration for this earning rule"}},"required":["earningRuleId","action","actionCategory","icon","title","reward"]},{"type":"object","properties":{"isCompleted":{"type":"boolean","description":"Whether the customer has completed this earning rule"}},"required":["isCompleted"]}]},"description":"List of earning rules with completion status for the authenticated customer"}},"required":["earningRules"]}}}},"401":{"description":"Unauthorized - Invalid or missing authentication token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"404":{"description":"Customer or subscriber not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Trigger Social Earning Rule

> Trigger a social earning rule to earn points for the authenticated customer

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/earning_rules/{earningRuleId}/trigger":{"post":{"summary":"Trigger Social Earning Rule","tags":["loyalty"],"description":"Trigger a social earning rule to earn points for the authenticated customer","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}},{"name":"earningRuleId","in":"path","required":true,"schema":{"type":"string"},"description":"The unique identifier for the earning rule to trigger"}],"requestBody":{"description":"Empty request body","content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Earning rule triggered successfully","content":{"application/json":{"schema":{"type":"object","properties":{"pointsEarned":{"type":"integer","description":"Number of points earned by triggering the earning rule"}},"required":["pointsEarned"]}}}},"400":{"description":"Bad request - Invalid earning rule or customer","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"401":{"description":"Unauthorized - Invalid or missing authentication token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"403":{"description":"Forbidden - Customer not enrolled or invalid earning rule type","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"404":{"description":"Earning rule not found or inactive","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Update Customer Birthday

> Updates the birthday for the given customer.

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/customer_birthday":{"put":{"summary":"Update Customer Birthday","tags":["loyalty"],"description":"Updates the birthday for the given customer.","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"day":{"type":"integer","minimum":1,"maximum":31,"description":"The day of the month, from 1 to 31."},"month":{"type":"integer","minimum":1,"maximum":12,"description":"The month of the year, from 1 to 12."}},"required":["day","month"]}}}},"responses":{"204":{"description":"Successfully updated customer birthday."},"400":{"description":"Bad Request - Invalid birthday provided.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"404":{"description":"Not Found - Customer or subscriber not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Get Redemption Rules For Customer

> Retrieve redemption rules for the authenticated customer with localization support

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/redemption_rules":{"get":{"summary":"Get Redemption Rules For Customer","tags":["loyalty"],"description":"Retrieve redemption rules for the authenticated customer with localization support","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}},{"name":"languageCode","in":"query","required":false,"schema":{"type":"string"},"description":"Language code for localization"},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string"},"description":"Country code for localization"},{"name":"currencyCode","in":"query","required":false,"schema":{"type":"string"},"description":"Currency code for localization"}],"responses":{"200":{"description":"Redemption rules retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"redemptionRules":{"type":"array","items":{"type":"object","properties":{"redemptionRuleId":{"type":"string","format":"uuid","description":"Unique identifier for the redemption rule"},"title":{"type":"string","description":"Display title for the redemption rule"},"type":{"type":"string","enum":["free-product","free-shipping","fixed-value","percentage-coupon","variable-value"],"description":"Type of redemption rule"},"icon":{"description":"Icon for the redemption rule - either a FontAwesome icon name or custom image","oneOf":[{"type":"string","description":"FontAwesome icon name"},{"type":"object","description":"Icon object with URL and dimensions","properties":{"url":{"type":"string","format":"uri","description":"URL of the custom icon image"},"width":{"type":"integer","minimum":1,"description":"Width of the icon image in pixels"},"height":{"type":"integer","minimum":1,"description":"Height of the icon image in pixels"}},"required":["url","width","height"]}]},"imageUrl":{"type":"string","format":"uri","description":"Image URL for the redemption rule"},"reward":{"oneOf":[{"type":"object","description":"Free product reward","properties":{"points":{"type":"integer"},"product":{"type":"object","properties":{"productId":{"type":"string"},"name":{"type":"string"},"imageUrl":{"type":"string","format":"uri"},"url":{"type":"string","format":"uri"},"price":{"type":"string"},"currencyCode":{"type":"string"}},"required":["productId","name"]},"variants":{"type":"array","items":{"type":"object","properties":{"variantRemoteId":{"type":"string"},"title":{"type":"string"},"price":{"type":"string"},"currencyCode":{"type":"string"}},"required":["variantRemoteId","title"]}}},"required":["points","product"]},{"type":"object","description":"A redemption for a percentage-off coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"}},"required":["points","value"]},{"type":"object","description":"A fixed-value redemption for store credit or a coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"},"awardVia":{"type":"string","enum":["store-credit","coupon"]},"localised":{"type":"object","properties":{"value":{"type":"number"},"formattedValue":{"type":"string"}},"required":["value","formattedValue"]}},"required":["points","value"]},{"type":"object","description":"A variable-value redemption for store credit or a coupon","properties":{"points":{"type":"integer"},"value":{"type":"number"},"awardVia":{"type":"string","enum":["store-credit","coupon"]},"minimumPoints":{"type":"number"},"maximumPoints":{"type":"number"},"localised":{"type":"object","properties":{"value":{"type":"number"},"formattedValue":{"type":"string"}},"required":["value","formattedValue"]}},"required":["points","value"]},{"type":"object","description":"Free shipping reward","properties":{"points":{"type":"integer"},"maximumShipping":{"type":"number"}},"required":["points"]}]},"appliesToCollections":{"type":"array","items":{"type":"object","properties":{"collectionId":{"type":"string"},"title":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["collectionId","title"]},"description":"Collections this reward coupon will apply to"},"expiresAfterDays":{"type":"integer","description":"Number of days after which the reward expires"},"minimumPurchase":{"type":"number","description":"Minimum purchase amount required for the reward coupon to be valid in cart"},"purchaseType":{"type":"string","enum":["single","subscription","both"],"description":"Type of purchase that the reward coupon will apply to"},"recurringCycleLimit":{"type":"integer","description":"The number of recurring payments that the reward coupon will apply to for subscription purchases"}},"required":["redemptionRuleId","title","type","icon","reward"]},"description":"List of redemption rules available to the authenticated customer"},"localisation":{"type":"object","description":"Localization information including currency details","properties":{"currency":{"type":"object","properties":{"code":{"type":"string","description":"Three letter currency code"},"exchangeRate":{"type":"number","description":"Exchange rate for currency conversion"}},"required":["code","exchangeRate"]}},"required":["currency"]}},"required":["redemptionRules"]}}}},"401":{"description":"Unauthorized - Invalid or missing authentication token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"404":{"description":"Customer or subscriber not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Redeem Points

> Redeem loyalty points for rewards using a redemption rule

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/redemptions":{"post":{"summary":"Redeem Points","tags":["loyalty"],"description":"Redeem loyalty points for rewards using a redemption rule","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Redemption request details","content":{"application/json":{"schema":{"type":"object","properties":{"redemptionRuleId":{"type":"string","format":"uuid","description":"The unique identifier of the redemption rule to use"},"variableValue":{"type":"object","description":"Variable value selected by the customer for redemption rules that support variable amounts. Required for variable value redemptions. Ignored for other redemption types.","properties":{"points":{"type":"integer","description":"The number of points to redeem"},"value":{"type":"number","description":"The value of the reward in currency"}}},"localisation":{"type":"object","description":"Localization settings for the redemption","properties":{"currencyCode":{"type":"string","description":"Currency code used to generate the localized client value"},"clientValue":{"type":"number","description":"The value of the reward in the localized currency"},"locale":{"type":"string","description":"Locale for localization"}},"required":["currencyCode","clientValue"]}},"required":["redemptionRuleId"]}}}},"responses":{"200":{"description":"Points redeemed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"reward":{"type":"object","properties":{"rewardType":{"type":"string","enum":["coupon","store-credit"],"description":"Type of reward received"},"result":{"description":"Result of the redemption operation - either success with reward data or failure with error details","oneOf":[{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"oneOf":[{"type":"object","properties":{"code":{"type":"string","description":"Coupon code"}},"required":["code"]},{"type":"object","properties":{"currencyCode":{"type":"string","description":"Currency code for the store credit"},"storeCreditTransactionAmount":{"type":"string","description":"Amount of store credit awarded in this transaction"},"balanceAmount":{"type":"string","description":"Total store credit balance after this transaction"}},"required":["currencyCode","storeCreditTransactionAmount","balanceAmount"]}]}},"required":["success","data"]},{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["shopify-error","timeout-error"],"description":"Error code indicating the type of failure"},"message":{"type":"string","description":"Human-readable error message"}},"required":["code"]}},"required":["success","error"]}]}},"required":["rewardType","result"]},"customerPoints":{"type":"object","properties":{"balance":{"type":"number","description":"Customer's updated points balance after redemption"},"dateUpdated":{"type":"string","format":"date-time","description":"Date when points were last updated"},"pending":{"type":"number","description":"Points that are pending approval"},"spent":{"type":"number","description":"Total points spent by customer (including this redemption)"}},"required":["balance","dateUpdated","pending","spent"]}},"required":["reward","customerPoints"]}}}},"400":{"description":"Bad request - Invalid redemption rule or request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"401":{"description":"Unauthorized - Invalid or missing authentication token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"403":{"description":"Forbidden - Customer not enrolled, insufficient points, or ineligible for rule","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"404":{"description":"Customer not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"422":{"description":"Unprocessable entity - Currency exchange mismatch","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Get Loyalty Transactions

> Retrieve paginated list of loyalty transactions for the authenticated customer

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/transactions":{"get":{"summary":"Get Loyalty Transactions","tags":["loyalty"],"description":"Retrieve paginated list of loyalty transactions for the authenticated customer","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"description":"Maximum number of transactions to return"},{"name":"lastEvaluated","in":"query","required":false,"schema":{"type":"string"},"description":"Token for pagination to get the next page of results"},{"name":"orderBy","in":"query","required":false,"schema":{"type":"string","enum":["date desc"],"default":"date desc"},"description":"Field and direction to order results by"}],"responses":{"200":{"description":"Loyalty transactions retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"transactions":{"type":"array","items":{"type":"object","properties":{"loyaltyTransactionId":{"type":"string","format":"uuid","description":"Unique identifier for the loyalty transaction"},"amount":{"type":"integer","description":"Points amount for the transaction (positive for earning, negative for redemption)"},"notificationText":{"type":"string","description":"Human-readable text describing the transaction"},"date":{"type":"string","format":"date-time","description":"Date and time when the transaction occurred"},"status":{"type":"string","enum":["complete","pending","declined"],"description":"Current status of the transaction"},"type":{"type":"string","enum":["earn","redeem","adjustment"],"description":"Type of transaction"},"bonusPoints":{"type":"integer","description":"Additional bonus points earned from promotions (only present for earn transactions)"}},"required":["loyaltyTransactionId","amount","date","status","type"]},"description":"List of loyalty transactions for the customer"},"nextUrl":{"type":"string","format":"uri","description":"URL for the next page of results"}},"required":["transactions"]}}}},"401":{"description":"Unauthorized - Invalid or missing authentication token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Get Customer Spend

> Retrieve the customer's spending amount within the current VIP tier eligibility period

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/customer_spend":{"get":{"summary":"Get Customer Spend","tags":["loyalty"],"description":"Retrieve the customer's spending amount within the current VIP tier eligibility period","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Customer spend retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"customerSpend":{"type":"number","description":"Total amount spent by the customer in the current VIP tier eligibility period"},"dateFrom":{"type":"string","format":"date-time","description":"Start date of the spending period (ISO 8601 format)"}},"required":["customerSpend","dateFrom"]}}}},"401":{"description":"Unauthorized - Invalid or missing authentication token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"403":{"description":"Forbidden - Loyalty program not launched or customer not enrolled","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}},"404":{"description":"Customer not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

### Loyalty x Referrals

{% hint style="info" %}
Before making a referral, the customer will need to be registered as a "referral sender". See [Referrals](/on-site/storefront-rest-api/endpoints/referrals.md).
{% endhint %}

## Send Referral Request

> Sends a referral request to the specified email address

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/referrals":{"post":{"summary":"Send Referral Request","tags":["loyalty"],"description":"Sends a referral request to the specified email address","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"The email of the person being referred to the loyalty program"},"referralSenderId":{"type":"string","format":"uuid","description":"The Referral Sender ID of the loyalty member. This can be found in the response from the `Get Customer Details` authenticated endpoint."}},"required":["email","referralSenderId"]}}}},"responses":{"204":{"description":"Successfully sent referral request."},"400":{"description":"Bad Request - Unable to create referral.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"description":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Error code identifier"}},"required":["description"]}},"required":["error"]}}}}}}}}}
```

## Get Referral History

> Retrieves the referral history for the authenticated customer

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/referrals":{"get":{"summary":"Get Referral History","tags":["loyalty"],"description":"Retrieves the referral history for the authenticated customer","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}},{"name":"lastEvaluated","in":"query","required":false,"schema":{"type":"string"},"description":"Token for pagination to get the next page of results"}],"responses":{"200":{"description":"Referral history retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"referrals":{"type":"array","items":{"type":"object","properties":{"dateCreated":{"type":"string","format":"date-time","description":"Date and time when the referral was made"},"recipient":{"type":"object","description":"Details of the person who received the referral invitation","properties":{"email":{"type":"string","format":"email"}}},"status":{"type":"string","enum":["complete","pending","declined"],"description":"Current status of the referral"}},"required":["dateCreated","recipient","status"]},"description":"List of referrals for the customer"},"nextUrl":{"type":"string","format":"uri","description":"URL for the next page of results"}},"required":["referrals","nextUrl"]}}}}}}}}}
```

## Get Referral Count

> Retrieves the number of referrals by an authenticated customer

```json
{"openapi":"3.0.0","info":{"title":"Okendo Storefront API (Customer Authed)","version":"1.1.0"},"servers":[{"url":"https://api.okendo.io/v1"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token for authenticated customer"}}},"paths":{"/loyalty/referral_aggregate":{"get":{"summary":"Get Referral Count","tags":["loyalty"],"description":"Retrieves the number of referrals by an authenticated customer","parameters":[{"name":"okendo-api-version","in":"header","required":true,"schema":{"type":"string","enum":["2025-02-01"]},"description":"API version header"},{"name":"okendo-partner-id","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Referral count retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"referralsTotal":{"type":"number"}},"required":["referralsTotal"]}}}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.okendo.io/on-site/storefront-rest-api/endpoints/loyalty.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
