Suped

How do I create an image pixel for tracking email opens and clicks?

Published 2 May 2025
Updated 14 Oct 2026
13 min read
Summarize with
Email tracking pixel and click redirect for measuring email opens and link clicks.
Updated on 14 Oct 2026: We corrected the tracking examples and clarified how to embed pixels without overstating email engagement.
To create an image pixel for tracking email opens, generate a separate opaque event ID for the recipient's open pixel, place a 1x1 image URL in the HTML email, log the request when that URL loads, then return a tiny transparent GIF or PNG. To track clicks, do not use the image pixel. Give each tracked link its own signed event ID, log the request through a redirect endpoint, then send the reader to the stored destination with a 302 redirect.
Keep the first version simple: one tracking domain, a tracking ID table with a separate request log, separate open and click endpoints, and a dashboard that separates human-looking activity from proxy or scanner activity. Open tracking is useful, but it is not exact. Image caching, Apple Mail Privacy Protection, Gmail image handling, blocked images, and security systems all change what a raw event means.
  1. Open pixel: a hidden image request that records that an email client or proxy requested the asset.
  2. Click tracking: a tracked link that logs the request before redirecting to the real destination.
  3. Dashboard data: event IDs, timestamps, campaign IDs, recipient IDs, user agents, IPs, and bot classification.

How email tracking pixels work

A tracking pixel, also called a web beacon, is an image URL embedded in an HTML email. The email client requests that URL while rendering the message, and the server treats the request as an open event. The pixel is usually transparent, 1x1, and placed near the end of the HTML. A deeper explanation of tracking pixels helps with client-side behavior, but the server side is straightforward.
A common mistake is trying to make the image pixel handle opens and clicks. An image request does not record which email links were clicked. Opens are image loads. Clicks are link visits. They can share a tracking domain and event model, but they need different endpoints and different interpretation.
Email tracking flowchart showing image requests for opens and redirects for link clicks.
Email tracking flowchart showing image requests for opens and redirects for link clicks.

Signal

How it fires

Best use

Open
Image load
Image-load trend
Click
Redirect
Engagement after scanner filtering
Conversion
Site event
Outcome
Open and click tracking need separate signals.

Create a 1x1 email tracking pixel

Create one event ID for the open pixel and one for each tracked link, for every recipient and message. Store the campaign, recipient, message, and destination metadata in the database. Put only the opaque event ID and a signature in each tracking URL. Do not put email addresses, names, customer IDs, or raw campaign names in the URL because URLs end up in logs, forwards, screenshots, and proxy caches. Generate IDs with a cryptographically secure source, such as crypto.randomUUID(), rather than sequential numbers.
Use an HTML image tag because email clients commonly remove or block JavaScript. The exact host should be a tracking subdomain that you control, with TLS enabled and DNS configured before the campaign goes out. If a client clips a long message before a pixel placed at the end, the pixel will not load until the recipient opens the clipped content, so test the final HTML size.
HTML open pixelhtml
<img src='https://track.example.com/o/8ff21b95-903c-4cfa-a866-9d036509cab3.gif?sig=REPLACE_WITH_SIGNATURE' width='1' height='1' alt='' style='display:block;border:0;width:1px;height:1px' />
On the server, validate the signature, record the request, return a transparent image, and send headers that reduce caching. The headers do not stop every proxy cache, but they make the response behavior explicit and help during local testing. Replace the sample UUID with the stored open ID and REPLACE_WITH_SIGNATURE with sign(eventId) generated using the same server secret as the endpoint. The response body must contain GIF bytes with an HTTP 200 status and Content-Type: image/gif.
Node open endpointjavascript
import express from 'express'; import crypto from 'crypto'; const app = express(); const gif = Buffer.from( 'R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', 'base64' ); const secret = process.env.TRACKING_SECRET; if (!secret) throw new Error('Set TRACKING_SECRET before starting'); function sign(value) { return crypto .createHmac('sha256', secret) .update(value) .digest('hex') .slice(0, 32); } function validSignature(eventId, signature) { if (typeof signature !== 'string' || !/^[a-f0-9]{32}$/.test(signature)) { return false; } return crypto.timingSafeEqual( Buffer.from(signature, 'hex'), Buffer.from(sign(eventId), 'hex') ); } app.get('/o/:eventId.gif', async (req, res) => { const eventId = req.params.eventId; if (!validSignature(eventId, req.query.sig)) return res.sendStatus(404); try { await recordOpen({ eventId, userAgent: req.get('user-agent') || '', ip: req.ip, occurredAt: new Date() }); } catch { console.error('Open event write failed'); } res.set({ 'Content-Type': 'image/gif', 'Cache-Control': 'no-store, no-cache, must-revalidate, private', 'Pragma': 'no-cache', 'Expires': '0' }); res.end(gif); }); app.listen(3000);
Install Express and enable ES modules for the Node snippets. Set TRACKING_SECRET to a strong random server-side secret. Implement recordOpen, recordClick, and findTargetUrl as database helpers. Have them check that each ID exists and matches its open or click event type. Use bounded-time writes or a durable queue in production so analytics failures do not stall the image response or redirect.
Do not expose recipient data
  1. Use opaque IDs: store the recipient and campaign lookup on the server, not in the URL.
  2. Sign each ID: reject guessed or modified event IDs before logging an event.
  3. Enforce preferences: keep auditable consent or objection records and omit tracking where required.

Embed the pixel in the email you send

Add the img tag in your HTML template or source editor. Pasting it into a normal compose window can display markup as text instead of embedding an image. Generate a fresh tracking URL per recipient and message, then inspect the received HTML to confirm the sender preserved it.
Use an external HTTPS image URL that returns the GIF without a login or browser cookies. An attachment, cid image, or data URL does not request your tracking endpoint. Uploading a static pixel image is insufficient unless the host exposes usable request logs or invokes your event handler.
Plain-text emails cannot contain an image pixel. In a multipart/alternative message, put it only in the text/html part. Redirect-based click tracking still works in the plain-text part when the full tracked URL is included.

Add click tracking with redirects

For click tracking, rewrite each link before sending. Store the original target URL in the database and send the recipient through a tracking URL with a signed event ID. Keep destinations on the server; accepting an arbitrary destination query parameter without validation creates an open redirect. Validate the scheme and allowed destination when creating the tracked link, not only when someone clicks it. Leave unsubscribe and preference-management URLs out of analytics redirects so recipient choices do not depend on tracking availability.
Open tracking
  1. Trigger: email client or image proxy requests the tiny asset.
  2. Response: server returns a transparent image with cache-control headers.
  3. Meaning: a useful reach signal, not proof that a person read the email.
Click tracking
  1. Trigger: recipient, scanner, or browser requests the tracked link.
  2. Response: server logs the event and redirects to the stored destination.
  3. Meaning: a stronger engagement signal, but scanner clicks still need filtering.
The click endpoint should validate the signature, fetch the destination by event ID, log the request, then redirect. The dashboard can show raw clicks while marking likely scanner activity separately. This is where bot click data becomes important, especially in B2B campaigns.
Node click endpointjavascript
app.get('/c/:eventId', async (req, res) => { const eventId = req.params.eventId; if (!validSignature(eventId, req.query.sig)) return res.sendStatus(404); const target = await findTargetUrl(eventId); if (!target) return res.sendStatus(404); try { await recordClick({ eventId, userAgent: req.get('user-agent') || '', ip: req.ip, occurredAt: new Date() }); } catch { console.error('Click event write failed'); } res.set({ 'Cache-Control': 'no-store', 'Referrer-Policy': 'no-referrer' }); res.redirect(302, target.url); });

Store tracking IDs and request events

Store both first-seen timestamps and total counts. Count a unique open once per recipient and message, and a unique campaign clicker once per recipient across tracked links. Keep per-link unique clicks separate so clicking two links does not count as two campaign clickers. Repeated requests are still useful because they can indicate forwarding, preview panes, retries, proxy behavior, or scanners.
Tracking ID summary tablesql
create table email_tracking_ids ( event_id uuid primary key, campaign_id uuid not null, recipient_id uuid not null, message_id uuid not null, event_type varchar(10) not null check (event_type in ('open', 'click')), target_url text, first_seen_at timestamptz, last_seen_at timestamptz, open_count integer not null default 0, click_count integer not null default 0, last_user_agent text, last_ip inet );
Each row stores one tracking ID and its summary counters. Keep a separate append-only request log with its own request ID, the tracking event_id, timestamp, and permitted request metadata. Have recordOpen and recordClick append requests and update summary counters atomically. Calculate classification fields without overwriting the original request; retain necessary raw user agent and network data only for the documented period. This keeps reporting flexible when classification rules improve.
For a single campaign send, email open rate is unique recipients with a recorded open divided by delivered messages, multiplied by 100. Click-through rate (CTR) uses unique recipients with a filtered click as its numerator. Exclude bounces from delivered counts and keep reporting windows consistent. Label open rates as image-load measurements.
Keep a send snapshot for each message version, including the subject, sender, template ID, tracking domain, and send time. This makes later debugging easier when a campaign is resent, a link changes, or a test address receives multiple versions. The event table should answer what happened, while the send snapshot explains what the recipient received.

Field

Purpose

Keep raw?

Event ID
Lookup key
Yes
User agent
Client clue
Limited
IP
Network clue
Limited
Class
Report filter
Derived
A compact event model keeps the dashboard useful.

Apply privacy controls before collecting events

Tracking rules depend on where recipients are located, what the tracker collects, and how the data is used. A pixel or decorated link can trigger rules for access to a person's device as well as rules for processing personal data. Complete a privacy review before rollout, document the applicable lawful basis or consent requirement, and avoid assuming that permission to send an email also permits engagement tracking. Treat opaque IDs linked back to recipients as personal data and apply the same access and retention controls.
Provide clear notice about the tracking purpose, collected fields, retention period, and any data recipients. Where consent or an objection mechanism is required, store the preference separately from event data and send an untracked version when the recipient declines or withdraws. A privacy policy alone does not replace a required choice.
  1. Minimise collection: avoid precise location claims, shorten or discard IP data, and collect only fields used for a stated purpose.
  2. Set retention limits: delete or anonymise recipient-level events when the documented reporting period ends.
  3. Honor the choice: remove both the open pixel and tracking redirects when a recipient's preference requires no tracking.
  4. Restrict access: limit raw event data to staff who need it and log administrative access.

Account for image caching and automated activity

Open tracking is a directional signal, not a precise count of readers. When Protect Mail Activity is enabled, Apple Mail Privacy Protection downloads remote content in the background regardless of engagement. Gmail can display images through systems that prevent the sender from learning the reader's computer or precise location, and recipients can require approval before external images load. Security systems can also inspect tracked links before or around a human click. More detail on Gmail image caching helps explain odd timestamps or repeated loads.
A pixel does not measure reading duration or scrolling. Proxy caching can hide repeat opens despite cache-control headers, and proxy IP addresses or user agents do not reliably identify a recipient's location or device. A forwarded message retains the original tracking URLs, so activity stays associated with the original send. Avoid person-level conclusions such as "read" or "ignored" because these signals do not justify that language.
How to report opens
  1. Unique opens: one first-seen image load per recipient and message, with suspected proxy loads labeled separately.
  2. Total opens: all requests received by the tracking endpoint; cached repeat views are missing and automated loads add noise.
  3. Stronger signals: scanner-filtered clicks and confirmed downstream actions carry more weight; an unclassified click is not proof of human activity.
Before trusting production numbers, send real test messages to different inboxes and inspect the received HTML and server logs. Use Suped's email tester to check authentication in a delivered test message. Verify image loads, redirects, and client rendering with separate request-log and inbox tests.

Email tester

Send a real email to this address. Suped shows a results button when the test is ready.

?/43tests passed
A test run should confirm that the pixel loads in a basic client, the click redirect lands on the approved URL, the tracking domain has valid TLS, and the final email still renders correctly with images disabled. Also test unsubscribe and preference links because tracking logic must never block them. Check that a valid pixel URL returns a 200 image response, a valid click returns a 302 to the stored destination, and invalid signatures return 404 without recording events. Mark preview and internal test loads so they do not inflate campaign results.

Protect deliverability and authentication

A tracking pixel does not automatically cause filtering, but broken redirects, TLS errors, unstable DNS, or a tracker domain shared with unrelated senders can create warnings and failed requests. Use a domain you control, keep redirects fast, and make link copy describe the real destination. The tracking host should fit the brand; its reputation can also affect filtering.
Suped is our DMARC and email authentication platform. In this workflow, Suped monitors DMARC aggregate data for the sending domain and surfaces SPF or DKIM alignment failures after rollout. It does not host the open pixel or click redirect, so the tracking service still needs its own reliable DNS, TLS, logging, and privacy controls.
Suped DMARC dashboard showing email volume, authentication health, and source breakdown
Check the sending identities and tracking host as separate parts of the rollout. DMARC evaluates the visible From domain against the domain authenticated by SPF or DKIM. A domain health check can identify malformed authentication records, while ongoing DMARC monitoring shows whether real mail passes DMARC alignment once the campaign is live. The tracking subdomain needs valid DNS and TLS, but hosting a pixel there does not make it part of DMARC alignment. Finish pixel insertion and link rewriting before DKIM signing; changing the signed body afterward can invalidate the signature.
  1. Tracking domain: use TLS, stable DNS, and a subdomain that recipients can recognize.
  2. Redirect speed: log asynchronously when needed so clicks do not wait on analytics writes.
  3. Authentication: verify SPF or DKIM alignment with the From domain and review DMARC results.
  4. Reputation: monitor blocklist and blacklist signals when traffic or complaints change.

Views from the trenches

Best practices
Generate opaque event IDs per recipient and store all meaning on the server side only.
Send the pixel from a tracking domain with working TLS and stable DNS records in place.
Treat opens as directional signals, then use clicks and replies for engagement scoring.
Common pitfalls
Using raw email addresses in pixel URLs exposes personal data in logs and forwards later.
Counting every image request as human engagement inflates reports after privacy proxy loads.
Redirecting to arbitrary query string URLs creates an open redirect that scanners can abuse.
Expert tips
Keep each click target in the database, not in the URL, so recipients cannot rewrite it.
Use first-seen time and total count separately because repeated requests aid diagnosis.
Label machine-looking opens in reports instead of deleting them from the raw event table.

Marketer view

Marketer from Email Geeks says the first design choice is deciding whether the dashboard needs email opens, click redirects, website visits, or conversion events.
2024-04-18 - Email Geeks

Marketer view

Marketer from Email Geeks says basic opens and clicks can be built into a backend dashboard, but the sender's existing email software should be checked first.
2024-05-02 - Email Geeks

Frequently asked questions

DMARC monitoring

Start monitoring your DMARC reports today

Suped DMARC platform dashboard
What you'll get with Suped
Real-time DMARC report monitoring and analysis
Automated alerts for authentication failures
Clear recommendations to improve email deliverability
Protection against phishing and domain spoofing