Set up a loyalty program

Learn how to create, configure, and publish a loyalty program via the Brevo API.

Overview

This guide walks through creating and configuring a loyalty program via API — from creation through to publishing. You can also configure programs in the Brevo UI (Loyalty > Programs) and use the API exclusively for runtime operations.


Authentication

All Loyalty API requests require your Brevo API key as a request header.

$-H "api-key: YOUR_API_KEY"
$-H "Content-Type: application/json"

Retrieve your API key from Settings > API Keys in the Brevo app, or at app.brevo.com/settings/keys/api.

Never expose your API key in client-side code. All Loyalty API calls must be made server-side.


Steps

1

Create the program

Endpoint: POST https://api.brevo.com/v3/loyalty/config/programs

$curl --request POST \
> --url https://api.brevo.com/v3/loyalty/config/programs \
> --header 'api-key: YOUR_API_KEY' \
> --header 'content-type: application/json' \
> --data '{
> "name": "VIP Club",
> "description": "Earn points on every purchase and unlock exclusive rewards."
> }'

Request parameters

ParameterTypeRequiredDescription
namestringYesProgram name, max 128 characters
descriptionstringNoCustomer-facing description, max 256 characters
documentIdstringNoOptional external document reference
metaobjectNoArbitrary key-value metadata

Response (200)

1{
2 "id": "27xxdd7a-af67-0020-ba65-19d60000a26e",
3 "name": "VIP Club",
4 "description": "Earn points on every purchase and unlock exclusive rewards.",
5 "state": "inactive",
6 "createdAt": "2025-03-01T10:00:00.000Z",
7 "updatedAt": "2025-03-01T10:00:00.000Z"
8}

Save the returned id — you will use it as {pid} (program ID) in all subsequent calls.

state starts as inactive. Members cannot be enrolled until the program is published in Step 4.

2

Define a balance definition

Endpoint: POST https://api.brevo.com/v3/loyalty/config/programs/{pid}/balance-definitions

$curl --request POST \
> --url https://api.brevo.com/v3/loyalty/config/programs/27xxdd7a-.../balance-definitions \
> --header 'api-key: YOUR_API_KEY' \
> --header 'content-type: application/json' \
> --data '{
> "name": "Purchase Points",
> "unit": "points",
> "expiryPolicy": {
> "type": "rolling",
> "duration": 12,
> "unit": "month"
> },
> "roundingPolicy": "round_half_up"
> }'

Request parameters

ParameterTypeRequiredDescription
namestringYesInternal name for this balance type
unitstringYesDisplay label shown to members (e.g. "points", "€")
expiryPolicy.typestringNonever, rolling (from last activity), fixed (calendar date each year), or inactivity-based (after N months without purchase)
expiryPolicy.duration + unitint + stringFor rolling / inactivityDuration before expiry (e.g. 12, "month")
roundingPolicystringNonone (maintain decimals), round_half_up (nearest), floor (always round down), or ceiling (always round up)
maxBalancenumberNoMaximum balance cap. Credits are refused once this limit is reached — triggers a balance_transaction_unauthorized event.
minBalancenumberNoMinimum balance threshold. Falling below this value can trigger automations.
maxCreditPerOperationnumberNoMaximum amount that can be credited in a single transaction.
maxDebitPerOperationnumberNoMaximum amount that can be debited in a single transaction.
creditFrequencyLimitobjectNoMaximum number of credit operations allowed per period.
debitFrequencyLimitobjectNoMaximum number of debit operations allowed per period.
3

Configure tier groups (optional)

Endpoint: POST https://api.brevo.com/v3/loyalty/config/programs/{pid}/tier-groups

$curl --request POST \
> --url https://api.brevo.com/v3/loyalty/config/programs/27xxdd7a-.../tier-groups \
> --header 'api-key: YOUR_API_KEY' \
> --header 'content-type: application/json' \
> --data '{
> "name": "VIP Levels",
> "balanceDefinitionId": "{balanceDefinitionId}",
> "upgradeEvaluationTrigger": "real_time",
> "downgradeEvaluationTrigger": "membership_anniversary",
> "tiers": [
> { "name": "Bronze", "threshold": 0 },
> { "name": "Silver", "threshold": 300 },
> { "name": "Gold", "threshold": 500 }
> ]
> }'

Tier group parameters

ParameterTypeRequiredDescription
namestringYesInternal name for the tier group
balanceDefinitionIdstring (UUID)YesThe balance definition this tier group is evaluated against
upgradeEvaluationTriggerstringYesWhen a member is evaluated for a higher tier
downgradeEvaluationTriggerstringYesWhen a member is evaluated for a lower tier
tiersarrayYesOrdered list of tiers. Each tier requires name and threshold.

Tier evaluation trigger options

ValueDescriptionRecommended use
real_timeTier re-evaluated on every completed transactionUpgrades — reward immediately
membership_anniversaryRe-evaluated once a year on enrollment anniversaryDowngrades — avoid mid-year status loss
tier_anniversaryRe-evaluated once a year on tier entry anniversaryWhen tier-year tracking matters

Set upgradeEvaluationTrigger: real_time and downgradeEvaluationTrigger: membership_anniversary. This upgrades members instantly while protecting them from losing status mid-year.

Tier thresholds within the same group must be unique — two tiers cannot share the same entry point. Any threshold change requires re-publishing the program.

4

Publish the program

Endpoint: POST https://api.brevo.com/v3/loyalty/config/programs/{pid}/publish

$curl --request POST \
> --url https://api.brevo.com/v3/loyalty/config/programs/27xxdd7a-.../publish \
> --header 'api-key: YOUR_API_KEY'

Response (200): Returns the updated program object with "state": "active".

Any configuration changes made after publishing — to tiers, balance definitions, or rewards — require calling /publish again before they take effect for members.