Read member data

Learn how to fetch a member's balance, tier status, vouchers, and transaction history.
View as Markdown

Overview

Use these endpoints to power loyalty widgets in your storefront, mobile app, or customer account page. All read endpoints are independent — make them in parallel for best performance.


Get current balance

Endpoint: GET https://api.brevo.com/v3/loyalty/balance/programs/{pid}/subscriptions/{cid}/balances

curl --request GET \
--url 'https://api.brevo.com/v3/loyalty/balance/programs/27xxdd7a-.../subscriptions/12345/balances?includeInternal=false' \
--header 'api-key: YOUR_API_KEY'

Query parameters

ParameterTypeRequiredDescription
includeInternalbooleanNoIf true, includes balances tied to internal balance definitions. Defaults to false.

Response (200)

{
"loyaltyProgramId": "27xxdd7a-af67-0020-ba65-19d60000a26e",
"contactId": 12345,
"balance": [
{
"balanceDefinitionId": "a74cxx1d-4a96-4xx3-804e-dc3xxd9axxeb",
"value": 340
}
]
}

balance is an array — one entry per balance definition configured on the program. To display a definition’s name or unit alongside its value, cross-reference balanceDefinitionId against GET /loyalty/balance/programs/{pid}/balance-definitions.


Get current tier

There is no single endpoint that returns a member’s current tier directly. Compute it client-side from two calls:

  1. GET /loyalty/balance/programs/{pid}/subscriptions/{cid}/balances (above) for the member’s current balance value.
  2. GET /loyalty/tier/programs/{pid}/tier-groups/{gid}/tiers for the tier group’s configured tiers and their accessConditions thresholds (each tier’s minimum balance per balanceDefinitionId).
curl --request GET \
--url https://api.brevo.com/v3/loyalty/tier/programs/27xxdd7a-.../tier-groups/2exxx6ee-.../tiers \
--header 'api-key: YOUR_API_KEY'

Match the member’s balance against each tier’s accessConditions[].minimumValue to find their current tier and the next threshold to reach.

Tiers are otherwise only assigned via the API — POST /loyalty/tier/programs/{pid}/contacts/{cid}/tiers/{tid} manually assigns a tier to a membership. There is no corresponding read endpoint for a single member’s assignment.


Get available vouchers

Endpoint: GET https://api.brevo.com/v3/loyalty/offer/programs/{pid}/vouchers

contactId is a required query parameter (not a path segment).

curl --request GET \
--url 'https://api.brevo.com/v3/loyalty/offer/programs/27xxdd7a-.../vouchers?contactId=12345' \
--header 'api-key: YOUR_API_KEY'

Query parameters

ParameterTypeRequiredDescription
contactIdintegerYesContact ID to fetch vouchers for
limitintegerNoPage size. Default 25, max 100.
offsetintegerNoPagination offset. Default 0.
sortstringNoasc or desc. Default desc.
sortFieldstringNoupdatedAt or createdAt. Default updatedAt.

Response (200)

{
"contactId": 12345,
"loyaltyProgramId": "27xxdd7a-af67-0020-ba65-19d60000a26e",
"loyaltySubscriptionId": "sub_xyz789",
"count": 1,
"contactRewards": [
{
"id": "3c000afd-fb2e-4275-9007-29178f00fd5a",
"code": "GOLD10",
"rewardId": "29xx7df8-3cf3-4x5c-8e74-8cd00085000e",
"unit": "percent",
"value": 10,
"validFrom": "2025-11-01T00:00:00.000Z",
"expirationDate": "2025-12-31T23:59:59.000Z",
"consumedAt": null,
"createdAt": "2025-11-01T00:00:00.000Z",
"updatedAt": "2025-11-01T00:00:00.000Z",
"meta": {}
}
]
}

Get transaction history

Endpoint: GET https://api.brevo.com/v3/loyalty/balance/programs/{pid}/transaction-history

contactId and balanceDefinitionId are both required query parameters.

curl --request GET \
--url 'https://api.brevo.com/v3/loyalty/balance/programs/27xxdd7a-.../transaction-history?contactId=12345&balanceDefinitionId=a74cxx1d-4a96-4xx3-804e-dc3xxd9axxeb&status=completed&transactionType=credit&limit=20&offset=0' \
--header 'api-key: YOUR_API_KEY'

Query parameters

ParameterTypeRequiredDescription
contactIdintegerYesContact ID to fetch history for
balanceDefinitionIdstring (UUID)YesWhich balance definition to fetch history for
limitintegerNoMax transactions to return (1–500).
offsetintegerNoPage number to retrieve (not a record skip count). Default 0.
statusstringNoFilter by transaction status. Allowed values: draft, completed, rejected, cancelled, expired.
transactionTypestringNoFilter by transaction type. Allowed values: credit, debit.
sortFieldstringNocreatedAt (default and only supported value).
sortstringNoasc or desc.

Response (200)

{
"loyaltyProgramId": "27xxdd7a-af67-0020-ba65-19d60000a26e",
"contactId": 12345,
"balanceDefinitionId": "a74cxx1d-4a96-4xx3-804e-dc3xxd9axxeb",
"count": 1,
"transactionHistory": [
{
"amount": 50,
"transactionType": "credit",
"completedAt": "2025-03-01T10:05:00.000Z",
"cancelledAt": null,
"balanceExpirationDate": null
}
]
}

Building a loyalty widget

A standard loyalty account widget combines two parallel calls, plus the tier lookup from the previous section:

1. GET .../subscriptions/{cid}/balances → "You have 340 points"
2. GET .../tier-groups/{gid}/tiers → compute "Silver member · 160 pts to Gold"
3. GET .../offer/programs/{pid}/vouchers → "1 reward available · GOLD10"

Make the balance and voucher calls in parallel — each is independent. The tier lookup can be cached far longer than the other two, since a tier group’s thresholds change rarely.

const headers = { 'api-key': API_KEY };
const [balances, vouchers] = await Promise.all([
fetch(`https://api.brevo.com/v3/loyalty/balance/programs/${programId}/subscriptions/${contactId}/balances`, { headers }).then(r => r.json()),
fetch(`https://api.brevo.com/v3/loyalty/offer/programs/${programId}/vouchers?contactId=${contactId}`, { headers }).then(r => r.json()),
]);
// Render: "340 pts · 1 reward available"

Cache balance responses for 30–60 seconds on high-traffic account pages — these only change when a transaction is completed, so near-real-time staleness is acceptable for display purposes. Tier-group thresholds can be cached far longer (minutes to hours), since they only change when you edit the program’s configuration.