Loyalty rules

GET /loyalty-rules

List the earning rules across the organization's loyalty programs, oldest first by default. Each rule pairs a trigger with the reward it grants. Pass include=stats for what each rule has issued and how much of that has been redeemed. Supports search, filtering and cursor pagination.

Requires the loyalty:read permission.

Query parameters

limitnumber

The number of records to return.

cursorstring

A pagination cursor. Fetch the next page by passing the nextCursor value from the previous response.

sortname | -name | createdAt | -createdAt | rewardType | -rewardType

The sort order. Prefix a field with - to sort descending. Defaults to createdAt.

searchstring

A free-text search term. Every word has to match, from the start of a word, in any order and ignoring case and accents, against the record's most identifying fields. Combined with filter using AND.

filterstring

A JSON-encoded filter document, for example {"createdAt":{"$gte":"2025-01-01T00:00:00Z"}}. Filterable fields: id, loyaltyProgramId, section, name, availableFrom, availableTo, createdAt. See Filtering for the syntax.

includestring

A comma-separated list of extra fields to compute and return. Each one costs an additional query, so ask only for what you need. Available: stats.

availableAtstring (date-time)

Return only rules that are live at this moment in time.

Request
curl \
  "https://your-store.meisei.app/api/loyalty-rules" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "data": [
    {
      "id": "A4Ws1igz",
      "loyaltyProgramId": "A4Ws1igz",
      "section": "rules",
      "name": "string",
      "trigger": {
        "type": "..."
      },
      "reward": {
        "type": "...",
        "amount": "..."
      },
      "maxRedemptionsPerCustomer": 0,
      "maxAvailableCount": 0,
      "availableCount": 0,
      "availableFrom": "2025-01-15T09:30:00Z",
      "availableTo": "2025-01-15T09:30:00Z",
      "filter": "...",
      "metadata": "...",
      "createdAt": "2025-01-15T09:30:00Z",
      "updatedAt": "2025-01-15T09:30:00Z",
      "stats": {
        "issuedCount": "...",
        "redeemedCount": "..."
      }
    }
  ],
  "nextCursor": "string"
}

POST /loyalty-rules

Create an earning rule: a trigger paired with the reward it grants. A points reward needs the program to have points named, and any product filter has to name products and tags that exist.

Requires the loyalty:write permission.

Body parameters

loyaltyProgramIdstringrequired

The loyalty program the rule belongs to.

sectionrules | rewards | offersrequired

Which section of the loyalty widget the rule is presented in.

namestringrequired

The rule's display name, shown to members.

triggerobject | object | object | objectrequired

What has to happen for the rule to award its reward.

rewardobject | object | object | object | objectrequired

What the customer gets when the rule fires.

maxRedemptionsPerCustomerinteger | null

How many times one customer may earn this reward. Null means unlimited.

maxAvailableCountinteger | null

How many times the reward can be earned in total, across everyone. Null means unlimited. Setting it starts the remaining count at the same number.

availableFromstring (date-time) | null

When the rule starts firing. Null means straight away.

availableTostring (date-time) | null

When the rule stops firing. Null means it stays open.

filterobject | null

Who the rule applies to: a filter document in the same shape GET /loyalty-memberships takes, for example {"tier.id":{"$in":["..."]}} or {"tags.name":"vip"}. Null means every member qualifies.

metadataobject

Key/value pairs for your own data. Keys you define with /metadata-definitions are typed and validated; any other key is free-form. Individual keys are filterable with a dot path, for example metadata.category.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/loyalty-rules" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "loyaltyProgramId": "string",
  "section": "rules",
  "name": "string",
  "trigger": {
    "type": "joinProgram"
  },
  "reward": {
    "type": "points",
    "amount": 0
  },
  "maxRedemptionsPerCustomer": 0,
  "maxAvailableCount": 0,
  "availableFrom": "2025-01-15T09:30:00Z",
  "availableTo": "2025-01-15T09:30:00Z",
  "filter": "...",
  "metadata": "..."
}'
Response
{
  "id": "A4Ws1igz",
  "loyaltyProgramId": "A4Ws1igz",
  "section": "rules",
  "name": "string",
  "trigger": {
    "type": "joinProgram"
  },
  "reward": {
    "type": "points",
    "amount": 0
  },
  "maxRedemptionsPerCustomer": 0,
  "maxAvailableCount": 0,
  "availableCount": 0,
  "availableFrom": "2025-01-15T09:30:00Z",
  "availableTo": "2025-01-15T09:30:00Z",
  "filter": "...",
  "metadata": "...",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

GET /loyalty-rules/{id}

Get a single loyalty rule by ID.

Requires the loyalty:read permission.

Path parameters

idstringrequired

The ID of the loyalty rule.

Query parameters

includestring

A comma-separated list of extra fields to compute and return. Each one costs an additional query, so ask only for what you need. Available: stats.

Request
curl \
  "https://your-store.meisei.app/api/loyalty-rules/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "loyaltyProgramId": "A4Ws1igz",
  "section": "rules",
  "name": "string",
  "trigger": {
    "type": "joinProgram"
  },
  "reward": {
    "type": "points",
    "amount": 0
  },
  "maxRedemptionsPerCustomer": 0,
  "maxAvailableCount": 0,
  "availableCount": 0,
  "availableFrom": "2025-01-15T09:30:00Z",
  "availableTo": "2025-01-15T09:30:00Z",
  "filter": "...",
  "metadata": "...",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z",
  "stats": {
    "issuedCount": 0,
    "redeemedCount": 0
  }
}

PUT /loyalty-rules/{id}

Update a loyalty rule. The loyalty program it belongs to cannot change. Rewards already issued keep the configuration they were issued under, and the change is recorded in the audit trail.

Requires the loyalty:write permission.

Path parameters

idstringrequired

The ID of the loyalty rule to update.

Body parameters

sectionrules | rewards | offers

Which section of the loyalty widget the rule is presented in.

namestring

The rule's display name, shown to members.

triggerobject | object | object | object

What has to happen for the rule to award its reward.

rewardobject | object | object | object | object

What the customer gets when the rule fires.

maxRedemptionsPerCustomerinteger | null

How many times one customer may earn this reward. Null means unlimited.

maxAvailableCountinteger | null

How many times the reward can be earned in total, across everyone. Null means unlimited. Setting it starts the remaining count at the same number.

availableFromstring (date-time) | null

When the rule starts firing. Null means straight away.

availableTostring (date-time) | null

When the rule stops firing. Null means it stays open.

filterobject | null

Who the rule applies to: a filter document in the same shape GET /loyalty-memberships takes, for example {"tier.id":{"$in":["..."]}} or {"tags.name":"vip"}. Null means every member qualifies.

metadataobject

Key/value pairs for your own data. Keys you define with /metadata-definitions are typed and validated; any other key is free-form. Individual keys are filterable with a dot path, for example metadata.category.

Request
curl \
  -X PUT \
  "https://your-store.meisei.app/api/loyalty-rules/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "section": "rules",
  "name": "string",
  "trigger": {
    "type": "joinProgram"
  },
  "reward": {
    "type": "points",
    "amount": 0
  },
  "maxRedemptionsPerCustomer": 0,
  "maxAvailableCount": 0,
  "availableFrom": "2025-01-15T09:30:00Z",
  "availableTo": "2025-01-15T09:30:00Z",
  "filter": "...",
  "metadata": "..."
}'
Response
{
  "id": "A4Ws1igz",
  "loyaltyProgramId": "A4Ws1igz",
  "section": "rules",
  "name": "string",
  "trigger": {
    "type": "joinProgram"
  },
  "reward": {
    "type": "points",
    "amount": 0
  },
  "maxRedemptionsPerCustomer": 0,
  "maxAvailableCount": 0,
  "availableCount": 0,
  "availableFrom": "2025-01-15T09:30:00Z",
  "availableTo": "2025-01-15T09:30:00Z",
  "filter": "...",
  "metadata": "...",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

DELETE /loyalty-rules/{id}

Delete a loyalty rule. Rewards and activity it already produced are kept, so deleting it only stops future awards.

Requires the loyalty:write permission.

Path parameters

idstringrequired

The ID of the loyalty rule to delete.

Request
curl \
  -X DELETE \
  "https://your-store.meisei.app/api/loyalty-rules/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "loyaltyProgramId": "A4Ws1igz",
  "section": "rules",
  "name": "string",
  "trigger": {
    "type": "joinProgram"
  },
  "reward": {
    "type": "points",
    "amount": 0
  },
  "maxRedemptionsPerCustomer": 0,
  "maxAvailableCount": 0,
  "availableCount": 0,
  "availableFrom": "2025-01-15T09:30:00Z",
  "availableTo": "2025-01-15T09:30:00Z",
  "filter": "...",
  "metadata": "...",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}