Integrate a loyalty platform
Learn how to integrate a loyalty platform with Klaviyo.
Overview
This resource will help you as you build an integration between a loyalty platform and Klaviyo. It walks through the recommended integration flow, the profile properties and events to sync, and the authentication and certification requirements, with an API quick reference at the end.
Why connect your loyalty platform to Klaviyo
Loyalty data is the highest-signal layer a merchant has on a customer. It knows who's enrolled, how engaged they are, what tier they're in, and what they're close to earning. The merchants who get the most out of their loyalty program run it through their email and SMS platform, not in isolation. When that platform is Klaviyo and the data lives there natively, you get measurable wins:
- Tier and points-based segmentation. "VIPs who haven't ordered in 30 days," "Silver members within 10% of Gold," "members with more than 500 points and no recent redemption." These outperform list-only sends across every comparison we have.
- Lifecycle moments that drive repeat purchase. Tier upgraded, points expiring, reward issued, reward expiring. These are some of the highest-converting messages in the Klaviyo ecosystem.
- Suppression of inactive members. Stop paying to send to profiles who unsubscribed inside your platform. Stop wasting reward emails on customers who haven't engaged in a year.
- Stickier merchants. A live loyalty integration is consistently one of the strongest retention signals across the partner program. Merchants who set up tier-based segments rarely churn out of either platform.
Short version: properties and events from your platform into the Klaviyo profile means the merchant's marketing team can act on loyalty data from the same place they run every other channel.
The flow
One-way push, partner to Klaviyo, with two concurrent streams:
- Profile property sync for persistent state. Points balance, tier, member status, referral URL. These are the fields the merchant references in segments and personalization.
- Event emission for moments. Points earned, tier upgraded, reward issued, etc. Each event also writes the relevant profile properties inline, so a single API call covers both streams.
Both fire in real time as the underlying activity happens in your platform. Each profile is keyed by email, and by phone where you have it. Use the merchant's customer ID as external_id where it's stable, but always identify by email first.
On initial install, backfill the merchant's existing enrolled members through the bulk profile import job. This sets up the state you need to ship Day 1. Don't try to replay years of historical loyalty activity as events.
Profile properties to sync
Use Title Case property names prefixed with your platform's name. Replace {Platform} below with the literal name of your platform (e.g., "Acme Points Balance", "Acme VIP Tier Name").
This convention keeps your data cleanly namespaced when a merchant runs multiple integrations against the same profile, makes properties self-documenting in the Klaviyo UI, and matches the pattern Klaviyo's own UI uses for surfacing partner data.
| Property | What it is |
|---|---|
| {Platform} Loyalty Member | Boolean. Whether this profile is enrolled in the loyalty program. |
| {Platform} Points Balance | Current redeemable points. Updated on every earn or redeem. |
| {Platform} Lifetime Points | Cumulative points earned, never decremented by redemptions. Powers "close to next tier" segments that survive redemptions. |
| {Platform} VIP Tier Name | Human-readable tier ("Silver", "Gold", "Platinum"). Used for personalization. |
| {Platform} VIP Tier ID | Stable ID for tier. Use this for segment logic so tier renames don't break segments. |
| {Platform} Points Expiring At | Datetime of next points expiry. Drives date-anchored reminders. |
| {Platform} Last Activity At | Datetime of last earn or redeem. Useful for identifying lapsed members. |
| {Platform} Referral URL | The advocate's unique referral link. Required for any "share with a friend" personalization. |
| {Platform} Enrollment Date | When this profile joined the program. |
Implementation notes:
- Profile property writes go through Update Profile (
PATCH /api/profiles/{id}/), or are written inline on Create Event (POST /api/events/). - Pick property names up front and don't rename them. Renames break every segment, flow, and template that references them, and the merchant has to rebuild from scratch.
- Keep dates in ISO 8601 (UTC). Klaviyo will treat string-typed dates as strings, which silently breaks date-property segmentation.
- If a profile already exists with a conflicting older property (e.g., a lowercase variant from a legacy install), an upsert via Bulk Import Profiles (
POST /api/profile-bulk-import-jobs/) keyed on email will clean it up.
Events to send
Event names are not prefixed with your platform name. Branded events handle source attribution automatically when events flow through your OAuth token, so the metric name should just describe the action.
Use Title Case payload field names ("Points Delta", "New Balance") so they read cleanly in the Klaviyo property picker and template editor.
Loyalty events
| Event | When it fires | Payload |
|---|---|---|
| Loyalty Member Enrolled | Customer joins the program. | Program Name, Enrollment Date, Initial Points Balance, Tier At Enrollment |
| Points Earned | Any positive balance change. | Points Delta, Reason (purchase / activity / referral / manual), New Balance, Lifetime Points, Order ID (when applicable) |
| Points Redeemed | Customer redeems points for a reward. | Points Delta (negative), New Balance, Reward ID, Reward Name, Reward Value |
| Points Expiring Soon | N days before expiry. Partner-configurable; default of 14 to 30 days is standard. | Points Expiring, Expiry Date, Current Balance |
| Points Expired | Points removed at expiry. | Points Expired, New Balance |
| Reward Earned | A reward is issued to the customer, including birthday rewards or tier rewards. | Reward ID, Reward Name, Reward Type (coupon / product / shipping / gift card), Reward Value, Expires At, Code (when applicable) |
| Reward Redeemed | Reward applied at checkout. | Reward ID, Reward Name, Reward Value, Order ID |
| Reward Expiring Soon | N days before reward expiry. | Reward ID, Reward Name, Expires At |
| Tier Upgraded | Customer moves up a tier. | New Tier, Previous Tier, Qualifying Metric (lifetime points / spend / orders), Value To Next Tier |
| Tier Downgraded | Customer moves down a tier. | New Tier, Previous Tier, Downgrade Reason |
| Tier Approaching | Customer is within X% of the next tier (partner-configurable; 10% is standard). | Current Tier, Next Tier, Value Remaining, Threshold |
Implementation notes:
POST /api/events/auto-creates the profile if it doesn't exist yet. You do not need to upsert the profile first. This is the right path for any loyalty event.- Each event can update profile properties inline via the profile object on the event payload. Use this to keep balance and tier properties consistent with whatever just happened, in a single call.
- For very high event volume (millions per day), use Bulk Create Events (
POST /api/event-bulk-create-jobs/) for backfills andPOST /api/events/for the real-time hot path. Don't try to bulk every event. The single endpoint is the right default. - Use stable, well-named metric names from Day 1. Renaming a metric later means rebuilding every segment and template that references it.
Referral events
Referrals are a parallel event stream because two distinct profiles are involved. The advocate (existing customer) and the referred friend (often a brand-new profile). Model them as their own metrics so the merchant can target each audience separately.
| Event | When it fires | Payload |
|---|---|---|
| Referral Sent | Advocate shares their referral link or the friend submits their email. | Referral ID, Channel (email / sms / social / link), Advocate Email, Referred Email (when known) |
| Referral Started | Referred friend creates an account or completes first action. Fires on the referred friend's profile (creates one if not present). | Referral ID, Advocate Email, Referred Email |
| Referral Completed | Referred friend makes a qualifying purchase and the advocate's reward is issued. | Referral ID, Advocate Email, Referred Email, Conversion Value, Advocate Reward |
Practical notes:
- Set the {Platform} Referral URL property on every enrolled member. This is what the merchant uses to render "share with a friend" personalization. If the property isn't set on the advocate's profile, the personalization token won't resolve and the email goes out blank or broken.
- When firing Referral Started against a referred friend who isn't yet in Klaviyo, the events endpoint creates the profile. This is the standard way a referral-generated lead lands in Klaviyo.
- Include both Advocate Email and Referred Email on every referral event so the merchant can build segments off either side ("advocates with more than 3 completed referrals," "friends who started a referral but haven't converted in 14 days").
Auth, scopes, and certification
Build as a public OAuth app. Private API keys are a non-starter for the marketplace. Start with the Create a public OAuth app guide.
Key OAuth specifics for loyalty integrations:
- PKCE is required on the authorization code exchange (
code_verifiermust be included). - Access tokens are short-lived (1 hour). Refresh tokens are long-lived but rotate on every use. Persist the latest refresh token after every refresh call, or you'll lose the integration on the next refresh.
- Tokens are scoped per Klaviyo account. Merchants with multiple Klaviyo accounts (brands, regions, prod and test) install separately for each.
Scopes to request:
profiles:readfor reading existing profiles (matching on email and phone before write).profiles:writefor writing loyalty properties to profiles and writing enrolled members on initial backfill.events:writefor emitting loyalty events.lists:readandsegments:readonly if your integration also surfaces Klaviyo audiences in your product (e.g., for the merchant to pick a Klaviyo segment to grant loyalty status to). Don't over-scope. It gets flagged in marketplace review.
Branded metric badges happen automatically when events flow through the OAuth token. No extra payload field is needed. The integration source is identified by the token itself.
Once functional, submit for App Marketplace review. Plan for at least one round of feedback. The review covers OAuth, scopes, install and uninstall validation, and that the integration delivers what your listing claims.
API quick reference
Concrete specs for AI coding assistants and engineers grounding on this doc. The narrative above is the why and the flow. This section is the what-to-actually-type.
Headers (required on every request)
Authorization: Bearer <oauth_access_token>
revision: 2026-04-15
Accept: application/json
Content-Type: application/json
Pin the revision header to a specific date when you ship. Check the API versioning guide for the current latest. Without it you'll get a 400.
Profile property write
PATCH a profile to update loyalty properties. Use email as the primary identifier. Pass external_id as a secondary reference when you have a stable partner-side ID.
PATCH /api/profiles/{id}/
{
"data": {
"type": "profile",
"id": "01HXXX...",
"attributes": {
"email": "[email protected]",
"properties": {
"{Platform} Loyalty Member": true,
"{Platform} Points Balance": 1250,
"{Platform} Lifetime Points": 4870,
"{Platform} VIP Tier Name": "Gold",
"{Platform} VIP Tier ID": "tier_gold",
"{Platform} Points Expiring At": "2026-09-01T00:00:00Z",
"{Platform} Referral URL": "https://yourbrand.com/r/abc123"
}
}
}
}
Event POST body
Send a loyalty event. The event creates the profile if it doesn't exist, and updates properties on the profile inline.
POST /api/events/
{
"data": {
"type": "event",
"attributes": {
"properties": {
"Points Delta": 50,
"Reason": "purchase",
"New Balance": 1250,
"Lifetime Points": 4870,
"Order ID": "order_98765"
},
"metric": {
"data": {
"type": "metric",
"attributes": { "name": "Points Earned" }
}
},
"profile": {
"data": {
"type": "profile",
"attributes": {
"email": "[email protected]",
"properties": {
"{Platform} Points Balance": 1250,
"{Platform} Lifetime Points": 4870
}
}
}
}
}
}
}
Initial backfill of enrolled members
On first install, backfill the merchant's existing loyalty members through the bulk profile import job. This is for state, not history. Don't try to replay years of events through it.
POST /api/profile-bulk-import-jobs/
{
"data": {
"type": "profile-bulk-import-job",
"attributes": {
"profiles": {
"data": [
{
"type": "profile",
"attributes": {
"email": "[email protected]",
"properties": {
"{Platform} Loyalty Member": true,
"{Platform} Points Balance": 850,
"{Platform} VIP Tier Name": "Silver"
}
}
}
]
}
}
}
}
Retries
- 429: respect the
Retry-Afterheader. Otherwise exponential backoff starting at 1s, cap at 60s, max 5 retries. - 5xx: same backoff.
- 4xx (other than 429): don't retry. Log and surface to the merchant.
Identifier guidance
- Identify by email first; phone where you have it. These are the fields Klaviyo merges on.
external_idis NOT a merge key on its own. Use it as a secondary reference, pass it alongside email, and also store the merchant-side customer ID as a profile property (e.g., {Platform} Customer ID) for segmentation.- If duplicate profiles already exist for a merchant from a legacy install, an email-keyed upsert through profile-bulk-import-jobs will consolidate the
external_idonto the surviving profile cleanly.
Rate limits
Per-account, not per-app. Standard limits handle typical loyalty volume without effort. For merchants at unusual scale (think 10M+ events per day, hundreds of thousands of enrolled members per merchant), the path is per-endpoint, per-account increases through Klaviyo Support and CSM. Reach out before launch so we can fast-track the request rather than ramping into 429s in production.
Glossary
- Klaviyo profile: customer record. Keyed by email, phone, or external ID. The loyalty member.
- Klaviyo metric: event type. "Points Earned," "Tier Upgraded," etc. Created automatically on first event ingest.
- Klaviyo segment: dynamic audience computed from rules. The merchant builds these from your profile properties and events to target their loyalty members.
- Klaviyo list: static audience used for consent. Not where loyalty membership lives.
- Customer Hub: Klaviyo's hosted, logged-in customer experience layer where shoppers see their account info, including loyalty status and rewards.
Resources
- Klaviyo Developer Portal. Start here for everything.
- Create a public OAuth app
- Create Event / Update Profile / Bulk Import Profiles
- Klaviyo App Marketplace, Rewards category. The existing set of loyalty integrations.
- App Marketplace Review: [email protected]
Updated about 16 hours ago