---
title: "Get earning rule"
method: GET
path: "/v2/loyalties/earning-rules/{earningRuleId}"
tags: ["Earning Rules"]
---

# Get earning rule

`GET /v2/loyalties/earning-rules/{earningRuleId}`

## Request

- Base URL: `https://api.voucherify.io`
- URL: `https://api.voucherify.io/v2/loyalties/earning-rules/{earningRuleId}`
- Auth: one of:
  - API key in header `X-App-Id` and API key in header `X-App-Token`
  - HTTP bearer

Returns a single earning rule by its ID.

## Response `200`

Earning rule

- V2LoyaltiesEarningRulesGetResponseBody: Earning rule as returned by the API.
  - `id` string, required: Earning rule ID (`lern_...`).
  - `name` string, required: Earning rule name.
  - `status` 'DRAFT' | 'ACTIVE' | 'INACTIVE', required: Current status. `DELETED` also exists internally but deleted rules are excluded from API reads.
  - `earnings` EarningRuleEarning[], required: Earning definitions of the rule. Contains at least one earning.
    - `id` string, required: 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, required: 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` LoyaltyV2ActivityEarningRuleTierRulesAnyOfEntry[], 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[], required: Effects applied when the rules match. Contains 1 to 10 effects.
      - `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.
            - `period` LoyaltyV2ActivityEarningRuleEffectPointsExpirationRollingExpirationPeriod, required: Rolling expiration period. The maximum `value` depends on `unit`: `DAY` - 90, `MONTH` - 12, `YEAR` - 5.
              - …
            - `rounding` LoyaltyV2ActivityEarningRuleEffectPointsExpirationRollingExpirationRounding: `value` is the month (1-12). Required when `type` is `END_OF_PARTICULAR_MONTH`. Absent for other rounding types.
              - …
          - `calendar_expiration` EarningRuleEffectPointsExpirationCalendarExpiration: Calendar expiration - points expire on fixed calendar dates (1 to 20 dates).
            - `expiration_dates` LoyaltyV2ActivityEarningRuleEffectPointsExpirationCalendarExpirationDate[], required: Fixed expiration dates (day + month).
              - …
          - `sliding_expiration` EarningRuleEffectPointsExpirationSlidingExpiration: Sliding expiration. Points expire after a period of member inactivity.
            - `earning_activity` boolean, required: Whether earning activity resets the expiration window.
            - `period` LoyaltyV2ActivityEarningRuleEffectPointsExpirationSlidingExpirationPeriod, required: Sliding expiration inactivity period. The maximum `value` depends on `unit`: `DAY` - 90, `MONTH` - 12, `YEAR` - 1.
              - …
      - `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.
            - `period` LoyaltyV2ActivityEarningRuleEffectPointsExpirationRollingExpirationPeriod, required: Rolling expiration period. The maximum `value` depends on `unit`: `DAY` - 90, `MONTH` - 12, `YEAR` - 5.
              - …
            - `rounding` LoyaltyV2ActivityEarningRuleEffectPointsExpirationRollingExpirationRounding: `value` is the month (1-12). Required when `type` is `END_OF_PARTICULAR_MONTH`. Absent for other rounding types.
              - …
          - `calendar_expiration` EarningRuleEffectPointsExpirationCalendarExpiration: Calendar expiration - points expire on fixed calendar dates (1 to 20 dates).
            - `expiration_dates` LoyaltyV2ActivityEarningRuleEffectPointsExpirationCalendarExpirationDate[], required: Fixed expiration dates (day + month).
              - …
          - `sliding_expiration` EarningRuleEffectPointsExpirationSlidingExpiration: Sliding expiration. Points expire after a period of member inactivity.
            - `earning_activity` boolean, required: Whether earning activity resets the expiration window.
            - `period` LoyaltyV2ActivityEarningRuleEffectPointsExpirationSlidingExpirationPeriod, required: Sliding expiration inactivity period. The maximum `value` depends on `unit`: `DAY` - 90, `MONTH` - 12, `YEAR` - 1.
              - …
        - `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` LoyaltyV2ActivityEarningRulePointsProportionalEvery: "Every X gives Y points" formula based on an amount.
            - `every` integer, required: The divisor – every this amount (e.g. in cents) awards `value` points.
            - `value` number, required: Points awarded per `every` unit.
          - `total_amount` LoyaltyV2ActivityEarningRulePointsProportionalEvery: "Every X gives Y points" formula based on an amount.
            - `every` integer, required: The divisor – every this amount (e.g. in cents) awards `value` points.
            - `value` number, required: Points awarded per `every` unit.
          - `metadata` LoyaltyV2ActivityEarningRulePointsProportionalMetadata: "Every X gives Y points" formula based on a numeric metadata property.
            - `every` integer, required: The divisor – every this metadata value awards `value` points.
            - `value` number, required: Points awarded per `every` unit.
            - `property` string, required: Metadata property name holding the numeric value.
        - `customer` EarningRulePointsProportionalCustomer
          - `metadata` LoyaltyV2ActivityEarningRulePointsProportionalMetadata, required: "Every X gives Y points" formula based on a numeric metadata property.
            - `every` integer, required: The divisor – every this metadata value awards `value` points.
            - `value` number, required: Points awarded per `every` unit.
            - `property` string, required: Metadata property name holding the numeric value.
        - `custom_event` EarningRulePointsProportionalCustomEvent
          - `metadata` LoyaltyV2ActivityEarningRulePointsProportionalMetadata, required: "Every X gives Y points" formula based on a numeric metadata property.
            - `every` integer, required: The divisor – every this metadata value awards `value` points.
            - `value` number, required: Points awarded per `every` unit.
            - `property` string, required: Metadata property name holding the numeric value.
        - `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.
            - `every` integer, required: The divisor - every this amount/quantity awards `value` points.
            - `value` number, required: Points awarded per `every` unit.
            - `applicable_to` EarningRulePointsProportionalApplicableTo[], required: Product/SKU/collection criteria selecting matching order items.
              - …
          - `subtotal_amount` EarningRulePointsProportionalOrderItemsCalculation: Order items based calculation - "every X gives Y points" applied to items matching the `applicable_to` criteria.
            - `every` integer, required: The divisor - every this amount/quantity awards `value` points.
            - `value` number, required: Points awarded per `every` unit.
            - `applicable_to` EarningRulePointsProportionalApplicableTo[], required: Product/SKU/collection criteria selecting matching order items.
              - …
          - `quantity` EarningRulePointsProportionalOrderItemsCalculation: Order items based calculation - "every X gives Y points" applied to items matching the `applicable_to` criteria.
            - `every` integer, required: The divisor - every this amount/quantity awards `value` points.
            - `value` number, required: Points awarded per `every` unit.
            - `applicable_to` EarningRulePointsProportionalApplicableTo[], required: Product/SKU/collection criteria selecting matching order items.
              - …
      - `benefit` LoyaltyV2ActivityEarningRuleEffectBenefit: Benefit effect - grants a predefined benefit.
        - `id` string, required: Benefit ID (`lben_...`).
  - `trigger` EarningRuleTrigger, required: 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` LoyaltyV2ActivityEarningRuleTriggerCustomEvent: Custom event trigger configuration.
      - `schema_id` string, required: Custom event schema ID (`ms_...`).
    - `segment` LoyaltyV2ActivityEarningRuleTriggerSegment: Segment trigger configuration.
      - `id` string, required: Segment ID (`seg_...`).
  - `error` LoyaltyV2ActivityEarningRuleError: Custom error message configuration.
    - `message` string, required: Error message shown when validation fails.
  - `validity_hours` EarningRuleValidityHours, required: 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` LoyaltyV2ActivityEarningRuleValidityDailyHours[], 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, required: Date-time from which the rule is active. Can be `null`.
  - `end_date` string, date-time, nullable, required: Date-time until which the rule is active. Can be `null`.
  - `trigger_limits` object, required: Cooldown and frequency limits applied to the earning rule trigger.
    - `cooldown` object, required: 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` LoyaltyV2ActivityEarningRuleTriggerLimitsCooldownFixedCooldownPeriod, 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` object, required: 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` LoyaltyV2ActivityEarningRuleTriggerLimitsFrequencyLimitTimeBasedCurrentPeriod: Current calendar period unit for the frequency limit.
            - `unit` 'DAY' | 'WEEK' | 'MONTH' | 'QUARTER' | 'YEAR', required: Calendar period unit.
        - `triggers` LoyaltyV2ActivityEarningRuleTriggerLimitsFrequencyLimitTimeBasedTriggers, required: Maximum number of triggers allowed within the period.
          - `max` integer, required: Maximum number of triggers per period.
  - `earning_limits` LoyaltyV2ActivityEarningRuleEarningLimits, required: Limits on points earned through this rule. Always present. Defaults to `{ "global": { "type": "NO_LIMIT", "limits": [] } }`. Unlike card definition earning limits, this object has no `transactions` key.
    - `global` LoyaltyV2ActivityEarningRuleEarningLimitsGlobal, required: Global (per member, across this rule) earning limits. With `NO_LIMIT`, `limits` is an empty array. With `LIMITED`, `limits` contains exactly one `TIME_BASED` limit.
      - `type` 'NO_LIMIT' | 'LIMITED', required: Whether global earning limits apply.
      - `limits` LoyaltyV2ActivityEarningRuleEarningLimitsGlobalLimit[]: Earning limits (at most one). Empty array when `type` is `NO_LIMIT`.
        - `type` 'TIME_BASED', required: Earning limit variant.
        - `period` LoyaltyV2ActivityEarningRuleEarningLimitsGlobalTimeBasedPeriod, required: Time-based earning limit period. Currently only `CURRENT_PERIOD` is supported; when selected, `current_period` is required.
          - `type` 'CURRENT_PERIOD', required: Period type.
          - `current_period` LoyaltyV2ActivityEarningRuleEarningLimitsGlobalTimeBasedCurrentPeriod: Current calendar period unit for the earning limit.
            - `unit` 'DAY' | 'WEEK' | 'MONTH' | 'QUARTER' | 'YEAR', required: Calendar period unit.
        - `points` LoyaltyV2ActivityEarningRuleEarningLimitsGlobalTimeBasedPoints, required: Maximum points that can be earned in the period.
          - `max` integer, required: Maximum points in the period.
  - `metadata` LoyaltyV2ActivityMetadata, required: Arbitrary key-value metadata; any JSON object is accepted.
  - `created_at` string, date-time, required: Creation timestamp (ISO 8601).
  - `updated_at` string, date-time, nullable, required: Last update timestamp (ISO 8601). `null` when never updated.
  - `object` 'earning_rule', required: Object type marker. Always `earning_rule`.

## Other responses

- `404`: The earning rule doesn't exist. A deleted earning rule is not found. `key` is `not_found` and `resource_type` is `earning_rule`.
- `500`: Internal server error.

## Changes

- **2026-10-14** (v2) `d29b33490051`: 8 breaking, 8 info
  - the `allOf[#/components/schemas/EarningRuleResponse]/earnings/items/effects/items/allOf[subschema #3]/then/points_proportional/custom_event` response's property type changed from `object` to no type for status `200`
  - the `allOf[#/components/schemas/EarningRuleResponse]/earnings/items/effects/items/allOf[subschema #3]/then/points_proportional/customer` response's property type changed from `object` to no type for status `200`
  - the `allOf[#/components/schemas/EarningRuleResponse]/earnings/items/effects/items/points_proportional/custom_event` response's property type changed from `object` to no type for status `200`
  - the `allOf[#/components/schemas/EarningRuleResponse]/earnings/items/effects/items/points_proportional/customer` response's property type changed from `object` to no type for status `200`
  - …12 more
- …earlier changes not shown

[Operation history](https://skmtc.dev/voucherifyio/apis/voucherify-loyalty-v2-api/changes/v2/loyalties/earning-rules/:earningRuleId/get.md)

---

[API](https://skmtc.dev/voucherifyio/apis/voucherify-loyalty-v2-api.md) - [All operations](https://skmtc.dev/voucherifyio/apis/voucherify-loyalty-v2-api/llms.txt) - [OpenAPI document](https://skmtc.dev/voucherifyio/apis/voucherify-loyalty-v2-api/revisions/e0d9f2d2532f?raw)
