Integrations

Connect your tools. Keep your numbers current.

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.

Sending with Mailchimp, Klaviyo, HubSpot, or Braze? See the merge-tag examples.

Set up DynaMail once

  1. 01

    Save a Stat Counter or progress widget

    Copy its Automation PUT endpoint after you save the widget.

  2. 02

    Create a separate API key

    Name one key for this platform so you can revoke it independently.

  3. 03

    Keep the saved image URL

    Leave off an explicit value override so the image can use the automatic value.

API keys are scoped; the Automation preset can push values but cannot create or delete widgets.

The request updates the value delivered by the image. You still build and send the campaign from your email platform.

Choose your setup guide

Manual HTTP recipe

Make

Connect an existing source trigger to Make's HTTP v4 request module.

Make HTTP documentation
Make: Setup steps
  1. Start with your existing source trigger.
  2. Add HTTP v4 → Make a request. Store the DynaMail key in an API-key credential/keychain with header name X-API-Key.
  3. Send PUT to the copied Automation endpoint with body content type application/json.
  4. Use a Data structure with Number fields value and sourceVersion. For example, map inventory.availableUnits and inventory.revision.
  5. 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.

n8n import documentation
n8n: Setup steps
  1. Download the workflow and use n8n’s Import from File action.
  2. Open Update Stat Counter and replace its placeholder with the saved Automation PUT endpoint.
  3. Create or select Header Auth with name X-API-Key and your own separately named DynaMail key.
  4. Map numeric value and an increasing sourceVersion.
  5. Choose Execute workflow, then inspect data.applied and data.reason.

Manual API request

Zapier

API by Zapier is a beta premium app and requires a paid Zapier plan.

API by Zapier setup documentation
Zapier: Setup steps
  1. Create an API by Zapier app connection using Static Headers (API key).
  2. 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.
  3. Add API Request with PUT to the copied endpoint and content type application/json.
  4. Map numeric value and sourceVersion into valid JSON without quotes around the mapped numbers. Zapier interpolation does not format JSON automatically.
  5. 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.

Open the email builder
  • Mailchimp

    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.

    The recipient tag is URL-safe as substituted.

    Image URL with merge tags

    https://img.dynamail.io/widgets/WIDGET_ID/render.png?r=*|UNIQID|*&c=spring-sale
    Mailchimp personalization docs
  • Klaviyo

    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 }}.

    The recipient tag is URL-safe as substituted.

    Image URL with merge tags

    https://img.dynamail.io/widgets/WIDGET_ID/render.png?r={{ email|urlencode }}&c=spring-sale
    Klaviyo personalization docs
  • HubSpot

    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.

    Image URL with merge tags

    https://img.dynamail.io/widgets/WIDGET_ID/render.png?r={{ contact.email }}&c=spring-sale
    HubSpot personalization docs
  • SendGrid (dynamic templates)

    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.

    Image URL with merge tags

    https://img.dynamail.io/widgets/WIDGET_ID/render.png?r={{email}}&c=spring-sale
    SendGrid (dynamic templates) personalization docs
  • Braze

    Braze wraps personalization in Liquid ${...} attribute references. Custom attributes use {{custom_attribute.${name}}}.

    The recipient tag is URL-safe as substituted.

    Image URL with merge tags

    https://img.dynamail.io/widgets/WIDGET_ID/render.png?r={{${email_address} | url_param_escape}}&c=spring-sale
    Braze personalization docs
  • Iterable

    Iterable uses Handlebars against user-profile fields. Field names are case-sensitive and match your data feed / user-profile keys exactly.

    The recipient tag is URL-safe as substituted.

    Image URL with merge tags

    https://img.dynamail.io/widgets/WIDGET_ID/render.png?r={{#urlEncode}}{{email}}{{/urlEncode}}&c=spring-sale
    Iterable personalization docs
  • ActiveCampaign

    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.

    Image URL with merge tags

    https://img.dynamail.io/widgets/WIDGET_ID/render.png?r=%EMAIL%&c=spring-sale
    ActiveCampaign personalization docs
  • Campaign Monitor

    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.

    Image URL with merge tags

    https://img.dynamail.io/widgets/WIDGET_ID/render.png?r=[email]&c=spring-sale
    Campaign Monitor personalization docs

Count events as they happen

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.

Step-by-step guides: Live points balance in Klaviyo, Live waitlist spot in Mailchimp.

Request body

PUT https://api.dynamail.io/widgets/WIDGET_ID/live-value

Request body

{
  "recipient": "person@example.com",
  "value": 82,
  "sourceVersion": 1042
}

Image URL in Klaviyo

Other platforms use their own recipient tag from the list above.

Image URL

https://img.dynamail.io/widgets/WIDGET_ID/render.png?recipient={{ email|urlencode }}

Many recipients in one request

  • 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.

Set up API access