How to show each recipient a live points balance in Klaviyo
Published September 26, 2026 · Klaviyo steps checked against its help center on September 26, 2026
Loyalty points, store credit, referrals: a number that belongs to one person. There are two ways to put it in a Klaviyo email with DynaMail. If Klaviyo already has the number on the profile, merge it into the image URL. If the number lives elsewhere or changes after you send, push it to DynaMail and the image shows the latest value each time it loads.

Pick a method
- Method 1, a profile property: the number is already on the Klaviyo profile. Simple, no account needed for a Stat Counter, but the number is fixed when Klaviyo sends the email.
- Method 2, pushed values: you send each person’s number to DynaMail. The image shows the latest value every time it loads, including after the email has gone out.
Both work with a progress bar (points toward a reward, as below) or a Stat Counter (the number alone). For a Stat Counter, use value= where the examples use current=, and drop target.
Method 1: merge a profile property into the URL
Create the widget
Save a progress bar in DynaMail (the Loyalty Points template is a good start), or make a Stat Counter with the free stat counter generator.
Add an HTML block and paste this
Points from loyalty_points
{% if person.loyalty_points %} <img src="https://img.dynamail.io/widgets/YOUR-WIDGET-ID/render.png?current={{ person.loyalty_points }}&target=1000" alt="Your points toward the next reward" width="340" height="184" style="display:block;border:0;" /> {% endif %}{{ person.loyalty_points }}is Klaviyo’s dot notation for a profile property; Klaviyo says to use it for names without spaces or special characters. Keep the property name that way, because the lookup form for other names needs quote marks, which do not belong inside an HTML attribute.The
{% if %}wrapper comes from Klaviyo’s conditional logic reference. It skips the image for profiles without the property, whose empty value would otherwise show the widget’s own live or saved value instead of theirs. A balance of zero may count as empty too, so include a zero-balance profile when you preview.Preview with a real profile
Klaviyo’s preview renders profile-based variables when you pick a real profile. Choose one with points and one without, and check both.
Method 2: push each person’s value to DynaMail
Create the widget in a free account
Pushed values need a saved widget, so sign up (free while in beta) and save a progress bar or Stat Counter. Its detail page has an Automation card with the endpoint.
Send each recipient's value
Push a value with a
recipient, using the same email address Klaviyo will merge into the URL. Zapier, Make and n8n recipes are on the Integrations page; for a one-off load, the Automation card can import a CSV.PUT https://api.dynamail.io/widgets/WIDGET_ID/live-valueAuthenticate with an API key created with the Automation preset under API keys in your dashboard, sent in the
X-API-Keyheader; without it the request is rejected. The developer docs cover the full request.Request headers
X-API-Key: dm_sk_your_key_here Content-Type: application/jsonRequest body
{ "recipient": "person@example.com", "value": 450, "sourceVersion": 1 }Put the recipient tag in the image URL
Paste this into an HTML block.
{{ email|urlencode }}is Klaviyo’s email tag with its documentedurlencodefilter, so addresses containing+survive the query string.Live per-recipient points
<img src="https://img.dynamail.io/widgets/YOUR-WIDGET-ID/render.png?target=1000&recipient={{ email|urlencode }}" alt="Your points toward the next reward" width="340" height="184" style="display:block;border:0;" />Update values whenever they change
Push again after a purchase or a redemption, with a
sourceVersionhigher than the last one you sent for that recipient; a timestamp or an order number works. DynaMail rejects a new value that reuses an older version, so resend the same version only when retrying the exact same update. The next time a recipient’s email loads the image, it shows the new balance; nothing in Klaviyo changes.
Limits and privacy for pushed values
- Recipients are matched without regard to letter case, and anyone without a pushed value sees the widget’s shared value instead.
- 10,000 recipients per widget on the free plan; more on paid plans when they launch. Send up to 500 in one bulk request.
- Values expire 90 days after the last write.
- DynaMail stores a salted hash of each recipient identifier, never the address itself, and sends recipient images with
private, no-storecaching headers. Email clients can still keep their own copy of an image they have fetched.
Sources
Every Klaviyo step above comes from these pages, read on September 26, 2026. Apps rename menus often; if a step no longer matches what you see, the source page is the place to check.
- Klaviyo: Guide to the email template editor (opens in a new tab)
- Klaviyo: Message personalization reference (opens in a new tab)
- Klaviyo developers: Django filter glossary (opens in a new tab)
- Klaviyo: How to show or hide template blocks and sections based on dynamic variables (opens in a new tab)
- Klaviyo: How to preview and send test emails in Klaviyo (opens in a new tab)
Frequently asked questions
Which method keeps the number current after sending?
Only the pushed-value method. A Klaviyo profile tag is filled in once, when Klaviyo sends the email, so that number is fixed. A value pushed to DynaMail is read each time the image is requested.
Does DynaMail store my recipients’ email addresses?
No. DynaMail stores a salted hash of the recipient identifier, never the identifier itself, and renders for a recipient are sent with private, no-store caching headers.
What does someone without a pushed value see?
The widget’s shared value: the latest global push, a connected source, or the number saved on the widget. Per-recipient values expire 90 days after the last write.