Best practices
Integration best practices
Always enroll before crediting
Attempting to create a transaction for a contact who is not subscribed to the program returns a 422. Enroll the contact first, then credit points.
Use loyaltySubscriptionId as your bridge
Set loyaltySubscriptionId to your own customer ID at enrollment time. This lets you reference the member by your internal ID throughout the integration and pass it in eCommerce order identifiers — without maintaining a separate ID mapping table.
Use autoComplete: false for purchase flows, autoComplete: true for instant rewards
Purchase points should only be confirmed after the order is validated. Bonus credits (sign-up, birthday, referral) have no approval step and can be auto-completed.
Store transaction IDs
Always persist the id returned by Create transaction or Create balance order. You need it to call /complete or /cancel. If you lose it, you will need to query the transaction list to retrieve it.
Use meta to store your business context
Pass orderId, campaignId, or any relevant reference in the meta field. This makes debugging and auditing easier and keeps your transaction history self-documenting.
Never call Complete on an already-completed transaction
This returns a 422. Check the transaction status before completing: if it is not pending, skip the call.
Performance considerations
Parallelize read calls
The balance, tier, and voucher read endpoints are independent. Use concurrent requests to build your loyalty widget — do not chain them sequentially. See Read member data for an example.
Cache member data for display purposes
Balance and tier data do not change in real time on your frontend. Cache responses for 30–60 seconds to reduce API calls on high-traffic account pages.
Use webhooks instead of polling
Never poll the transaction endpoint to detect completion. Use the balance_value_updated webhook to trigger downstream actions. See Loyalty webhooks.
Set appropriate ttl on pending transactions
If your order confirmation flow takes up to 24 hours, set ttl: 1440 (minutes). This prevents orphaned pending transactions from accumulating if your system fails to call /complete or /cancel.
Security best practices
Keep API keys server-side
Never expose your api-key in browser JavaScript, mobile app binaries, or public repositories. All Loyalty API calls must originate from your backend.
Validate webhook signatures
Configure secure webhook calls with username and password authentication to verify that incoming webhooks originate from Brevo.
Scope API keys by environment
Use separate API keys for staging and production. Rotate keys immediately if you suspect exposure.
Audit meta fields
Treat meta as an internal field — never expose it raw to end users, as it may contain internal order references or pricing data.
Use cases
Points on purchase (eCommerce)
A fashion retailer credits 1 point per €1 spent on confirmed orders.
Referral program
A beauty brand gives 200 points to a member who refers a friend who completes their first purchase.
Birthday reward
A loyalty program sends a 50-point bonus 7 days before a member’s birthday.
Loyalty widget on account page
A retailer displays a loyalty status block on the customer account page.
Points expiry re-engagement
A program where points expire after 12 months. Trigger a winback campaign 30 days before expiry.