Members

Members are auto-created on first evaluate() call — you never need to pre-register customers. Use these endpoints to look up balances, view transaction history, manage state, and handle POPIA right-to-erasure requests.

Member states

active → suspended → active
active → anonymized (terminal, POPIA erasure)

Endpoints

GET
/tenants/{tenantId}/members

List all members. Use ?ref=<externalRef> for an exact lookup, or ?search= for substring match. Keyset paginated.

GET
/tenants/{tenantId}/members/{memberId}

Get a member by internal UUID — includes balance, tier, and state.

PATCH
/tenants/{tenantId}/members/{memberId}

Update member profile — name, email, or phone. Triggers POPIA-safe field logging.

POST
/tenants/{tenantId}/members/{memberId}/suspend

Suspend a member. Suspended members get 403 on evaluate() and redeem().

POST
/tenants/{tenantId}/members/{memberId}/reinstate

Reinstate a suspended member.

DELETE
/tenants/{tenantId}/members/{memberId}

POPIA right to erasure — anonymises all personal data. Points history retained for audit.

GET
/tenants/{tenantId}/members/{memberId}/ledger

Full points ledger — EARN, REDEEM, EXPIRE, and ADJUST entries. Keyset paginated.

POST
/tenants/{tenantId}/members/{memberId}/ledger/adjust

Manual points adjustment with a reason string. Recorded as ADJUST in the ledger.

GET
/tenants/{tenantId}/members/{memberId}/rewards

List the member's issued rewards — vouchers, gift cards, and points rewards.

GET
/tenants/{tenantId}/members/{memberId}/stamp-cards

List stamp card progress for STAMP_CARD campaigns.

POST
/tenants/{tenantId}/consent

Record POPIA consent — required before using personal data for marketing.

Ledger Entry Types

EARNPoints awarded from an evaluate() transaction
REDEEMPoints deducted by a redeem() transaction
EXPIREPoints removed by the nightly expiry worker
ADJUSTManual adjustment with reason string (admin action)

POPIA — right to erasure

DELETE /members/{memberId} anonymises the member: name, email, phone, and externalRef are overwritten with hashed placeholders. Points ledger rows are retained for financial audit. The member state becomes anonymized and is excluded from all future evaluate() calls.

Look up by customer ref

cURL
# Look up by your customer reference
curl "https://loyalty-engine-production-e5cb.up.railway.app/v1/tenants/$TENANT_ID/members?ref=customer_27821234567" \
  -H "X-API-Key: sk_test_YOUR_KEY"

Member response

200 OK
{
  "id":             "9f4c2e8a-1b2c-3d4e-5f6a-7b8c9d0e1f2a",
  "tenantId":       "tenant-uuid",
  "externalRef":    "customer_27821234567",
  "pointsBalance":  1450,
  "lifetimePoints": 3200,
  "tierId":         "tier-uuid-3",
  "state":          "active",
  "enrolledAt":     "2026-01-10T08:22:00.000Z",
  "lastActivityAt": "2026-05-20T14:30:00.000Z",
  "createdAt":      "2026-01-10T08:22:00.000Z",
  "updatedAt":      "2026-05-20T14:30:00.000Z"
}

Points ledger

cURL
curl "https://loyalty-engine-production-e5cb.up.railway.app/v1/tenants/$TENANT_ID/members/$MEMBER_ID/ledger" \
  -H "X-API-Key: sk_test_YOUR_KEY"
200 OK
{
  "entries": [
    {
      "id":            "e1f2a3b4-...",
      "tenantId":      "tenant-uuid",
      "memberId":      "9f4c2e8a-...",
      "transactionId": "d2f3a1b4-...",
      "type":          "EARN",
      "points":        150,
      "balanceAfter":  1450,
      "description":   "Spend & Earn — receipt_001",
      "expiresAt":     null,
      "createdAt":     "2026-05-20T14:30:00.000Z"
    },
    {
      "id":            "d0e1f2a3-...",
      "tenantId":      "tenant-uuid",
      "memberId":      "9f4c2e8a-...",
      "transactionId": "a1b2c3d4-...",
      "type":          "REDEEM",
      "points":        -500,
      "balanceAfter":  1300,
      "description":   "Redemption — redeem_001",
      "expiresAt":     null,
      "createdAt":     "2026-05-18T10:15:00.000Z"
    }
  ],
  "nextCursor": null
}
Members — API Reference