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, FounderUpdated
On this page
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.
What iOS 17 Link Tracking Protection does
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.
| Parameter | Set by | Safari, per Stape (August 2025) | Firefox 102 Strict, per Mozilla |
|---|---|---|---|
| gclid | Google Ads auto-tagging | Stripped in all 3 places | Not among the 8 |
| fbclid | Meta ads | Stripped in the same 3 places | Stripped |
| utm_source, utm_medium, utm_campaign | Your own tagging | Not stripped in Private Browsing | Not among the 8 |
| mc_eid | Mailchimp emails | Not reported | Stripped |
| mkt_tok | Marketo emails | Not reported | Stripped |
| _hsenc | HubSpot emails | Not reported | Stripped |
Apple names no parameters, so the Safari column rests on one vendor's notes.
Where it applies
| Where the link opens | In Apple's description? | Evidence |
|---|---|---|
| Messages and Mail | Yes | Apple announcement, June 5, 2023 |
| Safari Private Browsing | Yes | Apple, plus the WebKit post for Safari 17.0 |
| A regular Safari tab | No | Apple lists no such case |
| Slack, LinkedIn or Instagram in-app browsers | No | Not 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
| Feature | Ships in | Announced or released | What it restricts |
|---|---|---|---|
| Intelligent Tracking Prevention 2.1 | Safari 12.1, iOS 12.2 | February 2019 | Cookies created through document.cookie last at most 7 days; cookies set in HTTP responses are not covered |
| Intelligent Tracking Prevention 2.3 | Safari 13, iOS 13 | September 23, 2019 | After 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 Protection | iOS 15 | June 7, 2021 | Stops senders from using invisible pixels to see when an email is opened, and hides the recipient's IP address |
| Link Tracking Protection | Safari 17.0, iOS 17 | June 5, 2023 (announced); September 18, 2023 (shipped) | Removes tracking parameters on Apple's list from links in 3 contexts |
| Fingerprinting script limits | Safari 26.0, iOS 26 | September 15, 2025 | Restricts 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 Mail | Newsletter customers shown | Signups filed as Direct | MRR filed as Direct | 12-month revenue filed as Direct |
|---|---|---|---|---|
| 20% | 32 | 8 | $312 | $3,744 |
| 40% | 24 | 16 | $624 | $7,488 |
| 60% | 16 | 24 | $936 | $11,232 |
| 80% | 8 | 32 | $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
| Mechanism | Survives? | Why |
|---|---|---|
| utm_ tags in the URL | Reported yes | Stape reports them arriving in Private Browsing, and Apple could add them to its list |
| gclid, fbclid and similar click IDs | No, in the 3 listed places | Stape reports them stripped |
| A code in the URL path | Yes | No query string, so nothing for a filter to match |
| A click logged on your server | Yes | Recorded before any script on the page runs |
| A cookie set in an HTTP response | Yes | ITP's 7-day cap targets cookies created in JavaScript |
| A cookie written by JavaScript | Capped | 7 days at most, or 24 hours following a decorated link from a classified tracker |
| A visitor ID on the payment | Yes | Stripe 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.
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 field | What it holds | Limit |
|---|---|---|
| client_reference_id | A string for reconciling the session with your own systems | One string per session |
| metadata | Key-value pairs on the session | 50 pairs, keys up to 40 characters, values up to 500 |
| subscription_data.metadata | Pairs saved on the subscription the session creates | The same 50, 40 and 500 limits |
Test your own links on an iPhone
Open one URL that carries 6 parameters in each of these places and check which reach your server.
| Step | Where to open it | What to expect |
|---|---|---|
| 1 to 3 | Messages and Apple Mail, tapped from a thread or email to yourself, then a Safari Private Browsing tab | Going by Stape: 2 click IDs missing, 3 UTM tags present, 1 custom code unknown |
| 4 | Any non-private tab, as the control | All 6 present; a gap points at a redirect or script on your side |
| 5 | Slack, LinkedIn and Instagram in-app browsers | Unknown, because Apple does not describe them |
| 6 | Every iOS release after your last test | Repeat steps 1 to 4, since the list can change |
https://www.example.com/pricing?gclid=test1&fbclid=test2&utm_source=iostest&utm_medium=manual&utm_campaign=ltp&ref=test3grep "utm_source=iostest" /var/log/nginx/access.log | tail -n 5A 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.
Frequently asked questions
- Apple names no parameters. Stape's notes show the 3 standard UTM tags arriving in Safari Private Browsing while gclid and fbclid do not, so test a tagged link in Messages and Apple Mail after each iOS release.
- Apple's 2023 announcement lists Messages, Mail and Safari Private Browsing. Safari tabs outside Private Browsing and the embedded browsers inside other apps are absent from it, so check your server log for what arrived.
- Mail Privacy Protection, in iOS 15 and later, is the feature that hides opens. Link Tracking Protection acts on link URLs, so click data remains the number to build on.
- Only if the parameter reaches the server. When Safari removes it first, the access log has nothing to recover, so put what you need in the path.
- It can for clicks from Private Browsing, Mail or Messages, where gclid is removed. Google says auto-tagging is required for offline conversion tracking, so keep capturing gclid on your landing page.
- Apple's announcement still lists 3 places. Safari 26.0 added a separate fingerprinting limit in September 2025, so repeat the iPhone test after each release.

Written by
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