pixellint

vendor/google-analytics · vendor documented

GA4 Measurement Protocol wants microseconds

The collect endpoint returns 204. The event does not show up, or it shows up with no revenue, or it shows up attached to nobody. A lot of that is the timestamp.

timestamp_micros is a Unix timestamp in microseconds, sixteen digits. Date.now() is milliseconds. Multiply by 1000. Meta's Conversions API is the inverse clock: seconds, so the same Date.now() is too large rather than too small.

timestamp_micros is 16 digits

A 13-digit value is milliseconds. A 10-digit value is seconds. Multiply a millisecond timestamp by 1000, or a second timestamp by 1_000_000.

Rule: vendor.google-analytics.body.timestamp_micros.invalid

purchase needs ecommerce fields

Google's recommended purchase event needs currency, value, transaction_id, and items. Value without currency is dropped. refund, add_to_cart, and begin_checkout have their own required sets.

Rule: vendor.google-analytics.body.purchase_requires_ecommerce_fields

Events with no client_id never join a user

client_id is recommended rather than required. The collect endpoint will take the hit. Nothing joins it to a browser or a session. Warnings do not fail pixellint validate; this one should fail your run.

Rule: vendor.google-analytics.body.client_id.missing

What this pack matches

Hosts
google-analytics.com
Paths
/mp/collect, /debug/mp/collect
Vendor docs
developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events

Rules

Codes are stable. A finding in CI, MCP, or the playground lands on the same id.

Field Required What it checks Rule ids Source
api_secret required It authenticates the request and is created in the GA4 admin UI. Fix: Create a Measurement Protocol API secret for the stream and send it as `api_secret`. vendor.google-analytics.param.api_secret.missing
vendor.google-analytics.param.api_secret.empty
docs
measurement_id optional Web stream measurement IDs start with `G-`. Fix: Use the web stream measurement ID, or send `firebase_app_id` for an app stream. vendor.google-analytics.param.measurement_id.empty
vendor.google-analytics.param.measurement_id.invalid
docs
firebase_app_id optional It identifies an app stream and replaces `measurement_id`. vendor.google-analytics.param.firebase_app_id.empty docs
stream.identifier_missing required The request identifies no GA4 stream. Web streams send `measurement_id` and app streams send `firebase_app_id`. Fix: Add `measurement_id` for a web stream or `firebase_app_id` for an app stream. vendor.google-analytics.stream.identifier_missing docs
stream.identifier_ambiguous required The request sends both `measurement_id` and `firebase_app_id`. One request targets one stream type. Fix: Keep the identifier that matches the stream this event belongs to and drop the other. vendor.google-analytics.stream.identifier_ambiguous docs
client_id recommended It identifies the browser or device the event belongs to, and events without it are not joined to a user. Fix: Send the `_ga` cookie's client id, or a stable id of your own. vendor.google-analytics.body.client_id.missing
vendor.google-analytics.body.client_id.empty
docs
events optional Google documents the events array as the one required field of the request body. An empty array sends no events at all. Fix: Send an `events` array holding at least one event. docs
timestamp_micros optional Google documents this as a Unix timestamp in microseconds, not milliseconds. A 13-digit value is milliseconds and a 10-digit value is seconds. Fix: Multiply a millisecond timestamp by 1000, or a second timestamp by 1000000. vendor.google-analytics.body.timestamp_micros.empty
vendor.google-analytics.body.timestamp_micros.invalid
docs
non_personalized_ads deprecated Google marks it deprecated in the Measurement Protocol reference. Fix: Use the `consent` object instead. vendor.google-analytics.body.non_personalized_ads.deprecated docs
name required Google documents event names as 40 characters or fewer. Fix: Use a short name of letters, digits, and underscores, starting with a letter. vendor.google-analytics.body.name.missing
vendor.google-analytics.body.name.empty
vendor.google-analytics.body.name.invalid
docs
params.currency optional It is the ISO 4217 currency code, and Google requires it whenever `value` is set. Fix: Use the three-letter code, such as `USD`. vendor.google-analytics.body.params.currency.empty
vendor.google-analytics.body.params.currency.invalid
docs
params.value optional It is the monetary value of the event. Fix: Set it to the sum of price times quantity across the items, excluding shipping and tax. docs
params.transaction_id optional It identifies the transaction, and Google requires it for purchase and refund events. docs
params.items optional It lists the items the event covers. docs
body.value_requires_currency required The event carries a `value` with no `currency`. Google documents currency as required whenever value is set, and drops the revenue otherwise. Fix: Add `currency` as an ISO 4217 code alongside the value. vendor.google-analytics.body.value_requires_currency docs
body.purchase_requires_ecommerce_fields required A `purchase` event is missing fields Google documents as required for it, so it will not report revenue correctly. Fix: Add the required ecommerce parameters to the event. vendor.google-analytics.body.purchase_requires_ecommerce_fields docs
body.refund_requires_ecommerce_fields required A `refund` event is missing fields Google documents as required for it, so it will not report revenue correctly. Fix: Add the required ecommerce parameters to the event. vendor.google-analytics.body.refund_requires_ecommerce_fields docs
body.cart_requires_ecommerce_fields required Google documents `currency`, `value`, and `items` as required for this ecommerce event. Fix: Add `currency`, `value`, and the `items` array to the event. vendor.google-analytics.body.cart_requires_ecommerce_fields docs

Validate a payload

pixellint validate json @payload.json --rulepack vendor/google-analytics

Or paste it into the playground. Same engine, in the browser, nothing sent anywhere.

cargo install pixellint · npm install pixellint