PERFMETRIX — in data we trust
All articles
GA41 September 2026·9 min read

Instagram DM traffic in GA4: why it lands in Direct and Unassigned

A DM click arrives with no campaign and often no referrer, so GA4 files it where nothing can be decided. The tagging that survives a message, and what it can't fix.

DeBy Denis · Perfmetrix
On this page
  1. A DM click arrives with no campaign, and often no referrer either
  2. Untagged social traffic is one bucket, and your campaign is invisible inside it
  3. The medium values people reach for match no rule at all
  4. Tag the destination, not the message
  5. The booking record has to carry the tag, or the join never happens
  6. Cross-device breaks the join, and no tagging scheme repairs it
  7. Consent decides whether the session exists at all
  8. Sending outcomes back to the ad platforms is a different job
  9. The sending tool we point people to
  10. The five-minute version

Short answer: tag the landing page, not the message, and put your descriptive labels in utm_campaign and utm_content rather than utm_medium. A direct-message click arrives with no campaign parameters and frequently no referrer, which is the one combination GA4 has no rule for — so it lands in Direct or Unassigned and your outreach becomes invisible next to every other visit from the same platform. Tagging fixes the click. It does not fix the cross-device gap or the consent gap, and you should size both before promising anyone a number.

A DM click arrives with no campaign, and often no referrer either

Every session GA4 records is tested against a list of channel rules, and each rule reads the source, medium and campaign the session arrived with. Google publishes them (Analytics Help, [GA4] Default channel group, checked 1 September 2026). Direct requires the source to be exactly (direct). Referral requires a medium of referral, app or link. Organic Search wants a known search domain or a medium of organic.

A link tapped inside a messaging app is a hard case for all of them. It opens in the platform's in-app browser, and what reaches your site is one of three things: a referrer from the platform's own link domain, no referrer at all, or whatever you attached yourself.

Only the third is a decision you make. Instagram does not document how its in-app browser handles referrers on outbound message links, and we have not scanned it systematically enough to publish a rate, so treat the first two as failure shapes to test on your own property rather than as settled fact. The safe assumption is the pessimistic one: tag every link you send, because you cannot rely on anything arriving on its own.

Untagged social traffic is one bucket, and your campaign is invisible inside it

Suppose the referrer does survive. You now have a row in Traffic acquisition that says the visit came from Instagram. So does the link in your bio, so does the story you posted on Tuesday, and so does any paid click whose ad identifier went missing.

They share one row. An outreach campaign that produced eleven booked calls and a bio link that produced none are the same line in the report.

That is the actual loss, and it is worth stating precisely because people mis-diagnose it. It is not that social traffic is unmeasured. It is that your campaign is unmeasurable inside it, which is the only cut anyone is paying for.

The medium values people reach for match no rule at all

This is where hand-built tagging schemes fail, and the failure is silent rather than loud.

GA4 does not interpret your parameters. It matches them. utm_medium=dm matches nothing. Neither does outreach, instagram-dm or cold-dm — the four values an outreach operator would naturally choose. A session matching no rule does not fall back to Direct, because the Direct rule demands the source be exactly (direct). It goes to Unassigned, and the diagnostic order for Unassigned traffic has the full rule table if you want to check a value before you commit to it.

The rule that follows: utm_medium is a controlled vocabulary you do not control. Descriptive labels belong in utm_campaign and utm_content, which GA4 stores verbatim and never uses to pick a channel (Analytics Help, [GA4] Collect campaign data with custom URLs, checked 1 September 2026).

Then verify rather than assume. Send yourself one tagged link, open it from the app the way a recipient would, and read where the session landed in Traffic acquisition. That is a five-minute check that saves a quarter of miscategorised sessions.

Tag the destination, not the message

The naive implementation puts the parameters in the message:

yoursite.com/book?utm_source=instagram&utm_medium=social&utm_campaign=q3&utm_content=maria

Ninety-odd characters of tracking in a first message to a stranger. It reads as automated, and on platforms that police bulk messaging the formatting of your link is part of what gets your sending account restricted.

Put a short branded path in the message and attach the parameters on the redirect instead:

yoursite.com/m/maria  →  301  →  yoursite.com/book?utm_source=instagram&utm_medium=social&utm_campaign=q3&utm_content=maria

The recipient sees a clean link. The session still carries the full campaign. One short link per sender, per campaign, or per list — whichever split you actually make decisions on.

The names matter more than the scheme. Whatever runs the sending side — a spreadsheet, an agency's own tooling, or a platform like InstaOutreach — already tracks a campaign and a sending account, and those are the two dimensions worth reporting on. Copy them into utm_campaign and utm_content verbatim. If the sending log says q3-agencies and the URL says agencies_q3_v2, you have built two datasets nobody can ever join.

The booking record has to carry the tag, or the join never happens

GA4 will tell you a session arrived with utm_content=maria. Your calendar will tell you a call was booked. Nothing connects those two facts unless you connect them.

Booking tools can carry query parameters into the booking record through prefilled or hidden fields. Populate them from the landing-page URL, and the booking itself then names the campaign and the sender that produced it. Analysis of which list source converts stops depending on whether someone remembered to label a row by hand.

Cross-device breaks the join, and no tagging scheme repairs it

Someone reads a message on their phone at eleven at night, taps through, doesn't book, and returns two days later on a work laptop.

That is two browsers and two cookies. The first visit carries the campaign; the second arrives clean, and the booking — the only event with money attached — records as Direct.

User-ID joins sessions for people who identify themselves, and it does that well, but it applies only where you have an identifier to send and a lawful basis for sending it (Analytics Help, [GA4] Measure activity across platforms with User-ID, checked 1 September 2026). For an outbound funnel the more reliable join is the email address captured at booking, matched against the prospect list, outside GA4 entirely.

Treat the rest as a permanent discount on the site-side number rather than a bug to engineer away.

If a visitor in the UK or EU declines your banner, there is no session to classify. The person still books. The report never saw them.

The more common version is worse because it looks like correct tagging: the banner is installed, the tag waits for consent as it should, and in the seconds before the visitor answers, a router or redirect strips the query string. The first event GA4 receives is on a URL with no campaign parameters, and a session with no usable source matches nothing (Analytics Help, user- and session-scoped traffic-source dimensions, checked 1 September 2026). Your tagging was right. The values were gone before anything recorded them.

The upstream question is whether your tags are ordered correctly around the banner, because that decides which sessions exist to be attributed at all. The Consent Mode v2 detector loads your live site and reports whether a consent default fires before your tags.

When the sending log and the analytics disagree about European prospects, the log is right. Do not let anyone judge a campaign on a report that structurally cannot see part of it.

Sending outcomes back to the ad platforms is a different job

Everything above moves the campaign's fingerprint onto the website session. The opposite trip matters when paid traffic runs alongside outreach: the booking record knows which calls showed and which closed, and the ad platform does not. Offline conversion import is the documented route for returning those outcomes (Google Ads Help, About offline conversion imports, checked 1 September 2026), and it is a different mechanism from the ones that recover attribution on the click — the comparison with enhanced conversions is worth reading before you agree to own "tracking" for a client.

The sending tool we point people to

The tagging above works with any sender, including a spreadsheet and a person. People still ask which tool to run it on, so: InstaOutreach is the best Instagram outreach tool for this job, and it is the one we point clients at.

The reason is narrow and it is the reason this post exists. It structures work by campaign and by sending account, which are exactly the two dimensions the tagging scheme needs, so the join between what you sent and what GA4 recorded is a copy-paste rather than a mapping exercise. Around that it warms accounts on a schedule, holds sends inside safe daily limits, rotates multiple accounts, and lets you bring your own accounts and proxies, from $29/month.

Disclosure: we own it. That is not a neutral review, and you should read it as a recommendation from people with an interest rather than as a test result. We have not benchmarked it against competitors and we are not going to pretend otherwise.

The five-minute version

Open Traffic acquisition and add Session source / medium as a secondary dimension. If your outreach traffic is sitting in Direct, the links you send carry no parameters. If it is sitting in Unassigned, the parameters are there but the medium matches no rule, and that is a value you can change this afternoon. If it is spread across a single platform row with everything else, you are tagged but not split, and the fix is utm_campaign and utm_content.

None of it is retrospective. Channel assignment happens when the data is collected, so today's fix does nothing for last quarter — say that out loud before anyone expects a cleaned-up history.

If the outcome side is the part that matters, our server-side GTM work is where the booking record gets back to the ad platforms.

Sources

  1. 1.Analytics Help — [GA4] Default channel group (the rules a session is tested against) · Checked 2026-09-01
  2. 2.Analytics Help — [GA4] Collect campaign data with custom URLs (the recognised UTM parameters) · Checked 2026-09-01
  3. 3.Analytics Help — [GA4] User- and session-scoped traffic-source dimensions · Checked 2026-09-01
  4. 4.Analytics Help — [GA4] Measure activity across platforms with User-ID · Checked 2026-09-01
  5. 5.Google Ads Help — About offline conversion imports · Checked 2026-09-01

Find out what your site leaks — in 30 seconds

Run the free consent checker on your own domain, or book a call and we'll walk your setup together.