Update a saved Stat Counter or progress widget from Make, n8n, Zapier, or any tool that can send an HTTP request. Your design and image URL stay the same.
Available action: update one live value per Stat Counter, Progress Bar, Radial, Gauge, or Vertical Progress widget.
Add HTTP v4 → Make a request. Store the DynaMail key in an API-key credential/keychain with header name X-API-Key.
Send PUT to the copied Automation endpoint with body content type application/json.
Use a Data structure with Number fields value and sourceVersion. For example, map inventory.availableUnits and inventory.revision.
Enable Parse response and Return error if HTTP request fails. Process data in order, run once, and inspect data.applied and data.reason before enabling your schedule.
Downloadable workflow
n8n
Import a portable example made from n8n's built-in nodes. It contains no credential and runs manually.
Create an API by Zapier app connection using Static Headers (API key).
Set the header name to X-API-Key and its value to the separately named DynaMail API key. Set the Domain filter to api.dynamail.io and the Test URL to https://api.dynamail.io/me.
Add API Request with PUT to the copied endpoint and content type application/json.
Map numeric value and sourceVersion into valid JSON without quotes around the mapped numbers. Zapier interpolation does not format JSON automatically.
Test the request and inspect data.applied and data.reason.
Personalize with the merge tags you already use
Every widget image URL accepts r for per-recipient open tracking and c for a campaign label. Progress widgets also take current and target, countdowns referenceDate, Membership Cards points, and Leaderboards me. Paste your platform's merge tag into a value and the image renders for that recipient when the email loads.
The email builder generates these tags when you map campaign fields: URL-encoding forms for Mailchimp, Braze, and Iterable, and for other platforms a source field whose values are already URL-safe. The examples below are for hand-built templates; each one says whether the platform URL-encodes the substituted value.
Mailchimp URL-encodes merge tags placed inside link href attributes, but values inside an <img src> render as-is. *|UNIQID|* is unique per subscriber per campaign, ideal for recipient tracking. Use *|EMAIL|* if you need a cross-campaign identity.
Klaviyo uses Django-style tags with spaces inside the braces. Add a fallback to avoid blank values, e.g. {{ email|default:"" }}. Add |urlencode when a value goes into a URL, e.g. {{ email|urlencode }}.
HubSpot personalization tokens are lowercase (firstname, lastname) and namespaced under contact. Only contact properties are available in marketing emails. HubL filters such as |urlencode are not available on tokens in emails.
This platform substitutes the raw value. Plain addresses work, but one containing +, &, or # breaks tracking, so prefer an opaque subscriber id field if your account has one.
Handlebars syntax for dynamic templates — field names must match keys in your dynamic_template_data payload. Legacy (non-dynamic) templates use -email- substitution tags instead. No URL-encoding helper exists; send an already URL-safe value in dynamic_template_data.
This platform substitutes the raw value. Plain addresses work, but one containing +, &, or # breaks tracking, so prefer an opaque subscriber id field if your account has one.
ActiveCampaign personalization tags are uppercase and wrapped in percent signs. Add a fallback with %FIRSTNAME|friend%. Tags have no URL-encoding option, so use an opaque id or a field whose values are already URL-safe in query strings.
This platform substitutes the raw value. Plain addresses work, but one containing +, &, or # breaks tracking, so prefer an opaque subscriber id field if your account has one.
Campaign Monitor uses square-bracket tags. Add fallbacks with [firstname,fallback=there]. Tags support only the fallback option, not URL encoding, so use an opaque id or a field whose values are already URL-safe in query strings.
This platform substitutes the raw value. Plain addresses work, but one containing +, &, or # breaks tracking, so prefer an opaque subscriber id field if your account has one.
Event triggers have no running total, so send {"delta": 1} and DynaMail adds it atomically.
Increment request
POST https://api.dynamail.io/widgets/WIDGET_ID/live-value/increment
JSON request body
{
"delta": 1,
"eventId": "order-123"
}
Make: add HTTP → Make a request, choose POST, reuse the same API-key credential, and send the body above to https://api.dynamail.io/widgets/WIDGET_ID/live-value/increment.
n8n: use an HTTP Request node with method POST and the JSON body above.
Zapier: use an API by Zapier POST request with the JSON body above.
Map a unique trigger ID to eventId. The same ID counts once per widget within 7 days; without it, every request counts. Use Set Live Value with a source version when your trigger carries a total.
A different number for each recipient
Push a value with a recipient and put the same identifier in the image URL; everyone else keeps seeing the widget’s global value. The identifier can be an email address or a subscriber ID, as long as your email platform can merge the same value into the URL.
Make: collect bundles with an Array aggregator, then send one HTTP request to PUT https://api.dynamail.io/widgets/WIDGET_ID/live-value/bulk with the aggregated array as entries.
n8n: fold items with an Aggregate (or Code) node into one entries array, then use one HTTP Request node.
Zapier: send one request per record with the single-recipient body; the bulk endpoint needs a Code step to assemble entries.
Up to 500 recipients per request
10,000 recipients per widget on the free plan; more on paid plans when they launch
Values expire 90 days after the last write
DynaMail stores a salted hash of the recipient identifier, never the identifier itself
Recipient renders are sent private, no-store
Check each entry’s applied and reason in the bulk response; limit means the widget’s recipient capacity is reached and conflict means the same sourceVersion arrived with a different value, an expectedRevision check failed, or a concurrent write to the same recipient won; only the last case is worth retrying.
One request, a stable image URL
Automation endpoint
PUT https://api.dynamail.io/widgets/WIDGET_ID/live-value
JSON request body
{
"value": 82,
"sourceVersion": 1042
}
Both fields are integers. Use a positive safe integer for sourceVersion from the same upstream record or snapshot as value, and increase it for every change. Retry the same event with the same version.
A 200 response can report an update as stale or unchanged. Inspect data.applied and data.reason before treating it as a changed value.
Keep one active data source on the widget at a time. For 429 or 503, wait for the response’s Retry-After interval before retrying. Email providers may retain cached image copies.