Loyalty

These endpoints are called from a shopper's browser, so they take your publishable key rather than a secret one. Anything specific to one customer also takes a signed email and timestamp. Identifying the customer explains how to produce the signature.

To call them from your own server instead, send a secret key as a bearer token and leave apiPublishableKey out. See Calling the widget API from a server.

GET /widgets/loyalty

Get the store's loyalty program: its tiers, ways to earn, offers and rewards, plus the signed-in shopper's own state when the request is signed

Query parameters

apiPublishableKeystring

Your organization's publishable key, from Settings, API keys. Leave it out when the request carries a secret key as a bearer token instead, which is how a server calls these endpoints.

customerEmailstring (email)

The signed-in shopper's address. Leave it out for the guest catalog.

timestampstring

The Unix seconds the signature was made at. Required with customerEmail.

signaturestring

The HMAC of the email and timestamp. Required with customerEmail.

siteSlugstring

Which of the store's sites the widget is embedded on. Leave it out and the oldest site is used.

previewTokenstring

A preview token from POST /loyalty-programs/{id}/preview. It adds the one draft program it names to the response, so a merchant can check a program before publishing it. The publishable key on its own never reaches a draft.

Request
curl \
  "https://your-store.meisei.app/api/widgets/loyalty?apiPublishableKey=pk_YOUR_PUBLISHABLE_KEY"
Response
{
  "organizationName": "string",
  "siteSlug": "string",
  "signInUrl": "string",
  "authenticated": true,
  "programs": [
    {
      "id": "A4Ws1igz",
      "name": "string",
      "pointsNames": {
        "singular": "...",
        "plural": "..."
      },
      "paused": true,
      "draft": true,
      "sectionsEnabled": {
        "tiers": "...",
        "rules": "...",
        "offers": "...",
        "rewards": "..."
      },
      "sectionOrder": ["..."],
      "tiers": ["..."],
      "rules": ["..."],
      "offers": ["..."],
      "rewards": ["..."],
      "member": {
        "loyaltyMembershipId": "...",
        "joinedAt": "...",
        "balance": "...",
        "tier": "...",
        "nextTier": "...",
        "tierEarned": "...",
        "tierRemaining": "...",
        "tierTarget": "...",
        "ruleProgress": "...",
        "rewards": "...",
        "metadata": "..."
      }
    }
  ]
}

GET /widgets/loyalty/earnable

Get the points a purchase would earn, for a badge on a product page. Send the price and it comes back with the points every live purchase rule adds up to, with the signed-in shopper's tier multiplier applied when the request is signed. A program that would earn nothing is left out, so a store with no purchase rule gets an empty list.

Query parameters

apiPublishableKeystring

Your organization's publishable key, from Settings, API keys. Leave it out when the request carries a secret key as a bearer token instead, which is how a server calls these endpoints.

customerEmailstring (email)

The signed-in shopper's address. Leave it out for the guest catalog.

timestampstring

The Unix seconds the signature was made at. Required with customerEmail.

signaturestring

The HMAC of the email and timestamp. Required with customerEmail.

siteSlugstring

Which of the store's sites the widget is embedded on. Leave it out and the oldest site is used.

previewTokenstring

A preview token from POST /loyalty-programs/{id}/preview. It adds the one draft program it names to the response, so a merchant can check a program before publishing it. The publishable key on its own never reaches a draft.

pricenumberrequired

What the shopper would spend, in whole currency units rather than cents. For example 12.50.

currencystring

The currency the price is in, such as USD. Points are earned per whole currency unit, so this is only carried back to the widget.

Request
curl \
  "https://your-store.meisei.app/api/widgets/loyalty/earnable?apiPublishableKey=pk_YOUR_PUBLISHABLE_KEY&price=0"
Response
{
  "siteSlug": "string",
  "authenticated": true,
  "currency": "string",
  "programs": [
    {
      "loyaltyProgramId": "A4Ws1igz",
      "programName": "string",
      "pointsNames": {
        "singular": "...",
        "plural": "..."
      },
      "points": 0,
      "pointsMultiplier": 0,
      "member": true
    }
  ]
}

POST /widgets/loyalty/join

Join a loyalty program as the signed-in shopper

Query parameters

apiPublishableKeystring

Your organization's publishable key, from Settings, API keys. Leave it out when the request carries a secret key as a bearer token instead, which is how a server calls these endpoints.

customerEmailstring (email)required

Email address of the customer the storefront signed in.

timestampstringrequired

Unix time in seconds when the signature was generated. It is accepted for 24 hours.

signaturestringrequired

Hex HMAC-SHA256 of customerEmail followed by timestamp, keyed with your widget signing secret. See the widgets guide for the recipe.

siteSlugstring

Which of the store's sites the widget is embedded on. Leave it out and the oldest site is used.

previewTokenstring

A preview token from POST /loyalty-programs/{id}/preview. It adds the one draft program it names to the response, so a merchant can check a program before publishing it. The publishable key on its own never reaches a draft.

Body parameters

loyaltyProgramIdstringrequired

The program to join.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/widgets/loyalty/join?apiPublishableKey=pk_YOUR_PUBLISHABLE_KEY&customerEmail=shopper%40example.com&timestamp=1735689600&signature=9f86d081..." \
  -H "Content-Type: application/json" \
  -d '{
  "loyaltyProgramId": "string"
}'
Response
{
  "program": {
    "id": "A4Ws1igz",
    "name": "string",
    "pointsNames": {
      "singular": "string",
      "plural": "string"
    },
    "paused": true,
    "draft": true,
    "sectionsEnabled": {
      "tiers": true,
      "rules": true,
      "offers": true,
      "rewards": true
    },
    "sectionOrder": ["tiers"],
    "tiers": [
      {
        "id": "...",
        "name": "...",
        "color": "...",
        "pointsMultiplier": "...",
        "thresholdAmount": "...",
        "thresholdWindow": "..."
      }
    ],
    "rules": [
      {
        "id": "...",
        "name": "...",
        "section": "...",
        "triggerType": "...",
        "reward": "...",
        "pointsPrice": "...",
        "variableAmount": "...",
        "every": "...",
        "remainingCount": "...",
        "availableTo": "...",
        "eligible": "..."
      }
    ],
    "offers": [
      {
        "id": "...",
        "name": "...",
        "section": "...",
        "triggerType": "...",
        "reward": "...",
        "pointsPrice": "...",
        "variableAmount": "...",
        "every": "...",
        "remainingCount": "...",
        "availableTo": "...",
        "eligible": "..."
      }
    ],
    "rewards": [
      {
        "id": "...",
        "name": "...",
        "section": "...",
        "triggerType": "...",
        "reward": "...",
        "pointsPrice": "...",
        "variableAmount": "...",
        "every": "...",
        "remainingCount": "...",
        "availableTo": "...",
        "eligible": "..."
      }
    ],
    "member": {
      "loyaltyMembershipId": "A4Ws1igz",
      "joinedAt": "2025-01-15T09:30:00Z",
      "balance": 0,
      "tier": {
        "id": "...",
        "name": "...",
        "color": "...",
        "pointsMultiplier": "..."
      },
      "nextTier": {
        "id": "...",
        "name": "...",
        "color": "..."
      },
      "tierEarned": 0,
      "tierRemaining": 0,
      "tierTarget": 0,
      "ruleProgress": ["..."],
      "rewards": ["..."],
      "metadata": "..."
    }
  },
  "alreadyMember": true
}

POST /widgets/loyalty/claims

Spend points on a reward. The reward comes back with the code to use at checkout.

Query parameters

apiPublishableKeystring

Your organization's publishable key, from Settings, API keys. Leave it out when the request carries a secret key as a bearer token instead, which is how a server calls these endpoints.

customerEmailstring (email)required

Email address of the customer the storefront signed in.

timestampstringrequired

Unix time in seconds when the signature was generated. It is accepted for 24 hours.

signaturestringrequired

Hex HMAC-SHA256 of customerEmail followed by timestamp, keyed with your widget signing secret. See the widgets guide for the recipe.

siteSlugstring

Which of the store's sites the widget is embedded on. Leave it out and the oldest site is used.

previewTokenstring

A preview token from POST /loyalty-programs/{id}/preview. It adds the one draft program it names to the response, so a merchant can check a program before publishing it. The publishable key on its own never reaches a draft.

Body parameters

loyaltyRuleIdstringrequired

The reward to spend points on.

pointsToSpendinteger

How many points to spend. Only rewards that let the member choose accept more than one unit.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/widgets/loyalty/claims?apiPublishableKey=pk_YOUR_PUBLISHABLE_KEY&customerEmail=shopper%40example.com&timestamp=1735689600&signature=9f86d081..." \
  -H "Content-Type: application/json" \
  -d '{
  "loyaltyRuleId": "string",
  "pointsToSpend": 0
}'
Response
{
  "reward": {
    "id": "A4Ws1igz",
    "name": "string",
    "reward": {
      "type": "points",
      "amount": 0
    },
    "status": "pending",
    "code": "string",
    "pointsSpent": 0,
    "expiresAt": "2025-01-15T09:30:00Z",
    "redeemedAt": "2025-01-15T09:30:00Z",
    "createdAt": "2025-01-15T09:30:00Z",
    "cancelable": true
  },
  "balance": 0
}

GET /widgets/loyalty/rewards

List the rewards the shopper holds, with their codes

Query parameters

apiPublishableKeystring

Your organization's publishable key, from Settings, API keys. Leave it out when the request carries a secret key as a bearer token instead, which is how a server calls these endpoints.

customerEmailstring (email)required

Email address of the customer the storefront signed in.

timestampstringrequired

Unix time in seconds when the signature was generated. It is accepted for 24 hours.

signaturestringrequired

Hex HMAC-SHA256 of customerEmail followed by timestamp, keyed with your widget signing secret. See the widgets guide for the recipe.

siteSlugstring

Which of the store's sites the widget is embedded on. Leave it out and the oldest site is used.

previewTokenstring

A preview token from POST /loyalty-programs/{id}/preview. It adds the one draft program it names to the response, so a merchant can check a program before publishing it. The publishable key on its own never reaches a draft.

loyaltyProgramIdstringrequired

The program whose rewards to list.

Request
curl \
  "https://your-store.meisei.app/api/widgets/loyalty/rewards?apiPublishableKey=pk_YOUR_PUBLISHABLE_KEY&customerEmail=shopper%40example.com&timestamp=1735689600&signature=9f86d081...&loyaltyProgramId=A4Ws1igz"
Response
{
  "rewards": [
    {
      "id": "A4Ws1igz",
      "name": "string",
      "reward": {
        "type": "...",
        "amount": "..."
      },
      "status": "pending",
      "code": "string",
      "pointsSpent": 0,
      "expiresAt": "2025-01-15T09:30:00Z",
      "redeemedAt": "2025-01-15T09:30:00Z",
      "createdAt": "2025-01-15T09:30:00Z",
      "cancelable": true
    }
  ]
}

POST /widgets/loyalty/rewards/{id}/cancel

Cancel an unused reward and take the points it cost back

Path parameters

idstringrequired

The ID of the reward.

Query parameters

apiPublishableKeystring

Your organization's publishable key, from Settings, API keys. Leave it out when the request carries a secret key as a bearer token instead, which is how a server calls these endpoints.

customerEmailstring (email)required

Email address of the customer the storefront signed in.

timestampstringrequired

Unix time in seconds when the signature was generated. It is accepted for 24 hours.

signaturestringrequired

Hex HMAC-SHA256 of customerEmail followed by timestamp, keyed with your widget signing secret. See the widgets guide for the recipe.

siteSlugstring

Which of the store's sites the widget is embedded on. Leave it out and the oldest site is used.

previewTokenstring

A preview token from POST /loyalty-programs/{id}/preview. It adds the one draft program it names to the response, so a merchant can check a program before publishing it. The publishable key on its own never reaches a draft.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/widgets/loyalty/rewards/A4Ws1igz/cancel?apiPublishableKey=pk_YOUR_PUBLISHABLE_KEY&customerEmail=shopper%40example.com&timestamp=1735689600&signature=9f86d081..."
Response
{
  "reward": {
    "id": "A4Ws1igz",
    "name": "string",
    "reward": {
      "type": "points",
      "amount": 0
    },
    "status": "pending",
    "code": "string",
    "pointsSpent": 0,
    "expiresAt": "2025-01-15T09:30:00Z",
    "redeemedAt": "2025-01-15T09:30:00Z",
    "createdAt": "2025-01-15T09:30:00Z",
    "cancelable": true
  },
  "balance": 0
}