iOS 17 Link Tracking Protection: what it strips and what survives

iOS 17 Link Tracking Protection removes known tracking parameters in Messages, Mail and Private Browsing. What it strips, what survives and how to test it.

Muzahid Maruf — Founder of TrackRev.io

Muzahid MarufUpdated

Revenue attribution · 8 min read
On this page
  1. 01What iOS 17 Link Tracking Protection does
  2. 02Apple privacy changes that cause similar symptoms
  3. 03What breaks in a SaaS funnel
  4. 04What survives and why
  5. 05Test your own links on an iPhone
  6. 06How TrackRev handles the click

Explore with AI

Opens this article inside the chosen assistant with a ready-made prompt.

iOS 17 Link Tracking Protection removes known tracking parameters from links in Messages, Mail and Safari Private Browsing, and Apple publishes no list of which ones.

According to Stape, gclid and fbclid are removed while utm_ tags still arrive in Private Browsing.

What survives lives outside the query string: a short code in the URL path, a click logged on your server, a cookie your server sets in a response, and a visitor ID stored with the payment.

Key takeaways

  • Apple announced Link Tracking Protection on June 5, 2023 and names no parameters, so every list of what it strips comes from outside Apple.
  • Stape reports gclid and fbclid removed in 3 places while utm_ tags arrive in Private Browsing, so keep a second copy of every source outside the URL.
  • Safari deletes cookies created in JavaScript after 7 days without a visit, and a cookie set in a server response is outside that cap.
  • Mail Privacy Protection, Intelligent Tracking Prevention and Link Tracking Protection restrict different things, so test each hop on an iPhone before blaming one.

Apple announced the feature on June 5, 2023, under the heading Link Tracking Protection in Messages, Mail, and Safari Private Browsing.

The extra information some websites add to URLs to follow people across other sites is removed from links shared in Messages and Mail, and from links in Private Browsing, and the links keep working.

The WebKit post for Safari 17.0, which reached iOS 17 on September 18, 2023, lists blocking known tracking query parameters in links among the Private Browsing changes. Neither page names a parameter.

Every list of stripped parameters therefore comes from outside Apple. Stape, a server-side tagging vendor, reports gclid and fbclid stripped in all 3 places, and the standard UTM tags kept in Private Browsing.

I found no Apple commitment to leave them alone.

Which parameters it removes

Mozilla's query stripping documentation names 8 parameters for Firefox 102 (June 28, 2022) in Strict mode and says no standard yet defines navigational tracking protection.

The W3C Privacy Community Group's March 2025 draft adds that Brave keeps a list of its own.

ParameterSet bySafari, per Stape (August 2025)Firefox 102 Strict, per Mozilla
gclidGoogle Ads auto-taggingStripped in all 3 placesNot among the 8
fbclidMeta adsStripped in the same 3 placesStripped
utm_source, utm_medium, utm_campaignYour own taggingNot stripped in Private BrowsingNot among the 8
mc_eidMailchimp emailsNot reportedStripped
mkt_tokMarketo emailsNot reportedStripped
_hsencHubSpot emailsNot reportedStripped

Apple names no parameters, so the Safari column rests on one vendor's notes.

Where it applies

Where the link opensIn Apple's description?Evidence
Messages and MailYesApple announcement, June 5, 2023
Safari Private BrowsingYesApple, plus the WebKit post for Safari 17.0
A regular Safari tabNoApple lists no such case
Slack, LinkedIn or Instagram in-app browsersNoNot mentioned, so test each one

Stape's article, updated August 6, 2025, says Safari might extend the protection beyond those places in iOS 26 and that Apple had confirmed only the original three. I found no Apple statement that it did.

What Safari 26.0 added, according to WebKit's September 15, 2025 post, is a separate limit: known fingerprinting scripts can no longer read query parameters or document.referrer, and cannot set long-lived cookies or LocalStorage.

The post doesn't say which scripts count as known.

Apple privacy changes that cause similar symptoms

FeatureShips inAnnounced or releasedWhat it restricts
Intelligent Tracking Prevention 2.1Safari 12.1, iOS 12.2February 2019Cookies created through document.cookie last at most 7 days; cookies set in HTTP responses are not covered
Intelligent Tracking Prevention 2.3Safari 13, iOS 13September 23, 2019After a navigation from a classified tracker to a URL with a query string, LocalStorage and other non-cookie data are deleted after 7 days without an interaction
Mail Privacy ProtectioniOS 15June 7, 2021Stops senders from using invisible pixels to see when an email is opened, and hides the recipient's IP address
Link Tracking ProtectionSafari 17.0, iOS 17June 5, 2023 (announced); September 18, 2023 (shipped)Removes tracking parameters on Apple's list from links in 3 contexts
Fingerprinting script limitsSafari 26.0, iOS 26September 15, 2025Restricts what fingerprinting scripts can read and store

Litmus's July 2026 data puts Apple clients at 62.26% of email opens, ahead of Gmail at 27.03% and Outlook at 5.83%, and says Mail Privacy Protection affects roughly 55-60% of all opens, so open rates say little and clicks are the signal worth keeping.

Clicks inside Apple Mail are the ones Link Tracking Protection can touch. Our Safari ITP post covers the cookie rows from the revenue side.

What breaks in a SaaS funnel

Exposure follows the channel. Paid search mostly sits outside the 3 listed places: Google Ads adds gclid through auto-tagging, and a Google Search click that opens in an ordinary tab is not on Apple's list.

Newsletters are the exposed case, since a tap in Apple Mail is on it, and a source ID from Mailchimp or HubSpot, such as mc_eid or _hsenc, is the kind of parameter Firefox 102 already strips.

The cost shows up as misfiled revenue. Take 40 signups a month from one newsletter on a $39 plan, where every signup who arrives through Apple Mail loses its source ID.

Share arriving through Apple MailNewsletter customers shownSignups filed as DirectMRR filed as Direct12-month revenue filed as Direct
20%328$312$3,744
40%2416$624$7,488
60%1624$936$11,232
80%832$1,248$14,976

Invented numbers for the arithmetic: 40 signups a month on a $39 plan, each paying for 12 months.

What survives and why

MechanismSurvives?Why
utm_ tags in the URLReported yesStape reports them arriving in Private Browsing, and Apple could add them to its list
gclid, fbclid and similar click IDsNo, in the 3 listed placesStape reports them stripped
A code in the URL pathYesNo query string, so nothing for a filter to match
A click logged on your serverYesRecorded before any script on the page runs
A cookie set in an HTTP responseYesITP's 7-day cap targets cookies created in JavaScript
A cookie written by JavaScriptCapped7 days at most, or 24 hours following a decorated link from a classified tracker
A visitor ID on the paymentYesStripe stores it, out of any browser's reach

A redirect that reads the path

A server log cannot recover a parameter that Safari removed before the request, so the click's identity goes in the path of a link you own, such as go.example.com/spring-launch.

The redirect logs the click, sets the visitor cookie and sends a 302 built from saved UTM tags.

A path-based redirect that logs the click and sets the visitor cookie (Express with cookie-parser)
const crypto = require("crypto"); // go.example.com/spring-launch: the click's identity is the path, not a query parameterapp.get("/:code", async (req, res) => {  const link = await db.links.findByCode(req.params.code);  if (!link) return res.redirect(302, "https://www.example.com");   let vid = req.cookies.vid;  if (!vid) {    vid = crypto.randomUUID();    res.cookie("vid", vid, {      maxAge: 365 * 24 * 60 * 60 * 1000, // one year, in milliseconds      domain: ".example.com",            // readable by www, app and checkout      secure: true,      sameSite: "lax",    });  }   await db.clicks.insert({    linkId: link.id,    vid,    userAgent: req.get("user-agent"),    referer: req.get("referer"),  });   const destination = new URL(link.destination);  destination.searchParams.set("utm_source", link.utmSource);  destination.searchParams.set("utm_medium", link.utmMedium);  destination.searchParams.set("utm_campaign", link.utmCampaign);  res.redirect(302, destination.toString());});

Setting Domain=.example.com lets www.example.com, app.example.com and checkout.example.com read one cookie, which a shared shortener cannot offer.

Something must then carry the ID across the hop, usually a destination parameter, and the Privacy Community Group draft says Safari caps JavaScript cookies at 24 hours when that navigation comes from a domain it classifies as a tracker.

Apple publishes no classifier, so test your own hop on a phone.

WebKit's tracking prevention page exempts cookies set in an HTTP response from the 7-day cap unless it detects CNAME or IP-address cloaking on a first-party subresource.

A short link is a page navigation, so I read that rule as aimed at pixels on CNAME subdomains.

Store the visitor ID on the payment

A visitor who clicks on a Monday and subscribes 9 days later has lost a JavaScript cookie, while an ID stored on the payment cannot expire.

Write the visitor ID into the Stripe fields below when you create the Checkout Session. Stripe does not copy the session's metadata to the subscription, so set subscription_data.metadata too and each renewal invoice carries a snapshot of the source.

The Stripe metadata attribution setup post has the field mapping.

Stripe fieldWhat it holdsLimit
client_reference_idA string for reconciling the session with your own systemsOne string per session
metadataKey-value pairs on the session50 pairs, keys up to 40 characters, values up to 500
subscription_data.metadataPairs saved on the subscription the session createsThe same 50, 40 and 500 limits

Open one URL that carries 6 parameters in each of these places and check which reach your server.

StepWhere to open itWhat to expect
1 to 3Messages and Apple Mail, tapped from a thread or email to yourself, then a Safari Private Browsing tabGoing by Stape: 2 click IDs missing, 3 UTM tags present, 1 custom code unknown
4Any non-private tab, as the controlAll 6 present; a gap points at a redirect or script on your side
5Slack, LinkedIn and Instagram in-app browsersUnknown, because Apple does not describe them
6Every iOS release after your last testRepeat steps 1 to 4, since the list can change
A test URL with click IDs, UTM tags and a custom code
https://www.example.com/pricing?gclid=test1&fbclid=test2&utm_source=iostest&utm_medium=manual&utm_campaign=ltp&ref=test3
Read the request your server received, not the address bar
grep "utm_source=iostest" /var/log/nginx/access.log | tail -n 5

A parameter in the log after the Messages tap was not removed before the request. One missing from it was dropped on the device or in a hop, and the 5-step hop test finds which.

How TrackRev handles the click

TrackRev is SaaS affiliate software with link tracking built in, and a TrackRev link keeps its channel and UTM tags on the saved link, so the shared URL holds only a short code.

The redirect logs the click on the server, adds the saved tags and a _vid visitor parameter to the destination, and answers with a 302. A custom tracking domain takes one CNAME record pointed at cname.trackrev.io.

The pixel reads _vid on the first pageview and writes its own vid cookie with JavaScript, so Safari's 7-day cap applies and a visitor who returns later is new to the pixel.

When someone identifies, TrackRev binds the visitor ID to their email, and the hourly sync of the Stripe integration matches charges to clicks through it.

The pixel also adds the visitor ID as client_reference_id to Payment Links and Buy Buttons, and renewals keep crediting the original click.

The redirect forwards only the saved tags and _vid, so a gclid added to a short link at send time never reaches your page.

The Free plan covers 50 links and 1,000 tracked events a month for link tracking, with revenue figures hidden. Seeing revenue by channel needs a paid plan, from Indie at $29 a month (pricing).

If you only need sessions by source in Google Analytics 4, UTM tags that arrive and the naming rules in the UTM parameters guide go most of the way without another tool.

Found this useful? Share it.

PostLinkedIn

Frequently asked questions

Muzahid Maruf — Founder of TrackRev.io

Written by

Muzahid Maruf

Founder, TrackRev.io & Contant.io

Muzahid Maruf founded TrackRev.io, SaaS affiliate software with no limit on tracked revenue, and Contant.io. He writes about affiliate programs.

Writes about Marketing attribution · Link tracking · Revenue analytics · SaaS growth

Stop guessing where your revenue comes from.

Set up TrackRev in about five minutes. The free plan covers 1,000 events a month, no card needed.

Start free