Personalized Images in Email Campaigns: One Template URL, Zero Image-Service Bill

Dynamic image services charge per open because email marketers reliably pay for merge-tag personalization. The mechanism underneath is simpler than the pricing…

Dynamic image services charge per open because email marketers reliably pay for merge-tag personalization. The mechanism underneath is simpler than the pricing suggests: an image URL with query parameters filled by your ESP at send time or open time. MarkupGo's Magic Template URL replicates this with flat credit pricing and no per-recipient billing [1].

Build a reusable template with variables

Open the MarkupGo template editor and create a new template. Write standard HTML and CSS; flexbox, web fonts, and gradients behave as they do in a browser [2].

Add variables for any data your ESP can provide. Common choices include:

  • first_name for greeting personalization
  • product_name or product_image for abandoned-cart blocks
  • discount_code or discount_percent for promotional banners
  • points_balance or tier_name for loyalty programs
  • event_date or location for event reminders

Reference these variables with whatever syntax your server-side renderer uses. In Handlebars, that looks like:

<div class="banner">
  <h1>Hi, {{first_name}}</h1>
  <p>Your {{product_name}} is waiting</p>
  <span class="code">{{discount_code}}</span>
</div>

Style with CSS as normal. The editor preview updates in real time. Save the template and note the template ID from the dashboard or the URL [1].

Enable and test the Magic Template URL

Visit the Templates page, click your template, and enable the Magic URL option [1].

The URL format is:

https://render.markupgo.com/template/{templateId}.{extension}?{query}

Supported extensions are png, jpeg, webp, and pdf [1]. Query parameters other than reserved fields like json and redirect are treated as template context data automatically, with no context prefix needed [1].

Build a test URL. For template ID abc123, requesting a PNG:

https://render.markupgo.com/template/abc123.png?first_name=Alex&product=Headphones&discount=20OFF

Paste this into your browser. The image generates on first request and caches for 15 days [1]. Revisit the same URL within that window and MarkupGo serves the cached file without charging another credit [1].

Test variants to verify your template logic: empty strings, long names, special characters. The qs library parses parameters, so arrays use bracket notation if your template expects them [1].

Insert merge tags into the query string for your ESP

Klaviyo: Use {{ first_name|default:'Friend' }} directly in the query string. The |default filter supplies a fallback when a value is missing [3]. Your image tag becomes:

<img src="https://render.markupgo.com/template/abc123.png?first_name={{ first_name|default:'Friend' }}&product={{ product_name }}" alt="Your personalized offer" />

Mailchimp: Insert *|FNAME|* merge tags into the URL query string, a technique demonstrated by APITemplate.io for rendering personalized images at open time:

<img src="https://render.markupgo.com/template/abc123.png?first_name=*|FNAME|*&discount=*|DISCOUNTCODE|*" alt="Your personalized offer" />

Other ESPs: Any merge tag that renders at send time or open time works. Instantly and similar B2B outreach tools qualify if they allow source URL editing. The image renders at open time with the recipient's actual data, just as NiftyImages or DynaPictures would handle it [4].

Handle email-specific rendering constraints

Images blocked by default in Outlook desktop 2007–2019 and Outlook for Mac; Gmail, Yahoo, Outlook.com, and most mobile clients show images by default [5]. AOL Mail is the webmail exception with images off [5].

Account for this in your template design:

  • Always include descriptive alt text on the image tag
  • Add a text fallback or bulletproof button beneath the image; never send image-only emails
  • Keep image widths to 600px or less for email-safe rendering
  • Use fixed heights to prevent layout shifts when images load

Each recipient gets a unique URL because their merge-tag data differs. This reduces cache reuse but ensures true personalization. Unique URLs consume credits per generation; plan your volume against your plan limits [1].

Cost comparison: per-open billing versus flat credits

NiftyImages charges $25–950/month based on monthly image opens, with a 7-day trial and 20% annual discount [4].

MarkupGo uses flat credits instead. Lite at $29/month gives 2,000 credits; Plus at $49 gives 10,000; Pro at $99 gives 20,000 [2]. The free trial offers 100 credits monthly with no credit card required [2].

For most senders under 10,000 opens, flat credits cost less than per-open subscriptions. A 5,000-recipient campaign with one personalized image per email consumes up to 5,000 credits for generation, since every unique URL consumes credits [1]—well within Plus plan limits at $49. The same volume on NiftyImages' $25 Starter plan (50,000 opens) costs the same base rate but scales up faster as your list grows [4].

The same Magic URL also renders PDFs for invoices or attachments [1][6].

What to do next

Build your first template in the MarkupGo editor. Test the Magic URL with sample query parameters in your browser. Paste the URL into a test email with your ESP's merge tags and send to yourself. Verify image blocking behavior in Outlook and mobile clients. Scale to your full list on a paid plan when ready.

Sources

  1. markupgo.com
  2. markupgo.com
  3. How to insert a dynamic image in an email (help.klaviyo.com)
  4. NiftyImages Review 2026: Dynamic Email Images (phi.consulting)
  5. Email Image Blocking: Answering the What, Why, Where, Who, and How (litmus.com)
  6. markupgo.com