Instructions

GA4 Measurement Protocol: What It Is and How to Set It Up

| 21 May 2026 Updated: 22 May 2026 | 11 min read 0 views
GA4 Measurement Protocol: What It Is and How to Set It Up — cover

GA4 Measurement Protocol is Google’s HTTP API that lets you send analytics events directly from a server, offline system, or IoT device — bypassing the browser entirely. If your business handles offline conversions, server-side checkout confirmations, or CRM data, Measurement Protocol fills the gaps your browser tag cannot reach.

What Is Measurement Protocol

Measurement Protocol is a Google Analytics API that allows you to send event data directly to GA4 without a browser or JavaScript tag. Instead of waiting for gtag.js or GTM to fire on a page, you construct an HTTP POST request and send it straight to the GA4 server.

There are two generations of Measurement Protocol: v1 for Universal Analytics and v2 for Google Analytics 4. The key difference lies in the data model. Universal Analytics Measurement Protocol built hits around fixed types — pageview, event, ecommerce transaction. GA4 Measurement Protocol is built entirely around the event model: you send an array of event objects with arbitrary parameters, consistent with the overall GA4 architecture.

Universal Analytics was officially decommissioned in July 2024. If you are still sending data using the v1 Measurement Protocol endpoint, that is critical technical debt that needs addressing. Migration to GA4 Measurement Protocol v2 is required.

Two foundational use cases: (1) a European ecommerce store sends a purchase event from the server after payment confirmation to prevent duplicate conversions from browser tag page refreshes; (2) a sales team logs a phone-based sale in the CRM and sends an offline conversion event to GA4, tied to the original session via client_id.

When You Need Measurement Protocol

Measurement Protocol does not replace a standard GA4 implementation via gtag.js or Google Tag Manager. It addresses specific scenarios where JavaScript is unavailable or unreliable:

  1. Server-side events. Order confirmations, payment status changes, subscription activations — these events happen on the server with no browser involvement. Measurement Protocol lets you send them directly to GA4.
  2. Offline conversions. Phone sales, in-office conversions, CRM deals that close outside the website — Measurement Protocol lets you bring this data into GA4 and link it to the originating session.
  3. IoT devices. Self-service terminals, smart devices, mobile apps on embedded systems — any device that can send an HTTP request can send events to GA4.
  4. Game events. Mobile or desktop games can send events (level start, in-game purchase, achievement unlocked) directly from the game server, without a browser tag.
  5. CRM data import. If a deal in your CRM closes a week after first contact, you can send an event with timestamp_micros to attribute the conversion to the correct session and traffic source.

How GA4 Measurement Protocol Works

The architecture is straightforward: your server or application constructs an HTTP POST request and sends it to the GA4 endpoint. Google processes the request and the data appears in your Google Analytics 4 reports.

Production endpoint:

POST https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXXX&api_secret=XXXXXXXXXX

Debug endpoint (validates without writing to GA4):

POST https://www.google-analytics.com/debug/mp/collect?measurement_id=G-XXXXXXXX&api_secret=XXXXXXXXXX

The request body is JSON with the following required fields:

Required URL query parameters: measurement_id (G-XXXXXXXX from GA4 Admin) and api_secret (generated in GA4 Admin settings).

How GA4 Measurement Protocol Works — architecture diagram

Step-by-Step Setup

Step 1. Get Measurement ID and API Secret

  1. Open GA4 → Admin → Data Streams.
  2. Select your web stream and copy the Measurement ID (format: G-XXXXXXXX).
  3. Scroll down to “Measurement Protocol API secrets” → click “Create”.
  4. Name it (e.g., “server-events”) and copy the generated API Secret.

Never expose your API Secret in frontend code or public repositories. It is a server-side secret — store it in environment variables (.env) or a secret manager.

Step 2. Send Your First Request with curl

curl -X POST \
  "https://www.google-analytics.com/debug/mp/collect?measurement_id=G-XXXXXXXX&api_secret=YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "test-client-123",
    "events": [{
      "name": "test_event",
      "params": {
        "custom_param": "hello_from_server"
      }
    }]
  }'

Note: use /debug/mp/collect — the debug endpoint returns a JSON validation report and does not write data to GA4.

Step 3. Python Example

import requests

MEASUREMENT_ID = "G-XXXXXXXX"
API_SECRET = "your_api_secret_here"

def send_ga4_event(client_id, event_name, params=None):
    url = "https://www.google-analytics.com/mp/collect"
    payload = {
        "client_id": client_id,
        "events": [{
            "name": event_name,
            "params": params or {}
        }]
    }
    response = requests.post(
        url,
        params={"measurement_id": MEASUREMENT_ID, "api_secret": API_SECRET},
        json=payload
    )
    return response.status_code  # 204 = accepted

status = send_ga4_event(
    client_id="user_12345",
    event_name="purchase",
    params={
        "transaction_id": "T_12345",
        "value": 149.99,
        "currency": "EUR"
    }
)
print(f"Status: {status}")

Step 4. Verify in GA4 DebugView

To monitor live events: GA4 → Configure → DebugView. For Measurement Protocol events to appear in DebugView, add "debug_mode": 1 to the event params, then send to the production endpoint (/mp/collect).

GA4 Measurement Protocol Setup Steps — infographic

Required and Optional Parameters

ParameterLocationRequiredDescription
measurement_idQuery stringYesGA4 stream ID, format G-XXXXXXXX
api_secretQuery stringYesAPI secret key from GA4 Admin
client_idJSON bodyYesUnique client/browser identifier
user_idJSON bodyNoAuthenticated user ID (for cross-device tracking)
timestamp_microsJSON bodyNoEvent time in microseconds (Unix epoch). Max: 72 hours ago
non_personalized_adsJSON bodyNotrue/false — disable personalized advertising for this event
events[].nameJSON bodyYesEvent name. Max 40 characters
events[].paramsJSON bodyNoEvent parameters object (up to 25 parameters)

Event Examples

page_view event

curl -X POST \
  "https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXXX&api_secret=YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "user_abc123",
    "events": [{
      "name": "page_view",
      "params": {
        "page_location": "https://example.com/products/running-shoes/",
        "page_title": "Running Shoes — Buy Online",
        "engagement_time_msec": 100
      }
    }]
  }'

Custom event

curl -X POST \
  "https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXXX&api_secret=YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "user_abc123",
    "user_id": "crm_user_987",
    "timestamp_micros": 1716285600000000,
    "events": [{
      "name": "crm_deal_closed",
      "params": {
        "deal_id": "CRM-456",
        "deal_value": 4200,
        "currency": "EUR",
        "sales_region": "europe_west"
      }
    }]
  }'

Measurement Protocol for Ecommerce

The most common use case for European ecommerce businesses is sending a server-side purchase event after payment confirmation. This eliminates the duplicate conversions that occur when a customer refreshes the order confirmation page.

purchase event with items array

curl -X POST \
  "https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXXX&api_secret=YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "user_abc123",
    "events": [{
      "name": "purchase",
      "params": {
        "transaction_id": "ORDER-78901",
        "value": 189.97,
        "tax": 31.66,
        "shipping": 9.99,
        "currency": "EUR",
        "coupon": "SUMMER10",
        "items": [
          {
            "item_id": "SKU_001",
            "item_name": "Nike Air Max Running Shoes",
            "item_category": "Footwear",
            "price": 149.99,
            "quantity": 1
          },
          {
            "item_id": "SKU_002",
            "item_name": "Sports Socks Pack",
            "item_category": "Accessories",
            "price": 14.99,
            "quantity": 2
          }
        ]
      }
    }]
  }'

refund event

curl -X POST \
  "https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXXX&api_secret=YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "user_abc123",
    "events": [{
      "name": "refund",
      "params": {
        "transaction_id": "ORDER-78901",
        "value": 149.99,
        "currency": "EUR",
        "items": [
          {
            "item_id": "SKU_001",
            "quantity": 1
          }
        ]
      }
    }]
  }'

Debug Mode and Validation

GA4 provides two tools for debugging Measurement Protocol:

Debug endpoint /debug/mp/collect

Send requests to https://www.google-analytics.com/debug/mp/collect instead of /mp/collect. The debug endpoint returns a JSON validation report and does not write data to GA4. Example error response:

{
  "validationMessages": [
    {
      "fieldPath": "events[0].name",
      "description": "Event name must match the pattern '^(?!ga_)(?!_)[A-Za-z][A-Za-z0-9_]{0,39}$'",
      "validationCode": "NAME_INVALID"
    }
  ]
}

A valid request returns: {"validationMessages": []}.

DebugView in GA4

For real-time event monitoring: GA4 → Configure → DebugView. To display Measurement Protocol events in DebugView, add "debug_mode": 1 to the event params and send to the production endpoint (/mp/collect). Events appear within seconds.

Common Mistakes with Measurement Protocol

Common Mistakes with GA4 Measurement Protocol
  1. Wrong endpoint. Using the UA endpoint www.google-analytics.com/collect instead of the GA4 endpoint www.google-analytics.com/mp/collect. Data simply will not arrive in GA4.
  2. Missing or mismatched client_id. If client_id does not match the value in the browser’s _ga cookie, server-side and browser-side sessions will not be joined. Always pass the actual GA client_id extracted from the browser.
  3. Invalid event names. GA4 requires: Latin letters, digits, and underscores; must start with a letter; cannot start with ga_; max 40 characters. Names with spaces, special characters, or non-Latin scripts fail validation.
  4. Misreading 204 No Content as success. A 204 response means the request was technically accepted, but does not guarantee data correctness or that it appeared in reports. Always validate with the debug endpoint first.
  5. timestamp_micros outside the 72-hour window. GA4 silently drops events older than 72 hours. For importing older data, use the Data Import feature in GA4 Admin.
  6. API Secret exposed in frontend code. If api_secret leaks into client-side JavaScript or a public repository, anyone can send fake events into your GA4 property. Keep it server-side only.
  7. Duplicate events. If both the browser tag (gtag.js/GTM) and server-side Measurement Protocol send the same purchase event, the conversion is counted twice. Choose one source of truth per event type, or deduplicate using transaction_id.

FAQ: Measurement Protocol Questions

Does Measurement Protocol replace gtag.js or GTM?

No. Measurement Protocol is a complement, not a replacement. GTM and gtag.js track browser behavior via JavaScript. Measurement Protocol handles server-side events, offline conversions, and scenarios where JavaScript is not available. In ecommerce projects across Europe, both tools are often used in parallel.

Can you send events with a past timestamp?

Yes, using timestamp_micros you can specify event time in Unix epoch microseconds. GA4 accepts events up to 72 hours in the past. Events older than 72 hours are silently dropped and will not appear in reports.

How many events can you send in one request?

A single HTTP request to GA4 Measurement Protocol can carry up to 25 events. Each event can have up to 25 parameters. For larger volumes, send multiple batched requests.

Is there a rate limit?

Google does not publish a hard rate limit for GA4 Measurement Protocol. In practice, avoid exceeding several thousand requests per second from a single source. For high-volume use cases, batch up to 25 events per request and implement message queues for reliability.


Need help setting up analytics for your business?

Spilno Agency configures GA4, Measurement Protocol, server-side events, and ecommerce analytics for businesses across Europe. Get in touch — we will sort it out together.

Валерій Красько Spilno Agency All articles by author →
← Back to blog