utm_source
Where the visitor clicked
Tag every campaign consistently, read matching GA4 sessions and key events with read-only access, and use the pattern to choose the next angle—without pretending attribution is perfect.

Google Analytics can only group the visits it receives. Emelyn adds consistent UTM values when it creates the destination link, then keeps those IDs beside the source, draft, channel, and publish record.
utm_source
Where the visitor clicked
utm_medium
social
A consistent traffic type
utm_campaign
eml-2026-08-release
The campaign across its posts
utm_content
practical-post-1
The individual post or creative
https://example.com/guide?utm_source=linkedin&utm_medium=social&utm_campaign=eml-2026-08-release&utm_content=practical-post-1
Choose a GA4 property that already measures the destination website. Sign in with Google OAuth and grant the analytics.readonly scope. Emelyn does not need permission to edit properties, data streams, users, or key events.
PrerequisitesA GA4 property and web data stream, working website tagging, access to that property, consistent UTM naming, and at least one business-relevant key event if you want more than visit counts.
Emelyn lists properties the signed-in account may read. Confirm the website and time zone.
Authorize https://www.googleapis.com/auth/analytics.readonly and store refresh credentials encrypted.
Send a tagged test visit and confirm source, medium, campaign, and content values in DebugView or Realtime.
Start with 28 complete days ending yesterday. Expect processed reports to change for 24–48 hours.
The request groups landing pages and sessions by manual campaign and content values. It also asks Google to return quota status so the connection can slow down before it fails.
POST https://analyticsdata.googleapis.com/v1beta/
properties/GA4_PROPERTY_ID:runReport
Authorization: Bearer <oauth-access-token>
Content-Type: application/json
{
"dateRanges": [{ "startDate": "28daysAgo", "endDate": "yesterday" }],
"dimensions": [
{ "name": "landingPagePlusQueryString" },
{ "name": "sessionSourceMedium" },
{ "name": "sessionManualCampaignName" },
{ "name": "sessionManualAdContent" }
],
"metrics": [
{ "name": "sessions" },
{ "name": "keyEvents" }
],
"dimensionFilter": {
"filter": {
"fieldName": "sessionManualCampaignName",
"stringFilter": { "value": "eml-2026-08", "matchType": "BEGINS_WITH" }
}
},
"returnPropertyQuota": true
}Reporting recipe revision 1.0 · Google Analytics Data API v1beta · Last tested 29 August 2026.
| Link or report field | GA4 field | Meaning |
|---|---|---|
| utm_source | sessionManualSource | Channel that sent the visit |
| utm_medium | sessionManualMedium | Use a consistent value such as social |
| utm_campaign | sessionManualCampaignName | Stable Emelyn campaign ID |
| utm_content | sessionManualAdContent | Distinct post or creative ID |
| landing page + query string | landingPagePlusQueryString | Destination first seen in the session |
| sessions | sessions | Directional visits grouped by the dimensions above |
| key events | keyEvents | Configured business actions—not every click |
Emelyn can compare tagged visits and key events between published posts. It cannot prove that one post caused a sale or reconcile every number shown by a social platform.
Practical posts brought more tagged visits and key events than announcement posts. Test another practical angle before changing the whole strategy.
A redirect or script removed the query string before Analytics read the landing page.
The visit may not be recorded, or the original campaign values may be unavailable when the tag fires.
In-app browsers, privacy controls, copied links, and broken session continuity can hide the source.
The connection records when it queried, which date range was complete, whether Google applied thresholds, and whether a report was empty, delayed, unauthorized, or quota-limited.
Store the report window and matched campaign IDs. Refresh recent days later because processing can change.
Use returned quota information and back off. Reduce dimensions, date range, or concurrency before retrying.
The OAuth token expired or was revoked. Stop reads and ask the owner to reconnect.
An incompatible dimension, metric, filter, or property ID will not improve with retries.
QuotaCore reports consume property tokens and concurrent-request capacity. High-cardinality dimensions and long ranges cost more.
PrivacyEmelyn reads campaign-level report rows, not user-level identities. Google may threshold low-volume data.
DisconnectRevoke the Google connection to stop new reads. Remove saved reporting snapshots through the normal Emelyn data-deletion controls.
Search results and practitioner discussions focus on UTMs, missing sessions, direct traffic, consent timing, and numbers that disagree across platforms. The integration answers those questions and follows the current Data API schema, OAuth scope, quota, and freshness guidance.