Reward Networks Reward Networks Developer Hub

Customers & members

Every Reward Networks user has one account across all merchants. A member is a user who has joined your merchant; only members earn and redeem there.

Look up a customer

Scope: customers.read.

curl "https://staging.app.rewards.network/api/partner/v1/customers/lookup?phone=0123456789" -H "Authorization: Bearer rn_live_..."
curl "https://staging.app.rewards.network/api/partner/v1/customers/lookup?email=jane@example.com" -H "Authorization: Bearer rn_live_..."
curl "https://staging.app.rewards.network/api/partner/v1/customers/lookup?code=RN-000123" -H "Authorization: Bearer rn_live_..."

Exactly one of phone, email, code. code accepts the customer code shown in the app (RN-000123), the full QR string (CUST-LOYALTY-ID-RN-000123) or a bare user_id.

{
  "success": true,
  "message": "Customer retrieved successfully",
  "data": {
    "user_id": 123,
    "full_name": "Jane Doe",
    "email": "jane@example.com",
    "phone": "0123456789",
    "is_member": true,
    "points_balance": 640,
    "stamps_balance": 5
  }
}

404 Customer not found when nothing matches. Staff and merchant accounts are never returned.

Contact details are complete only for members of your merchant. A non-member found by phone or email keeps their full_name, but email and phone come back masked (j***@example.com, 60******789); a non-member found by code is shown as "Jane D." with masked contacts. phone must contain at least 8 digits (422 otherwise); 60…, 0… and +60 … forms of the same Malaysian number all match, other country codes must be given as stored.

Balance

curl "https://staging.app.rewards.network/api/partner/v1/customers/123/balance" -H "Authorization: Bearer rn_live_..."
{ "success": true, "data": { "user_id": 123, "is_member": true, "points_balance": 640, "stamps_balance": 5 } }

Balances are always for the key's merchant and only for its members — any other user_id answers 404. Points held by an open redemption are still included here; redeem-options shows the on_hold part separately.

Enroll a member

Scope: members.write.

Customers normally join a merchant from the app. Enroll them from the till when they ask, or when a non-member scans at your counter:

curl -X POST "https://staging.app.rewards.network/api/partner/v1/members/add" \
  -H "Authorization: Bearer rn_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "user_id": 123, "branch_id": 45 }'
{
  "success": true,
  "message": "Member added successfully",
  "data": { "membership_id": 7781, "user_id": 123, "merchant_id": 7, "branch_id": 45, "status": "ACTIVE", "approved_source": "SYSTEM", "...": "..." },
  "already_member": false
}

Idempotent: an existing member answers "already_member": true with the existing membership. A new membership fires the membership.created webhook.

Enrolling needs proof that the customer is at the till: a qr/validate of their QR or a customers/lookup by phone/email within the last 15 minutes. Without it the call answers 403 with "code": "SCAN_REQUIRED" (a lookup by code alone does not count).

transactions/commit does not enroll automatically. If is_member is false after a scan, call members/add first (or ask the customer to join in the app), then commit.