SendGrid's Click Tracking Rewrites Your URLs — Here's Why That Bites You
SendGrid's click tracking silently rewrites every link in your emails through their redirect domain. That's a DMARC problem and a user trust problem you need to know about.
I've been sending transactional email through SendGrid for years across probably a dozen client projects. It works well enough that I mostly set it up and move on. But click tracking has a quiet behavior that has caused real headaches — once for a healthcare client whose IT security team flagged it, and again when I was debugging a DMARC report that looked like a spoofing attempt. If you're not paying attention, this one will surprise you at exactly the wrong moment.
What Click Tracking Actually Does
When you enable click tracking in SendGrid, every URL in your outgoing email gets rewritten to pass through SendGrid's redirect infrastructure before landing at your actual destination. A link that looks like this in your template:
https://app.yourcompany.com/reset-password?token=abc123
becomes something like this in the delivered message:
https://u12345678.ct.sendgrid.net/ls/click?upn=LONGOPAQUESTRING
SendGrid logs the click event, then 302-redirects the user to your original URL. The stat shows up in your dashboard. Clean, right?
Except that what the user actually sees in their email client — in the status bar on hover, in the link preview on mobile — is that ct.sendgrid.net domain. Not yours.
The DMARC Angle
DMARC is about domain alignment. When you've set up SPF and DKIM for yourcompany.com and published a DMARC policy, you're telling the world: mail claiming to be from us should align with our domain. Click tracking doesn't break that alignment for the from address — SendGrid handles DKIM signing correctly for the sender domain. That part is fine.
The problem shows up in a different place: DMARC aggregate reports (rua reports). Those XML files that land in your abuse inbox every morning contain data about every message that passed through DMARC evaluation. When security teams or automated analyzers see links pointing at ct.sendgrid.net in mail signed by yourcompany.com, they start asking questions. It doesn't fail DMARC — but it looks suspicious. I've had a healthcare client's IT security vendor flag this in a quarterly email audit and hand me a two-page report that took longer to explain than it did to fix.
More importantly: if you've set up a custom tracking domain — which SendGrid supports and which I'll get to — and that domain isn't properly configured in your DNS and sending setup, you can create actual alignment problems. I've seen this happen when someone migrated to a new SendGrid subuser and forgot to re-associate the custom domain.
What You Should Actually Do
SendGrid lets you configure a custom tracking domain (they call it a "whitelabel link" in older docs, or "link branding" in the current UI). Instead of ct.sendgrid.net, your rewritten links go through something like links.yourcompany.com. The redirect behavior is identical, but the domain the user sees is yours.
Set this up under Settings → Sender Authentication → Authenticate a Link Branding Domain in the SendGrid dashboard. You'll get a CNAME record to add to your DNS pointing links.yourcompany.com at SendGrid's infrastructure. Once it's verified, SendGrid automatically uses it for all outbound mail from that sender.
In my Laravel projects, I use the symfony/mailer driver via laravel/sendgrid-driver or the official SendGrid PHP library for anything that needs fine-grained control. Here's a practical pattern I use when I want to selectively disable click tracking on certain messages — like password resets, where the link is sensitive and I don't want it going through any redirect:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class PasswordResetMail extends Mailable
{
use Queueable, SerializesModels;
public function __construct(
public readonly string $resetUrl,
) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Reset your password',
);
}
public function content(): Content
{
return new Content(
markdown: 'emails.password-reset',
);
}
/**
* Disable SendGrid click tracking for this message.
* Password reset links should go directly to our domain — no redirects.
*/
public function headers(): \Illuminate\Mail\Mailables\Headers
{
return new \Illuminate\Mail\Mailables\Headers(
text: [
'X-SMTPAPI' => json_encode([
'filters' => [
'clicktrack' => [
'settings' => [
'enable' => 0,
],
],
],
]),
],
);
}
}
The X-SMTPAPI header is SendGrid's per-message override system. You can enable or disable any filter — click tracking, open tracking, subscription management — on a per-message basis using that header. This works even if click tracking is enabled globally on your account. The JSON gets stripped before delivery; it's purely an instruction to SendGrid's mail pipeline.
If you're using the v3 Mail Send API directly instead of SMTP, the equivalent goes in the tracking_settings object:
$body = [
'personalizations' => [
['to' => [['email' => $toAddress]]],
],
'from' => ['email' => 'noreply@yourcompany.com'],
'subject' => 'Reset your password',
'content' => [
['type' => 'text/html', 'value' => $htmlBody],
],
'tracking_settings' => [
'click_tracking' => [
'enable' => false,
'enable_text' => false,
],
],
];
I use the API directly for bulk sends and anything that needs the full v3 feature set. For transactional one-offs in Laravel, the SMTP path with the X-SMTPAPI header is cleaner.
The Gotchas That Actually Bit Me
Custom domain verification doesn't cascade automatically. If you set up link branding on one SendGrid subuser or IP pool and then send from a different one — which happens more than you'd think during account reorganization — the links go back to ct.sendgrid.net. Verify your link branding is associated with the right sending identity, not just the account.
The plain-text part gets rewritten too. This is the one that causes real user trust problems. If your plain-text email body includes a raw URL — which many clients show in email readers — it also gets rewritten. That means a user reading your email in a plain-text client or email archiver sees the SendGrid redirect URL in full, which is both ugly and alarming. If you're disabling click tracking, pass enable_text: false explicitly, or use the clicktrack_text filter in SMTPAPI. They're separate settings.
Redirects break signed URLs. I hit this on a document-signing integration for a legal-tech client. The original URL had a cryptographic signature in the query string. SendGrid's redirect treated the entire original URL as an opaque blob and encoded it into the redirect URL — the final destination was correct — but the intermediate redirect response had headers that some strict link validators in enterprise email gateways tried to follow, which caused the signature check to fail on the first request. The fix was to disable click tracking for that specific email type. I wasted most of an afternoon on it.
URL rewriting happens server-side before delivery. You can't inspect the rewritten URLs before they go out without either looking at delivered message source or setting up a webhook to capture click events. If you want to audit what SendGrid is doing to your links, the Event Webhook with a tool like RequestBin during development is worth the setup time.
When I'd Use Click Tracking, and When I Wouldn't
I leave click tracking on for marketing-adjacent transactional email — onboarding sequences, feature announcements, anything where I actually care about engagement metrics. I configure the custom link branding domain first, always. No exceptions.
I disable it per-message for:
- Password resets and account security emails
- Anything with a signed or time-limited URL
- Emails to healthcare users (HIPAA optics; an IT auditor seeing third-party redirects in PHI-adjacent email is a conversation I'd rather not have)
- Any email where the URL is itself meaningful to the user, like a shareable link or a document URL they might copy out
If you're on a plan where you're not actually looking at click metrics — a lot of small clients are — turn off click tracking globally. There's no reason to route your users through SendGrid's infrastructure and take on that dependency if you're not using the data.
Bottom Line
SendGrid click tracking is a reasonable feature that most people enable without reading what it actually does. Set up custom link branding before you send a single email, and build in per-message opt-out for anything security-sensitive. The X-SMTPAPI header is your friend — use it.
Need help shipping something like this? Get in touch.