---
title: "List earning rules"
method: GET
path: "/v2/loyalties/earning-rules"
tags: ["Earning Rules"]
---

# List earning rules

`GET /v2/loyalties/earning-rules`

<Info>

<Badge color="gray">Documentation in progress</Badge>

This documentation is in progress. The parameters, fields, request and response bodies, and other data may be subject to change. If you need more information or you want to share feedback, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.

</Info>

Returns a cursor-paginated list of earning rules. The same field cannot be used
in both ascending and descending order at once
(e.g. `order=name&order=-name` is rejected). Default order is `-created_at`;
`id` is always appended as a tie-breaker.

## Query parameters

- `limit` integer
- `order` union
  - '-created_at' | 'created_at' | 'name' | '-name'
  - string[]
- `cursor` string
- `filters` EarningRuleListFilters — Filters for listing earning rules. Each field carries a required `conditions` object; condition values may be passed as a single string or as an array. Conditions not allowed for the field type are rejected.
  - `junction` 'AND' | 'OR', nullable — How multiple field filters are combined. Defaults to AND behaviour. Can be `null`.
  - `id` object, nullable — ID filter. Allowed conditions: `$is`, `$is_not` (single value), `$in`, `$not_in` (up to 100 values). Values must match `^lern_[a-f0-9]+$`. Can be `null`.
    - `conditions` object, required
      - `$is` union — Exactly matches the value (single value).
        - string
        - string[]
      - `$is_not` union — Does not match the value (single value).
        - string
        - string[]
      - `$in` union — Matches any of the values (up to 100).
        - string
        - string[]
      - `$not_in` union — Matches none of the values (up to 100).
        - string
        - string[]
  - `name` EarningRuleStringFilterConditions — String field filter conditions. `$is`, `$is_not`, `$contains`, `$not_contain`, `$starts_with` and `$ends_with` take a single value (string or one-element array); `$in` and `$not_in` take up to 10 values; `$has_value` and `$is_unknown` are presence checks (value is ignored).
    - `conditions` object, required
      - `$is` union — Exactly matches the value.
        - string
        - string[]
      - `$is_not` union — Does not match the value.
        - string
        - string[]
      - `$contains` union — Contains the substring.
        - string
        - string[]
      - `$not_contain` union — Does not contain the substring.
        - string
        - string[]
      - `$starts_with` union — Starts with the prefix.
        - string
        - string[]
      - `$ends_with` union — Ends with the suffix.
        - string
        - string[]
      - `$in` union — Matches any of the values (up to 10).
        - string
        - string[]
      - `$not_in` union — Matches none of the values (up to 10).
        - string
        - string[]
      - `$has_value` string — Field has a value (presence check).
      - `$is_unknown` string — Field has no value (absence check).
  - `status` object, nullable — Status filter (enum type). Allowed conditions: `$is`, `$is_not` (single value), `$in`, `$not_in` (up to 10 values). Allowed values: `ACTIVE`, `INACTIVE`, `DRAFT`. Can be `null`.
    - `conditions` object, required
      - `$is` union — Exactly matches the value (single value).
        - 'ACTIVE' | 'INACTIVE' | 'DRAFT'
        - string[]
      - `$is_not` union — Does not match the value (single value).
        - 'ACTIVE' | 'INACTIVE' | 'DRAFT'
        - string[]
      - `$in` union — Matches any of the values (up to 10).
        - 'ACTIVE' | 'INACTIVE' | 'DRAFT'
        - string[]
      - `$not_in` union — Matches none of the values (up to 10).
        - 'ACTIVE' | 'INACTIVE' | 'DRAFT'
        - string[]
  - `created_at` EarningRuleDateFilterConditions — Date field filter conditions. `$before` and `$after` take a date string; `$is`, `$more_than` and `$less_than` take a non-negative integer number of days (relative comparison); `$has_value` and `$is_unknown` are presence checks.
    - `conditions` object, required
      - `$before` union — Before the given date (single date string).
        - string
        - string[]
      - `$after` union — After the given date (single date string).
        - string
        - string[]
      - `$is` union — Exactly N days ago (non-negative integer).
        - string
        - string[]
      - `$more_than` union — More than N days ago (non-negative integer).
        - string
        - string[]
      - `$less_than` union — Less than N days ago (non-negative integer).
        - string
        - string[]
      - `$has_value` string — Field has a value (presence check).
      - `$is_unknown` string — Field has no value (absence check).

## Response `200`

Paginated list of earning rules

- EarningRuleListResponse — Cursor-paginated list of earning rules.
  - `data` EarningRuleResponse[] — Earning rules on the current page.
    - `id` string — Earning rule ID (`lern_...`).
    - `name` string — Earning rule name.
    - `status` 'DRAFT' | 'ACTIVE' | 'INACTIVE' — Current status. `DELETED` also exists internally but deleted rules are excluded from API reads.
    - `earnings` EarningRuleEarningResponse[] — Earning definitions of the rule.
      - `id` string — Earning item ID (`lernei_...`).
      - `name` string, nullable — Earning item name. Can be `null`.
      - `rules` EarningRuleRulesGroup — Group of rule definitions combined by a logical formula. Besides `logic`, only positive-integer keys are allowed (property names must match `^[1-9]\d*$`), each referencing a rule definition. The `logic` value is a logical expression referencing the numbered rules, e.g. `"1 and 2"` or `"1 and (2 or 3)"`. At least one numbered rule is required (`minProperties: 2` including `logic`).
        - `logic` string, required — Logical expression combining the numbered rule definitions, e.g. `"1 and 2"`.
      - `tier_rules` EarningRuleTierRules — Tier requirements for an earning. With `NO_REQUIREMENTS`, `any_of` must be null/absent. With `ANY_OF`, `any_of` is required (at least one entry) and the member must be in any of the listed tiers to earn.
        - `type` 'NO_REQUIREMENTS' | 'ANY_OF', required — Tier requirement type.
        - `any_of` EarningRuleTierRulesAnyOfEntry[], nullable — Tier structure/tier combinations, any of which satisfies the requirement. Can be `null`.
          - `tier_structure_id` string, required — Tier structure ID (`lts_...`).
          - `tier_ids` string[], required — Qualifying tier IDs (`lt_...`).
      - `effects` EarningRuleEffect[] — Effects applied when the rules match.
        - `type` 'POINTS' | 'POINTS_PROPORTIONAL' | 'BENEFIT', required — Effect type.
        - `points` EarningRuleEffectPoints — Fixed points effect - awards a fixed number of points to a card definition.
          - `value` integer, required — Fixed number of points to award.
          - `card_definition_id` string, required — Card definition ID (`lcdef_...`) the points are awarded to.
          - `points_expiration` EarningRuleEffectPointsExpiration — Points expiration override. Depending on `type`, exactly one of `rolling_expiration`, `calendar_expiration` or `sliding_expiration` is required; for `NO_EXPIRATION` all three must be null/absent.
            - `type` 'NO_EXPIRATION' | 'ROLLING_EXPIRATION' | 'CALENDAR_EXPIRATION' | 'SLIDING_EXPIRATION', required — Points expiration type.
            - `rolling_expiration` EarningRuleEffectPointsExpirationRollingExpiration — Rolling expiration - points expire a fixed period after earning.
              - …
            - `calendar_expiration` EarningRuleEffectPointsExpirationCalendarExpiration — Calendar expiration - points expire on fixed calendar dates (1 to 20 dates).
              - …
            - `sliding_expiration` EarningRuleEffectPointsExpirationSlidingExpiration — Sliding expiration - points expire after a period of member inactivity. At least one of `earning_activity`, `spending_activity` or `custom_activity` must be `true`. When `custom_activity` is `true`, `custom_activity_types` is required (1-10 unique items).
              - …
        - `points_proportional` EarningRuleEffectPointsProportional — Proportional points effect - awards points using an "every X gives Y points" formula. Depending on `calculation_type`, one specific configuration object is required and the others must be null/absent: - `PRE_DISCOUNT_ORDER_AMOUNT`: requires `order.amount` - `POST_DISCOUNT_ORDER_AMOUNT`: requires `order.total_amount` - `ORDER_METADATA_VALUE`: requires `order.metadata` - `CUSTOMER_METADATA_VALUE`: requires `customer.metadata` - `CUSTOM_EVENT_METADATA_VALUE`: requires `custom_event.metadata` - `PRE_DISCOUNT_ORDER_ITEMS_AMOUNT`: requires `order_items.amount` - `POST_DISCOUNT_ORDER_ITEMS_AMOUNT`: requires `order_items.subtotal_amount` - `ORDER_ITEMS_QUANTITY`: requires `order_items.quantity` The trigger further restricts allowed calculation types: `customer.order.paid` allows all order/order-items types plus `CUSTOMER_METADATA_VALUE`; `customer.custom_event` allows `CUSTOMER_METADATA_VALUE` and `CUSTOM_EVENT_METADATA_VALUE`; `customer.segment.entered` allows only `CUSTOMER_METADATA_VALUE`.
          - `calculation_type` 'PRE_DISCOUNT_ORDER_AMOUNT' | 'POST_DISCOUNT_ORDER_AMOUNT' | 'PRE_DISCOUNT_ORDER_ITEMS_AMOUNT' | 'POST_DISCOUNT_ORDER_ITEMS_AMOUNT' | 'ORDER_ITEMS_QUANTITY' | 'ORDER_METADATA_VALUE' | 'CUSTOMER_METADATA_VALUE' | 'CUSTOM_EVENT_METADATA_VALUE', required — How the proportional points are calculated.
          - `card_definition_id` string, required — Card definition ID (`lcdef_...`) the points are awarded to.
          - `points_expiration` EarningRuleEffectPointsExpiration — Points expiration override. Depending on `type`, exactly one of `rolling_expiration`, `calendar_expiration` or `sliding_expiration` is required; for `NO_EXPIRATION` all three must be null/absent.
            - `type` 'NO_EXPIRATION' | 'ROLLING_EXPIRATION' | 'CALENDAR_EXPIRATION' | 'SLIDING_EXPIRATION', required — Points expiration type.
            - `rolling_expiration` EarningRuleEffectPointsExpirationRollingExpiration — Rolling expiration - points expire a fixed period after earning.
              - …
            - `calendar_expiration` EarningRuleEffectPointsExpirationCalendarExpiration — Calendar expiration - points expire on fixed calendar dates (1 to 20 dates).
              - …
            - `sliding_expiration` EarningRuleEffectPointsExpirationSlidingExpiration — Sliding expiration - points expire after a period of member inactivity. At least one of `earning_activity`, `spending_activity` or `custom_activity` must be `true`. When `custom_activity` is `true`, `custom_activity_types` is required (1-10 unique items).
              - …
          - `order` EarningRulePointsProportionalOrder — Order-based proportional calculation configuration. `amount` is used by `PRE_DISCOUNT_ORDER_AMOUNT`, `total_amount` by `POST_DISCOUNT_ORDER_AMOUNT` and `metadata` by `ORDER_METADATA_VALUE`.
            - `amount` EarningRulePointsProportionalEvery — "Every X gives Y points" formula based on an amount.
              - …
            - `total_amount` EarningRulePointsProportionalEvery — "Every X gives Y points" formula based on an amount.
              - …
            - `metadata` EarningRulePointsProportionalMetadata — "Every X gives Y points" formula based on a numeric metadata property.
              - …
          - `customer` EarningRulePointsProportionalCustomer — Customer-based proportional calculation configuration (`CUSTOMER_METADATA_VALUE`).
            - `metadata` EarningRulePointsProportionalMetadata, required — "Every X gives Y points" formula based on a numeric metadata property.
              - …
          - `custom_event` EarningRulePointsProportionalCustomEvent — Custom event based proportional calculation configuration (`CUSTOM_EVENT_METADATA_VALUE`).
            - `metadata` EarningRulePointsProportionalMetadata, required — "Every X gives Y points" formula based on a numeric metadata property.
              - …
          - `order_items` EarningRulePointsProportionalOrderItems — Order items based proportional calculation configuration. `amount` is used by `PRE_DISCOUNT_ORDER_ITEMS_AMOUNT`, `subtotal_amount` by `POST_DISCOUNT_ORDER_ITEMS_AMOUNT` and `quantity` by `ORDER_ITEMS_QUANTITY`.
            - `amount` EarningRulePointsProportionalOrderItemsCalculation — Order items based calculation - "every X gives Y points" applied to items matching the `applicable_to` criteria.
              - …
            - `subtotal_amount` EarningRulePointsProportionalOrderItemsCalculation — Order items based calculation - "every X gives Y points" applied to items matching the `applicable_to` criteria.
              - …
            - `quantity` EarningRulePointsProportionalOrderItemsCalculation — Order items based calculation - "every X gives Y points" applied to items matching the `applicable_to` criteria.
              - …
        - `benefit` EarningRuleEffectBenefit — Benefit effect - grants a predefined benefit.
          - `id` string, required — Benefit ID (`lben_...`).
    - `trigger` EarningRuleTrigger — Event that triggers the earning rule. Depending on `event`, either `custom_event` or `segment` is required and the other trigger contexts must be null/absent.
      - `event` 'customer.order.paid' | 'customer.custom_event' | 'customer.segment.entered', required — Triggering event type.
      - `custom_event` EarningRuleTriggerCustomEvent — Custom event trigger configuration.
        - `schema_id` string, required — Custom event schema ID (`ms_...`).
      - `segment` EarningRuleTriggerSegment — Segment trigger configuration.
        - `id` string, required — Segment ID (`seg_...`).
    - `error` EarningRuleError — Custom error message configuration.
      - `message` string, required — Error message shown when validation fails.
    - `validity_hours` EarningRuleValidityHours — Hours during which the earning rule is active. With `ANY_TIME`, `daily` must be null/absent. With `DAILY`, `daily` is required (at least one entry).
      - `type` 'DAILY' | 'ANY_TIME', required — Validity hours type.
      - `daily` EarningRuleValidityDailyHours[], nullable — Daily validity windows. Can be `null`.
        - `days_of_week` integer[], required — Days of week (0 = Sunday ... 6 = Saturday). Items must be unique.
        - `start_time` string, required — Window start time in `HH:mm` format.
        - `end_time` string, required — Window end time in `HH:mm` format.
    - `start_date` string, date-time, nullable — Date-time from which the rule is active. Can be `null`.
    - `end_date` string, date-time, nullable — Date-time until which the rule is active. Can be `null`.
    - `trigger_limits` EarningRuleTriggerLimits — Cooldown and frequency limits applied to the earning rule trigger.
      - `cooldown` EarningRuleTriggerLimitsCooldown — Cooldown between consecutive triggers per member. With `NO_COOLDOWN`, `fixed_cooldown` must be null/absent. With `FIXED_COOLDOWN`, `fixed_cooldown` is required.
        - `type` 'NO_COOLDOWN' | 'FIXED_COOLDOWN', required — Cooldown type.
        - `fixed_cooldown` EarningRuleTriggerLimitsCooldownFixedCooldown — Fixed cooldown period configuration.
          - `period` EarningRuleTriggerLimitsCooldownFixedCooldownPeriod, required — Cooldown period. The maximum `value` depends on `unit`: `HOUR` - 24, `DAY` - 90, `WEEK` - 52, `MONTH` - 12, `YEAR` - 1.
            - `value` integer, required — Period length. Maximum depends on `unit`: 24 for HOUR, 90 for DAY, 52 for WEEK, 12 for MONTH, 1 for YEAR.
            - `unit` 'HOUR' | 'DAY' | 'WEEK' | 'MONTH' | 'YEAR', required — Period unit.
      - `frequency` EarningRuleTriggerLimitsFrequency — Frequency limit for triggers per member. With `NO_LIMIT`, `limits` must be null or an empty array. With `LIMITED`, `limits` is required and must contain exactly one limit.
        - `type` 'NO_LIMIT' | 'LIMITED', required — Frequency limit type.
        - `limits` EarningRuleTriggerLimitsFrequencyLimit[], nullable — Frequency limits (at most one). Can be `null`.
          - `type` 'TIME_BASED', required — Frequency limit variant.
          - `period` EarningRuleTriggerLimitsFrequencyLimitTimeBasedPeriod, required — Time-based frequency limit period. Currently only `CURRENT_PERIOD` is supported; when selected, `current_period` is required.
            - `type` 'CURRENT_PERIOD', required — Period type.
            - `current_period` EarningRuleTriggerLimitsFrequencyLimitTimeBasedCurrentPeriod — Current calendar period unit for the frequency limit.
              - …
          - `triggers` EarningRuleTriggerLimitsFrequencyLimitTimeBasedTriggers, required — Maximum number of triggers allowed within the period.
            - `max` integer, required — Maximum number of triggers per period.
    - `metadata` Metadata — Arbitrary key-value metadata; any JSON object is accepted.
    - `created_at` string, date-time — Creation timestamp (ISO 8601).
    - `updated_at` string, date-time, nullable — Last update timestamp (ISO 8601). `null` when never updated.
    - `object` 'earning_rule' — Object type marker. Always `earning_rule`.
  - `cursor` EarningRuleListCursor, nullable — Pagination cursor. `null` when there are no more results.
    - `next` string — Cursor ID to pass as the `cursor` query parameter to fetch the next page.
    - `expires_at` string, date-time — Cursor expiration timestamp.
  - `object` 'list' — Object type marker. Always `list`.

## Other responses

- `400` — Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.
- `404` — Resource not found.
- `409` — Conflict - e.g. duplicate resource or invalid state transition.
- `500` — Internal server error.

---

[API](https://skmtc.net/voucherifyio/apis/voucherify-loyalty-v2-api.md) · [All operations](https://skmtc.net/voucherifyio/apis/voucherify-loyalty-v2-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/voucherifyio/voucherify-loyalty-v2-api/revisions/69be73b5cff0/schema)
