# Get customer loyalty points

The points balance of a customer, and their last 50 movements.

```http
GET https://larm.sa/stores/{storeId}/v1/customers/{id}/loyalty
```

Scope: `loyalty:read`

A customer who never earned a point has a balance of 0 and no movements. `points` in a movement is positive when points are added and negative when they are removed. See [Customers and loyalty](/guides/customers-and-loyalty).

## Path parameters

| Field | Type | Required | Description |
|---|---|---|---|
| `id` | string | yes |  |


## Response

| Field | Type | Required | Description |
|---|---|---|---|
| `data` | object | yes |  |
| `data.customer_id` | string | yes |  |
| `data.balance` | integer | yes | The points balance now. |
| `data.lifetime_earned` | integer | yes |  |
| `data.lifetime_spent` | integer | yes |  |
| `data.transactions` | array<object> | yes | The last 50 movements, newest first. |
| `data.transactions[].type` | string | no | One of: `earn`, `welcome`, `adjustment`, `reserve`, `release`, `refund`, `reversal`, `expire`. |
| `data.transactions[].points` | integer | no | Positive adds points, negative removes them. |
| `data.transactions[].balance_after` | integer | no |  |
| `data.transactions[].order_id` | string \| null | no |  |
| `data.transactions[].reason` | string | no |  |
| `data.transactions[].created_at` | string (date-time) | no |  |
| `execution` | object | no | Who executed the request: the app, version, installation and store. Field names here are camelCase. |
| `execution.appId` | string (uuid) | no |  |
| `execution.versionId` | string (uuid) | no |  |
| `execution.installationId` | string (uuid) | no |  |
| `execution.storeId` | string (uuid) | no |  |
| `execution.requestId` | string (uuid) | no |  |
| `execution.generation` | integer | no |  |
| `execution.routeEpoch` | integer | no |  |
| `execution.appAuthEpoch` | integer | no |  |
| `execution.grantRevision` | integer | no |  |
| `meta` | object | yes |  |
| `meta.request_id` | string (uuid) | no | The request ID; include it in any support request. |


## Example request

```bash
curl -X GET "https://larm.sa/stores/$STORE_ID/v1/customers/5821/loyalty" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```


## Example response (200)

```json
{
  "data": {
    "customer_id": "5821",
    "balance": 150,
    "lifetime_earned": 200,
    "lifetime_spent": 50,
    "transactions": [
      {
        "type": "earn",
        "points": 90,
        "balance_after": 150,
        "order_id": "200123",
        "reason": "",
        "created_at": "2026-10-15T09:13:01Z"
      }
    ]
  },
  "execution": {
    "appId": "1f2e3d4c-5b6a-4978-8695-a4b3c2d1e0f9",
    "versionId": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "installationId": "c7e4a1f2-6b3d-4e8a-9c05-1d2f3a4b5c6d",
    "storeId": "5b1d7a62-0c4e-4f38-9a51-2e7b3c9d8f10",
    "requestId": "3f0c2b8e-7a51-4c1e-9d0a-5b6f1e2d4c3a",
    "generation": 1,
    "routeEpoch": 4,
    "appAuthEpoch": 1,
    "grantRevision": 2
  },
  "meta": {
    "request_id": "3f0c2b8e-7a51-4c1e-9d0a-5b6f1e2d4c3a"
  }
}
```


## Errors

| HTTP | Code | Meaning |
|---|---|---|
| 404 | `RESOURCE_NOT_FOUND` | The ID does not exist in this store. |
| 403 | `SCOPE_REQUIRED` | The token does not carry the required scope. |
| 503 | `APPS_SCOPE_RUNTIME_NOT_READY` | The resource is not enabled on this merchant's store yet. |
