Resend email analytics start strong and stop early. Resend tells you an email was delivered, then opened, then clicked, and for a transactional or campaign send that is genuinely useful. The problem is that the interesting question lives on the other side of the click. Did the person come back and finish onboarding. Did they activate. Did they upgrade. Resend cannot answer that, because the trail ends the moment the recipient leaves the email. This guide covers what Resend actually measures, why open rates lie in a specific and predictable way, and how to connect email events to product behavior so you can measure email through to activation rather than to the click.
What Resend measures out of the box.
Resend gives you two kinds of signal. The first is delivery telemetry that comes for free on every send: whether the message was accepted for delivery, whether the receiving server took it, whether it bounced, and whether the recipient filed a spam complaint. These are the events you want most, because they are real server-to-server facts rather than guesses. A delivered event means a mail server on the other side said yes. A hard bounce means the address is dead and you should stop sending to it.
The second kind is engagement tracking, and this is opt in. Open tracking and click tracking are both configured per sending domain in the Resend dashboard, and neither is on until you turn it on. Open tracking drops an invisible one pixel image into the message and records an open when a mail client loads it. Click tracking rewrites the links in your email so each one passes through a Resend redirect, which lets Resend log the click before handing the recipient off to your real URL. If you are sending through Resend today and seeing deliveries but no opens or clicks, the tracking toggle is almost certainly the reason.
Why open rates overcount, and what to trust instead.
Open tracking has a structural flaw that has nothing to do with Resend and everything to do with how modern mail clients work. Apple Mail Privacy Protection, which a large share of Apple Mail users have enabled, prefetches remote images including your tracking pixel, regardless of whether the person ever opens the message. Every one of those prefetches looks exactly like a genuine open. Corporate security gateways and link preview services do the same thing. The result is an open rate that overcounts, and the size of the overcount depends on how many of your recipients read mail on Apple devices, which you do not control and cannot see.
This does not make open rate useless. It makes it a relative measure rather than an absolute one. Comparing the open rate of two subject lines sent to the same audience is fair, because the prefetch noise is roughly constant across both. Watching your open rate trend over months is fair. Reporting to yourself that exactly 4,213 people read your email is not fair, because a meaningful and unknown fraction of those never did. Clicks are the more honest engagement signal, since a click is an action rather than a passive load, though even clicks get inflated by automated link scanners that follow every URL in an inbound message.
| Signal | What it means | How much to trust it |
|---|---|---|
| Delivered | The receiving mail server accepted the message. This is the most reliable positive signal Resend gives you. | High. A delivery event is a real handshake between servers, not an inference. |
| Bounced | The receiving server rejected the message, hard (the address does not exist) or soft (a temporary problem). | High. Hard bounces should suppress the address so you stop sending to it. |
| Complained | The recipient marked the message as spam through their mail client. | High and important. A rising complaint rate is a deliverability emergency. |
| Opened | A tracking pixel loaded, which usually means the recipient viewed the message. | Low to moderate. Machine prefetching inflates this number, so read it as a trend, not a count. |
| Clicked | The recipient followed a tracked link, which rewrites your URLs through a redirect. | Moderate to high. Real intent, but security scanners also click links, so a single click is not proof of a human. |
Webhook events are the raw material for real analytics.
The Resend dashboard is a fine window into recent activity, but it is a window, not a feed. To build analytics you own, you need each event delivered to you as it happens, and that is what webhooks are for. Resend emits an event for each stage of a message: sent, delivered, delivery delayed, bounced, complained, opened, clicked, and a few more. Each arrives as a small JSON payload with a type field and a data object carrying the email id, recipient, and subject. Store those events, key them to the message and the recipient, and you have the primitive you need to build funnels, cohort reports, and revenue attribution on top of email.
The events are only trustworthy if you verify them, because the endpoint is public and anyone can POST to it. Resend signs every webhook using Svix, and getting that verification right has a couple of sharp edges that are worth their own writeup. If you are building the consumer yourself, read the companion guide to Resend webhooks, verification, and retries before you ship it, because the failure modes there are the kind that pass in testing and break in production.
A minimal Resend webhook consumer.
Here is the smallest handler that does the job correctly: a Next.js route that reads the raw request body, verifies the Svix signature, and records the event. The one detail people miss is reading the raw body before parsing it, because the signature is computed over the exact bytes Resend sent. Parse first and you have already changed the bytes.
import { Webhook } from "svix";
// app/api/webhooks/resend/route.js
export async function POST(req) {
// Read the raw body as text. Do not call req.json() first:
// Svix verifies the exact bytes Resend signed.
const body = await req.text();
const headers = {
"svix-id": req.headers.get("svix-id"),
"svix-timestamp": req.headers.get("svix-timestamp"),
"svix-signature": req.headers.get("svix-signature"),
};
const wh = new Webhook(process.env.RESEND_WEBHOOK_SECRET);
let event;
try {
event = wh.verify(body, headers); // throws on a bad signature
} catch (err) {
return new Response("invalid signature", { status: 401 });
}
// event.type is "email.delivered", "email.opened", "email.clicked", ...
await recordEmailEvent({
kind: event.type,
emailId: event.data.email_id,
recipient: event.data.to,
occurredAt: event.created_at,
});
return new Response("ok", { status: 200 });
}That handler stores the event, but storing it is not the point. The point is what you attach it to. If recordEmailEvent writes to a table that is keyed only by email id, you have a log of email activity and nothing more. If it writes to the customer profile of the person who received the message, you have the beginning of real analytics, because now the email event sits next to that person's signups, sessions, and feature use. The join is the whole game.
Build the analytics layer, or connect one.
The build path is clear and entirely doable. Consume the webhooks, verify each one, deduplicate by event id, store the events, and maintain a mapping from email id to the user in your own system so you can join email activity to product behavior. Then write the queries: open to activation, click to upgrade, campaign to revenue. None of it is exotic. It is a few weeks of focused work plus the ongoing cost of owning a public endpoint, a store, and a set of reports that someone has to keep correct as your product changes.
The buy path trades that work for a subscription. The question is not which is objectively better, it is what your team should be spending time on. If email attribution is a core part of what you sell, build it and own it. If email is one channel among several and you would rather spend the weeks on your actual product, connect a tool that already does the join. For a fuller treatment of that decision applied to lifecycle email specifically, see the guide to measuring email automation ROI.
How GetFluxly ties email events to the customer profile.
This is the case where we can speak from our own build. When you connect Resend to GetFluxly, we consume the Resend webhooks for you: delivery, bounce, and complaint events update the send log and feed suppression automatically, so a hard bounce stops future sends to that address without you writing a line of code. We pair those with our own open and click tracking, and every one of those signals lands on the same customer profile as the person's product events. There is no separate email id table to reconcile, because GetFluxly triggered the send in the first place and already knows who the recipient is.
That shared profile is what turns email data into product answers. You can see that the users who clicked the activation email reached their first value moment at a higher rate, or that a broadcast drove a measurable bump in upgrades, because the email event and the upgrade event are two rows on one record rather than two datasets in two tools. If you want the underlying pattern of capturing product behavior and attaching it to the same profile, the guide to product event tracking for email walks through how the profile gets built in the first place.
One honest limit: GetFluxly is not the sender. Your sending reputation, your deliverability, and your open and click tracking configuration all live with Resend, which is exactly where they should live. GetFluxly is the triggering, profile, and analytics layer on top. If all you want is a raw email log and you have no interest in joining it to product behavior, the Resend dashboard alone is enough and you do not need us.
Resend email analytics, answered.
Does Resend track email opens and clicks?
Yes. Resend supports both open tracking and click tracking, and you enable them per sending domain in the Resend dashboard. Open tracking works by embedding a tiny invisible image in the message; when a mail client loads that image, Resend records an email.opened event. Click tracking works by rewriting the links in your email to pass through a Resend redirect, so a click generates an email.clicked event before the recipient lands on your page. Both are off by default, so if you are seeing delivery events but no opens or clicks, that is the first setting to check.
How accurate are Resend open rates?
Open rates are directionally useful but should never be treated as an exact count. Apple Mail Privacy Protection, which is on for a large share of Apple Mail users, prefetches the tracking pixel whether or not the person actually reads the message, which inflates opens. Corporate security scanners and link previewers do the same. The practical effect is that your open rate overcounts, sometimes badly, and the size of the error changes with your audience mix. Use opens to compare one send against another, watch the trend over time, and never build a business decision on a single open number.
How do I track clicks from Resend emails?
Enable click tracking on your sending domain, and Resend will rewrite every link in your outgoing email to route through its redirect service. When a recipient clicks, Resend logs an email.clicked event and forwards them to the real destination. The event payload includes a click object with the specific link that was followed, a timestamp, the IP address, and the user agent. Click tracking is more reliable than open tracking because it reflects an action rather than a passive image load, but automated link scanners can still generate false clicks, so treat the first click on a message with mild skepticism.
Can I see what a user did in my product after clicking an email?
Not from Resend alone. Resend tells you the email was delivered, opened, and clicked, and then the trail goes cold at the redirect. To see whether that click turned into a signup, an activation, or an upgrade, you have to join the email event to the same person's product events. That means capturing a stable identifier at send time and again in your product, then querying across both. This is exactly the gap GetFluxly closes: because it triggers the send and owns the customer profile, the email events and the product events already live on the same record.
Do I need webhooks to get analytics out of Resend?
For a quick look, no. The Resend dashboard shows delivery, open, and click activity per message and in aggregate, which is enough to sanity check a campaign. For real analytics you own, yes. Webhooks are how you get each event as it happens so you can store it in your own database, join it to user records, and build funnels or attribution on top. The dashboard is a window; webhooks are the raw feed. If you want to measure email all the way to revenue, you need the feed.
What is the difference between Resend analytics and a product analytics tool?
Resend measures the email: was it delivered, opened, clicked. A product analytics tool measures behavior inside your app: signups, activations, feature use, upgrades. On their own, each answers half the question. The value is in the join. When email events and product events share one customer profile, you can ask whether the users who opened the onboarding email activated at a higher rate, or whether a specific broadcast drove upgrades. That cross-domain question is the one that actually informs what you send next.
Resend measures the email well. It was never designed to measure what happens after the click, and treating its open rate as gospel or its click log as the end of the story leaves the most useful question unanswered. The email did its job when the person came back and did something in your product. Measure to that moment, on the same profile, and the numbers finally tell you what to send next.