# Loyalty Accounts

> Create, retrieve, update, and list loyalty accounts that link customers to the VINR loyalty programme.

A loyalty account links a customer to the loyalty programme and tracks their current points balance
and tier membership. One account is created per customer per programme.

> **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 loyalty account object

- **id** `string` — Unique identifier for the loyalty account, e.g. `la_4Kp9bQ`.
- **customer** `object` (expandable) — The customer this loyalty account belongs to. Expand to retrieve the full object.
  - **id** `string` — Customer identifier, e.g. `cust_8aZ2`.
  - **email** `string` — Email address on the customer record.
- **points\_balance** `integer` — Current points balance. Never goes below zero.
- **tier** `object` (expandable) — The tier this account currently qualifies for. Expand to retrieve the full tier object.
  - **id** `string` — Tier identifier, e.g. `tier_silver`.
  - **name** `string` — Human-readable tier name, e.g. `Silver`.
- **programme\_id** `string` — The loyalty programme this account belongs to.
- **created** `integer` — Unix timestamp of when the account was created.

## Create a loyalty account

Enrolls a customer in the loyalty programme. Pass the customer ID and an optional programme ID (the
default programme is used when omitted).

`POST /v1/loyalty-accounts`

```bash
curl -X POST https://api.vinr.com/v1/loyalty-accounts \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-d customer=cust_8aZ2 \
-d programme_id=prog_default
```

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

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

const loyaltyAccount = await vinr.loyaltyAccounts.create({
customer: 'cust_8aZ2',
programme_id: 'prog_default',
});
```

```python
import vinr

loyalty_account = vinr.LoyaltyAccount.create(
  customer="cust_8aZ2",
  programme_id="prog_default",
)
```

```ruby
loyalty_account = Vinr::LoyaltyAccount.create(
customer: 'cust_8aZ2',
programme_id: 'prog_default',
)
```

```json
{
"id": "la_4Kp9bQ",
"customer": "cust_8aZ2",
"points_balance": 0,
"tier": "tier_bronze",
"programme_id": "prog_default",
"created": 1716300000
}
```

## Retrieve a loyalty account

Fetch a loyalty account by its ID. Pass `expand[]=customer` or `expand[]=tier` to inline the full
linked objects.

`GET /v1/loyalty-accounts/{id}`

```bash
curl "https://api.vinr.com/v1/loyalty-accounts/la_4Kp9bQ?expand[]=tier" \
-H "X-Api-Key: $VINR_SECRET_KEY"
```

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

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

const loyaltyAccount = await vinr.loyaltyAccounts.retrieve('la_4Kp9bQ', {
expand: ['tier'],
});
```

```python
import vinr

loyalty_account = vinr.LoyaltyAccount.retrieve(
  "la_4Kp9bQ",
  expand=["tier"],
)
```

```ruby
loyalty_account = Vinr::LoyaltyAccount.retrieve(
'la_4Kp9bQ',
expand: ['tier'],
)
```

```json
{
"id": "la_4Kp9bQ",
"customer": "cust_8aZ2",
"points_balance": 1250,
"tier": {
  "id": "tier_silver",
  "name": "Silver",
  "min_points": 1000
},
"programme_id": "prog_default",
"created": 1716300000
}
```

## Update a loyalty account

Update mutable fields on a loyalty account. Currently supports overriding the `tier` for manual
tier assignments outside the automatic promotion rules.

`POST /v1/loyalty-accounts/{id}`

```bash
curl -X POST https://api.vinr.com/v1/loyalty-accounts/la_4Kp9bQ \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-d tier=tier_gold
```

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

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

const loyaltyAccount = await vinr.loyaltyAccounts.update('la_4Kp9bQ', {
tier: 'tier_gold',
});
```

```python
import vinr

loyalty_account = vinr.LoyaltyAccount.modify(
  "la_4Kp9bQ",
  tier="tier_gold",
)
```

```ruby
loyalty_account = Vinr::LoyaltyAccount.update(
'la_4Kp9bQ',
tier: 'tier_gold',
)
```

```json
{
"id": "la_4Kp9bQ",
"customer": "cust_8aZ2",
"points_balance": 1250,
"tier": "tier_gold",
"programme_id": "prog_default",
"created": 1716300000
}
```

## List loyalty accounts

Returns a paginated list of loyalty accounts, newest first. Use `customer` to scope results to a
single customer.

| Parameter  | Type    | Description                                           |
| ---------- | ------- | ----------------------------------------------------- |
| `customer` | string  | Filter accounts by customer ID.                       |
| `limit`    | integer | Number of results to return. Default `10`, max `100`. |

`GET /v1/loyalty-accounts`

```bash
curl "https://api.vinr.com/v1/loyalty-accounts?customer=cust_8aZ2&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 accounts = await vinr.loyaltyAccounts.list({
customer: 'cust_8aZ2',
limit: 10,
});
```

```python
import vinr

accounts = vinr.LoyaltyAccount.list(
  customer="cust_8aZ2",
  limit=10,
)
```

```ruby
accounts = Vinr::LoyaltyAccount.list(
customer: 'cust_8aZ2',
limit: 10,
)
```

```json
{
"object": "list",
"data": [
  {
    "id": "la_4Kp9bQ",
    "customer": "cust_8aZ2",
    "points_balance": 1250,
    "tier": "tier_silver",
    "programme_id": "prog_default",
    "created": 1716300000
  }
],
"has_more": false
}
```

## Related events

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