# Earning Rules

> Create, retrieve, update, delete, and list the rules that govern how customers earn loyalty points.

An earning rule defines how customers accumulate points in response to platform events. The most
common rule awards one point per unit of currency spent when a payment succeeds.

> **Illustrative content.** Hand-authored to demonstrate the Standard/Advanced pattern; the production
> page will be generated from the VINR OpenAPI spec (roadmap item #1). Field names are representative.

## The earning rule object

- **id** `string` — Unique identifier for the earning rule, e.g. `er_2Gb7wJ`.
- **name** `string` — Human-readable label for the rule, e.g. `1 point per €1 spent`.
- **event** `string` — The platform event that triggers point accrual, e.g. `payment.succeeded`.
- **points\_per\_unit** `integer` — Number of points awarded for each qualifying unit of the triggering event.
- **unit\_value** `integer` — The size of one unit in the smallest currency denomination (e.g. `100` = 100 cents = €1).
  Points are awarded in proportion to `amount / unit_value`.
- **active** `boolean` — Whether the rule is currently applied when the trigger event fires.
- **created** `integer` — Unix timestamp of when the earning rule was created.

## Create an earning rule

Define a new rule. Rules take effect immediately for subsequent trigger events once `active` is set
to `true`.

`POST /v1/earning-rules`

```bash
curl -X POST https://api.vinr.com/v1/earning-rules \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-d name="1 point per €1 spent" \
-d event=payment.succeeded \
-d points_per_unit=1 \
-d unit_value=100
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const rule = await vinr.earningRules.create({
name: '1 point per €1 spent',
event: 'payment.succeeded',
points_per_unit: 1,
unit_value: 100,
});
```

```python
import vinr

rule = vinr.EarningRule.create(
  name="1 point per €1 spent",
  event="payment.succeeded",
  points_per_unit=1,
  unit_value=100,
)
```

```ruby
rule = Vinr::EarningRule.create(
name: '1 point per €1 spent',
event: 'payment.succeeded',
points_per_unit: 1,
unit_value: 100,
)
```

```json
{
"id": "er_2Gb7wJ",
"name": "1 point per €1 spent",
"event": "payment.succeeded",
"points_per_unit": 1,
"unit_value": 100,
"active": true,
"created": 1716300000
}
```

## Retrieve an earning rule

Fetch an earning rule by its ID.

`GET /v1/earning-rules/{id}`

```bash
curl https://api.vinr.com/v1/earning-rules/er_2Gb7wJ \
-H "X-Api-Key: $VINR_SECRET_KEY"
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const rule = await vinr.earningRules.retrieve('er_2Gb7wJ');
```

```python
import vinr

rule = vinr.EarningRule.retrieve("er_2Gb7wJ")
```

```ruby
rule = Vinr::EarningRule.retrieve('er_2Gb7wJ')
```

```json
{
"id": "er_2Gb7wJ",
"name": "1 point per €1 spent",
"event": "payment.succeeded",
"points_per_unit": 1,
"unit_value": 100,
"active": true,
"created": 1716300000
}
```

## Update an earning rule

Adjust the earning rate or pause a rule by setting `active: false`.

`POST /v1/earning-rules/{id}`

```bash
curl -X POST https://api.vinr.com/v1/earning-rules/er_2Gb7wJ \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-d points_per_unit=2 \
-d active=true
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const rule = await vinr.earningRules.update('er_2Gb7wJ', {
points_per_unit: 2,
active: true,
});
```

```python
import vinr

rule = vinr.EarningRule.modify(
  "er_2Gb7wJ",
  points_per_unit=2,
  active=True,
)
```

```ruby
rule = Vinr::EarningRule.update(
'er_2Gb7wJ',
points_per_unit: 2,
active: true,
)
```

```json
{
"id": "er_2Gb7wJ",
"name": "1 point per €1 spent",
"event": "payment.succeeded",
"points_per_unit": 2,
"unit_value": 100,
"active": true,
"created": 1716300000
}
```

## Delete an earning rule

Permanently deletes an earning rule. Existing points transactions created by this rule are not
affected.

`DELETE /v1/earning-rules/{id}`

```bash
curl -X DELETE https://api.vinr.com/v1/earning-rules/er_2Gb7wJ \
-H "X-Api-Key: $VINR_SECRET_KEY"
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const deleted = await vinr.earningRules.delete('er_2Gb7wJ');
```

```python
import vinr

deleted = vinr.EarningRule.delete("er_2Gb7wJ")
```

```ruby
deleted = Vinr::EarningRule.delete('er_2Gb7wJ')
```

```json
{
"id": "er_2Gb7wJ",
"deleted": true
}
```

## List earning rules

Returns a paginated list of earning rules. Pass `active=true` to return only currently live rules.

| Parameter | Type    | Description                                           |
| --------- | ------- | ----------------------------------------------------- |
| `active`  | boolean | Filter by active status. Omit to return all rules.    |
| `limit`   | integer | Number of results to return. Default `10`, max `100`. |

`GET /v1/earning-rules`

```bash
curl "https://api.vinr.com/v1/earning-rules?active=true&limit=10" \
-H "X-Api-Key: $VINR_SECRET_KEY"
```

```js
import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

const rules = await vinr.earningRules.list({
active: true,
limit: 10,
});
```

```python
import vinr

rules = vinr.EarningRule.list(
  active=True,
  limit=10,
)
```

```ruby
rules = Vinr::EarningRule.list(
active: true,
limit: 10,
)
```

```json
{
"object": "list",
"data": [
  {
    "id": "er_2Gb7wJ",
    "name": "1 point per €1 spent",
    "event": "payment.succeeded",
    "points_per_unit": 2,
    "unit_value": 100,
    "active": true,
    "created": 1716300000
  }
],
"has_more": false
}
```

## Related events

`earning_rule.created`, `earning_rule.updated`, and `earning_rule.deleted`. See [Events](/docs/api-reference/events).
