Complete guide to GA4 Measurement Protocol for server-side event tracking including API authentication, request format, validation, and implementation examples. Use when implementing server-side tracking, sending events from backend, working with Measurement Protocol API, integrating CRM with GA4, or tracking offline conversions. Covers API secrets, debug endpoint, Python/Node.js/PHP examples, and rate limits.
/plugin marketplace add henkisdabro/wookstar-claude-code-plugins/plugin install ga-suite@wookstar-claude-code-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
assets/measurement-protocol-example.pyreferences/complete-api-guide.mdThe GA4 Measurement Protocol allows server-side event collection, enabling data transmission to GA4 from any HTTP-capable environment including backend servers, mobile apps, kiosks, and IoT devices.
Invoke this skill when:
Production Endpoint:
POST https://www.google-analytics.com/mp/collect
Debug Endpoint (Validation):
POST https://www.google-analytics.com/debug/mp/collect
Key Difference: Debug endpoint returns validation messages without storing data.
Two Credentials Required:
Measurement ID (format: G-XXXXXXXXXX)
API Secret
Generating API Secret:
URL Format:
https://www.google-analytics.com/mp/collect?measurement_id={MEASUREMENT_ID}&api_secret={API_SECRET}
Headers:
Content-Type: application/json
Body (JSON):
{
"client_id": "unique_client_identifier",
"user_id": "optional_user_id",
"timestamp_micros": "1234567890123456",
"user_properties": {
"property_name": {
"value": "property_value"
}
},
"consent": {
"ad_storage": "granted",
"analytics_storage": "granted"
},
"events": [
{
"name": "event_name",
"params": {
"parameter_name": "parameter_value",
"value": 123.45,
"currency": "USD"
}
}
]
}
| Parameter | Type | Description |
|---|---|---|
session_id | string | Session identifier |
engagement_time_msec | integer | Engagement time in milliseconds |
page_location | string | Full URL |
page_title | string | Page title |
value | number | Monetary value |
currency | string | ISO 4217 currency code (USD, EUR) |
transaction_id | string | Unique transaction ID |
items | array | E-commerce items array |
Using Requests Library:
import requests
import json
import uuid
MEASUREMENT_ID = "G-XXXXXXXXXX"
API_SECRET = "your_api_secret"
ENDPOINT = f"https://www.google-analytics.com/mp/collect?measurement_id={MEASUREMENT_ID}&api_secret={API_SECRET}"
def send_event(event_name, params=None):
payload = {
"client_id": str(uuid.uuid4()),
"events": [{
"name": event_name,
"params": params or {}
}]
}
response = requests.post(
ENDPOINT,
headers={"Content-Type": "application/json"},
data=json.dumps(payload)
)
return response.status_code == 204
# Send page view
send_event("page_view", {
"page_location": "https://example.com/page",
"page_title": "Example Page"
})
# Send purchase
send_event("purchase", {
"transaction_id": "T_12345",
"value": 99.99,
"currency": "USD",
"items": [{
"item_id": "SKU_123",
"item_name": "Product Name",
"price": 99.99,
"quantity": 1
}]
})
Using ga4mp Library:
# Install: pip install ga4mp
from ga4mp import GtagMP
ga = GtagMP(
measurement_id="G-XXXXXXXXXX",
api_secret="your_api_secret",
client_id="unique_client_id"
)
# Send event
ga.send_event(
event_name="purchase",
event_parameters={
"transaction_id": "T_12345",
"value": 99.99,
"currency": "USD",
"items": [{
"item_id": "SKU_123",
"item_name": "Product Name",
"price": 99.99,
"quantity": 1
}]
}
)
const axios = require('axios');
const { v4: uuidv4 } = require('uuid');
const MEASUREMENT_ID = 'G-XXXXXXXXXX';
const API_SECRET = 'your_api_secret';
const ENDPOINT = `https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`;
async function sendEvent(eventName, params = {}) {
const payload = {
client_id: uuidv4(),
events: [{
name: eventName,
params: params
}]
};
try {
const response = await axios.post(ENDPOINT, payload, {
headers: { 'Content-Type': 'application/json' }
});
return response.status === 204;
} catch (error) {
console.error('Error sending event:', error);
return false;
}
}
// Send purchase event
sendEvent('purchase', {
transaction_id: 'T_12345',
value: 99.99,
currency: 'USD',
items: [{
item_id: 'SKU_123',
item_name: 'Product',
price: 99.99,
quantity: 1
}]
});
<?php
// Using php-GA4-Measurement-Protocol library
// Install: composer require br33f/php-ga4-measurement-protocol
use Br33f\Ga4\MeasurementProtocol\Dto\Event\PurchaseEvent;
use Br33f\Ga4\MeasurementProtocol\Dto\Request\MeasurementRequest;
use Br33f\Ga4\MeasurementProtocol\Service;
$measurementId = 'G-XXXXXXXXXX';
$apiSecret = 'your_api_secret';
$service = new Service($apiSecret, $measurementId);
$event = new PurchaseEvent();
$event->setTransactionId('T_12345')
->setValue(99.99)
->setCurrency('USD');
$request = new MeasurementRequest();
$request->setClientId('unique_client_id')
->addEvent($event);
$service->send($request);
?>
Send to Debug Endpoint:
curl -X POST "https://www.google-analytics.com/debug/mp/collect?measurement_id=G-XXXXXXXXXX&api_secret=YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"client_id": "test_client",
"events": [{
"name": "test_event",
"params": {
"test_param": "test_value"
}
}]
}'
Response Format:
{
"validationMessages": [
{
"fieldPath": "events[0].name",
"description": "Event name must be 40 characters or fewer",
"validationCode": "NAME_INVALID"
}
]
}
Empty Response = Valid:
| Code | Description | Fix |
|---|---|---|
NAME_INVALID | Invalid event/parameter name | Use lowercase, underscores, ≤40 chars |
NAME_RESERVED | Reserved name used | Check GA4 reserved names list |
VALUE_INVALID | Invalid parameter value | Check data type, format |
VALUE_REQUIRED | Required value missing | Add required parameter |
VALUE_OUT_OF_BOUNDS | Value exceeds limits | Check numeric ranges |
EXCEEDED_MAX_ENTITIES | Too many events | Max 25 events per request |
Always Validate First:
Use Consistent client_id:
Include session_id:
Batch Events:
Handle Errors Gracefully:
Set Proper Timestamps:
timestamp_micros for historical datatimestamp_ms * 1000Respect Consent:
Generate API Secret: Admin → Data Streams → Measurement Protocol API secrets → Create
Endpoint:
/mp/collect/debug/mp/collectRequired Fields:
Max Limits:
Validation:
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.