# GA4 Ecommerce Event Payload Auditor (`danielmichalek/ga4-ecommerce-event-auditor`) Actor

Audit supplied ecommerce events before a tracking release. Find missing identifiers, currency gaps, inconsistent values and repeated purchase IDs. Ready to check your event samples?

- **URL**: https://apify.com/danielmichalek/ga4-ecommerce-event-auditor.md
- **Developed by:** [Daniel Michałek](https://apify.com/danielmichalek) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$30.00 / 1,000 completed ecommerce payload audits

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## GA4 Ecommerce Event Payload Auditor

### What it does

Audit supplied ecommerce event payloads before a tracking release or during instrumentation QA. Find missing item identity, transaction identifiers and currency, wrong numeric types, inconsistent reported values, and repeated purchase identifiers. The report returns exact source field paths and review actions without contacting Google Analytics, Tag Manager or a customer website.

### Input

Supply1to500 JSON records in events and explicitly choose format. ga4-events expects each row to have name and params, matching the event objects inside a Measurement Protocol request or an exported gtag call. data-layer expects event and ecommerce. Context pushes without event, including ecommerce:null clears, are informational. The tool audits each resolved event independently and does not simulate dataLayer merging or replay browser state.

Supported event names: view_item, add_to_cart, remove_from_cart, view_cart, begin_checkout, add_shipping_info, add_payment_info, purchase and refund. Other syntactically valid events are marked OUT_OF_SCOPE. Missing or malformed supported payload fields are findings, rather than reasons to silently drop a row. Invalid batch shape and tool limits fail before any report billing emission.

The limits are500 records,5000 aggregate item entries,3MB total input and7MB serialized report. More than200items within one event is a platform-limit finding, while all supplied items inside the tool batch cap are still inspected. maxEvents lowers the batch cap. amountTolerance is an explicit absolute value from0to1, default0.01; no currency-dependent precision is guessed. Arithmetic rounds amounts and item products to six decimal places, with BigInt accumulation to avoid total overflow; this is an audit convention, not a financial ledger.

### Output

One dataset report includes findings, exact JSON source paths, counts, and record-level arithmetic status. AUDIT is complete JSON, FINDINGS_CSV is a downloadable correction checklist, and REPORT is Markdown. recordCount includes context pushes; eventCount excludes dataLayer pushes without event. ERROR and REVIEW statuses concern this documented subset, while CHECKED never means Google acceptance.

The reconciliation basis is supplied item price times quantity, excluding separately supplied tax and shipping. Missing quantity defaults to1; explicit zero is flagged for review and is not replaced. Positive values below audit precision are excluded with an explicit precision warning. Fractional numeric quantities are supported. Item price is already discounted, so discount is not subtracted again. Missing price leaves the total incomplete. A zero value is not treated as missing. Numeric strings are identified as type problems.

Repeated purchase identifiers with equal supplied totals produce context notes, because repeats can be retries and GA4 uses transaction identifiers for deduplication. Identity uses the exact supplied nonempty string; surrounding whitespace is flagged separately and never trimmed or merged. Different totals or currencies produce review warnings for all affected rows. Item order alone does not create a conflict. A refund may omit items for a full-transaction refund; a purchase absent from this sample produces an informational note, not a claim that the refund is invalid.

### Pricing and cost control

USD0.03 per completed ecommerce-audit-report, covering the declared batch limits. Check the current Store price before running. The cost estimate in PRICING is a planning assumption. No paid API, proxy, model inference, tracking hits or ad spend is required. The report event is emitted only after exports are saved. Structural failures and failed storage do not emit that report event.

### Limitations and fair use

This is offline payload QA, not an official Google validation service or an audit of actual revenue, consent, attribution, delivery, deduplication behavior or account configuration. It implements the documented field subset and syntactic uppercase currency codes, not a complete ISO currency database. Other recommended or custom parameters are outside scope. No campaigns, budgets or tags are changed.

Raw payloads, order IDs and unrelated customer fields are not copied into reports. Transaction identifiers are represented by SHA256 hashes, which reduce direct exposure but are not anonymization. Input is still stored under Apify run-retention settings; use authorized, minimized or synthetic samples and omit secrets or personal customer records.

### Example

examples/input.json includes a valid purchase, a purchase value including tax and shipping, an event missing currency and a refund whose purchase is outside the sample. It returns one error, one warning and one context note. examples/input-data-layer.json shows a legitimate clear push and resolved purchase. Run npm ci --ignore-scripts, npm test, then the existing factory release.mjs --local-run --write-example. Canonical source stays here; Apifi boty is only a generated view.

### References

Official Google event reference: https://developers.google.com/analytics/devguides/collection/ga4/reference/events . Ecommerce implementation guide: https://developers.google.com/analytics/devguides/collection/ga4/ecommerce . Current official text remains authoritative and provider requirements may change.

# Actor input Schema

## `events` (type: `array`):

1to500 JSON objects. ga4-events uses name and params; data-layer uses event and ecommerce. Supply resolved payloads, not private customer exports. Maximum5000 item entries and3MB total input. Prefilled values are synthetic demonstration data; replace them with your own samples.

## `format` (type: `string`):

Explicit shape; no automatic guessing or state replay.

## `amountTolerance` (type: `number`):

Absolute tolerance in supplied currency units. Arithmetic rounds to six decimal places; currency precision is not inferred.

## `maxEvents` (type: `integer`):

Hard batch cap; overflow is rejected without truncation.

## `maxItems` (type: `integer`):

One complete audit report, emitted after exports are stored.

## Actor input object example

```json
{
  "events": [
    {
      "name": "purchase",
      "params": {
        "transaction_id": "SYNTHETIC-001",
        "currency": "EUR",
        "value": 25,
        "tax": 5,
        "shipping": 2,
        "items": [
          {
            "item_id": "SKU-01",
            "price": 10,
            "quantity": 2
          },
          {
            "item_name": "Blue mug",
            "price": 5
          }
        ]
      }
    },
    {
      "name": "purchase",
      "params": {
        "transaction_id": "SYNTHETIC-002",
        "currency": "EUR",
        "value": 32,
        "tax": 5,
        "shipping": 2,
        "items": [
          {
            "item_id": "SKU-01",
            "price": 10,
            "quantity": 2
          },
          {
            "item_name": "Blue mug",
            "price": 5
          }
        ]
      }
    },
    {
      "name": "add_to_cart",
      "params": {
        "value": 1,
        "items": [
          {
            "item_id": "SKU-01",
            "price": 1,
            "quantity": 1
          }
        ]
      }
    },
    {
      "name": "refund",
      "params": {
        "transaction_id": "OUTSIDE-THIS-SYNTHETIC-SAMPLE",
        "value": 5,
        "currency": "EUR"
      }
    }
  ],
  "format": "ga4-events",
  "amountTolerance": 0.01,
  "maxEvents": 500,
  "maxItems": 1
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `report` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "events": [
        {
            "name": "purchase",
            "params": {
                "transaction_id": "SYNTHETIC-001",
                "currency": "EUR",
                "value": 25,
                "tax": 5,
                "shipping": 2,
                "items": [
                    {
                        "item_id": "SKU-01",
                        "price": 10,
                        "quantity": 2
                    },
                    {
                        "item_name": "Blue mug",
                        "price": 5
                    }
                ]
            }
        },
        {
            "name": "purchase",
            "params": {
                "transaction_id": "SYNTHETIC-002",
                "currency": "EUR",
                "value": 32,
                "tax": 5,
                "shipping": 2,
                "items": [
                    {
                        "item_id": "SKU-01",
                        "price": 10,
                        "quantity": 2
                    },
                    {
                        "item_name": "Blue mug",
                        "price": 5
                    }
                ]
            }
        },
        {
            "name": "add_to_cart",
            "params": {
                "value": 1,
                "items": [
                    {
                        "item_id": "SKU-01",
                        "price": 1,
                        "quantity": 1
                    }
                ]
            }
        },
        {
            "name": "refund",
            "params": {
                "transaction_id": "OUTSIDE-THIS-SYNTHETIC-SAMPLE",
                "value": 5,
                "currency": "EUR"
            }
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("danielmichalek/ga4-ecommerce-event-auditor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "events": [
        {
            "name": "purchase",
            "params": {
                "transaction_id": "SYNTHETIC-001",
                "currency": "EUR",
                "value": 25,
                "tax": 5,
                "shipping": 2,
                "items": [
                    {
                        "item_id": "SKU-01",
                        "price": 10,
                        "quantity": 2,
                    },
                    {
                        "item_name": "Blue mug",
                        "price": 5,
                    },
                ],
            },
        },
        {
            "name": "purchase",
            "params": {
                "transaction_id": "SYNTHETIC-002",
                "currency": "EUR",
                "value": 32,
                "tax": 5,
                "shipping": 2,
                "items": [
                    {
                        "item_id": "SKU-01",
                        "price": 10,
                        "quantity": 2,
                    },
                    {
                        "item_name": "Blue mug",
                        "price": 5,
                    },
                ],
            },
        },
        {
            "name": "add_to_cart",
            "params": {
                "value": 1,
                "items": [{
                        "item_id": "SKU-01",
                        "price": 1,
                        "quantity": 1,
                    }],
            },
        },
        {
            "name": "refund",
            "params": {
                "transaction_id": "OUTSIDE-THIS-SYNTHETIC-SAMPLE",
                "value": 5,
                "currency": "EUR",
            },
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("danielmichalek/ga4-ecommerce-event-auditor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "events": [
    {
      "name": "purchase",
      "params": {
        "transaction_id": "SYNTHETIC-001",
        "currency": "EUR",
        "value": 25,
        "tax": 5,
        "shipping": 2,
        "items": [
          {
            "item_id": "SKU-01",
            "price": 10,
            "quantity": 2
          },
          {
            "item_name": "Blue mug",
            "price": 5
          }
        ]
      }
    },
    {
      "name": "purchase",
      "params": {
        "transaction_id": "SYNTHETIC-002",
        "currency": "EUR",
        "value": 32,
        "tax": 5,
        "shipping": 2,
        "items": [
          {
            "item_id": "SKU-01",
            "price": 10,
            "quantity": 2
          },
          {
            "item_name": "Blue mug",
            "price": 5
          }
        ]
      }
    },
    {
      "name": "add_to_cart",
      "params": {
        "value": 1,
        "items": [
          {
            "item_id": "SKU-01",
            "price": 1,
            "quantity": 1
          }
        ]
      }
    },
    {
      "name": "refund",
      "params": {
        "transaction_id": "OUTSIDE-THIS-SYNTHETIC-SAMPLE",
        "value": 5,
        "currency": "EUR"
      }
    }
  ]
}' |
apify call danielmichalek/ga4-ecommerce-event-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,danielmichalek/ga4-ecommerce-event-auditor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/81tFrlaX3q1lfHaZA/builds/dFEA2hC9VmhQJCV1I/openapi.json
