# GA4 Ecommerce Purchase & Order Reconciliation (`h_murdock/ga4-order-reconciliation`) Actor

Reconcile supplied GA4 purchase exports with store orders by transaction ID. Flag duplicate IDs, missing counterparts and comparable revenue differences. Export JSON, CSV and HTML. Prepared CSV/JSON only; no Google login or automatic tracking repair. $0.25 per completed report.

- **URL**: https://apify.com/h_murdock/ga4-order-reconciliation.md
- **Developed by:** [Gilad Ronen](https://apify.com/h_murdock) (community)
- **Categories:** Marketing, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.25 / completed report

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

### Find purchase and order disagreements before your next tracking review

**GA4 Purchase & Order Evidence Report** compares the transaction IDs, currencies and comparable values in two exports you supply. Ecommerce analysts and agencies can use the source-linked report for a daily or weekly check, or after a tracking release. It flags duplicate IDs, absent counterparts in the supplied window and decimal value differences that deserve investigation.

**$0.25 per completed report, with platform usage included.** Start with the synthetic example in Apify Console; no Google login or local programming setup is needed for that example. For your real data, prepare the two exports and explicitly state their scope, timezone, completeness and value basis. This Actor does not fetch exports or automatically fix tracking.

### Try the worked example in Apify Console

1. Open this Actor in Console and inspect its prefilled synthetic input. The supplied example declares one property, one comparison window and matching value bases.
2. Check the displayed price and start the run. A completed run produces one report.
3. Open the run's Output and download `report.html` and `findings.csv`. The sample has 8 purchase rows and 5 order rows: 1 matched transaction group and 5 flagged groups. Its missing-ID and outside-window rows keep the overall outcome incomplete.
4. Inspect transaction `00002`: purchase value `15.20` versus order value `15.00`. The same-currency difference `0.20` exceeds the stated `0.01` tolerance, and source references identify the rows to investigate.

[Get the preparation templates, local assembler and synthetic worked report](https://api.apify.com/v2/key-value-stores/5RcQTbBk69ksjiTjv/records/ga4-order-reconciliation.zip?attachment=true). The kit includes a short walkthrough and a repeat-period workflow. The example is invented demonstration data, not customer activity, a measured conversion rate or proof of tracking failures.

### Prepare your real GA4 and backend exports

Use one property and one export scope per report. The kit's two CSV templates have explicit column mappings and a config file. Delete every synthetic data row before adding your own records. Keep IDs as text so leading zeros, case and whitespace survive; the Actor compares IDs exactly and does not match by customer name, amount or email.

Each source needs transaction ID, timestamp, currency and comparable value. Supply normalized JSON rows, or CSV text with an explicit mapping to distinct existing columns. Unknown fields can be null in JSON or blank in CSV; they remain unknown rather than becoming zero, USD or an invented date. Monetary values must be nonnegative decimal strings with at most 18 integer and 6 fractional digits. Numbers, exponents, grouping separators, signed values and refunds are not accepted in this purchase-value workflow. Currency codes must be uppercase three-letter strings.

Google's [report export guide](https://support.google.com/analytics/answer/9317657?hl=en) explains CSV downloads. A report export is not automatically an event-level input for this Actor. Aggregated rows, daily dates or missing per-row currency/value fields need preparation and may not support this comparison. No native GA4, BigQuery or Shopify CSV preset is promised. Unzip the kit and open `prepare.html` locally: choose your two prepared CSV files, review the configuration and download input JSON. No installation is needed. The page reads files locally and makes no network requests. An optional Node.js assembler supports scripted preparation without packages or account access.

### Declare the comparison policy explicitly

See the **Input** tab for every field. Set `propertyScope`, `exportScope` and a start-inclusive, end-exclusive `window`. Window and known row timestamps must be real RFC3339 timestamps with seconds and the same explicitly declared fixed offset, such as `Z` or `+05:30`. Normalize local dates and daylight-saving transitions yourself; no timezone is inferred.

Declare `purchaseCoverage` and `orderCoverage` separately as `complete`, `partial` or `unknown`. Use complete only when that source includes every relevant record for your scope/window. Partial or unknown coverage keeps absent counterparts unresolved. A matched supplied pair does not certify full tracking coverage.

State `purchaseValueBasis` and `orderValueBasis`, for example “merchandise net of discounts; excludes tax and shipping.” Values are compared only when these labels agree exactly and both currencies match. Prepare any tax, shipping or discount adjustments yourself. `tolerance` is an absolute allowed decimal difference for each compatible pair; equality at the tolerance boundary is accepted. There is no currency conversion or mixed-currency total.

### Download a reviewable exception report

| Output | Use |
| --- | --- |
| `report.html` | Standalone summary and source-linked evidence for a reviewer. |
| `findings.csv` | Flagged and unresolved evidence to investigate. |
| `evidence.csv` | All evidence, including accepted matches and outside-window rows. |
| `OUTPUT` | Full JSON report, scope, policy, input fingerprint and summary. |

The dataset contains one complete report with a `rows` array. Each finding includes an evidence ID, transaction ID, code/reason and positional purchase/order references, with optional source-row labels. Groups may be both flagged and unresolved, so those counts are not mutually exclusive. Repeated backend IDs, unknown times and IDs reused outside the window cannot become unique accepted matches. CSV exports neutralize spreadsheet formula prefixes; HTML escapes supplied content and uses no external resources. Import CSV identifiers as text when opening them in a spreadsheet.

### Repeat the check through the API or a saved workflow

Save the mappings and comparable-value policy after verifying your first real period. For each new day/week, replace both exports, change the window, recheck completeness and save the report with the input fingerprint and run ID. The preparation kit explains this recipe. The **API** tab provides the account-specific request example for passing the same JSON programmatically, including use through an Apify integration. This Actor does not schedule runs or retain a cross-run business history for you.

Each new run is a new billable report, even if it repeats the same period. Check an existing run's status before starting another one. Recovery within the same run preserves one report item and one report event; interrupted export writes are repaired before charging when recovery is possible. Invalid input, an insufficient report-event budget and output that exceeds the size limits are rejected before charging the report event.

### Pricing and limits

The price is **$0.25 per completed report** with platform usage included and no startup or per-dataset-item fee. Combined purchase/order rows must not exceed **5,000**, and the entire JSON input must not exceed **4 MB**. Full JSON output must be below 8 MB and each export below 9 MB. Split larger comparisons into explicit, nonoverlapping scopes/windows if you reach a limit.

### Questions, limitations and support

#### Does an absent purchase row prove GA4 is broken?

No. It describes absence in these supplied exports/window, with the declared coverage. It does not diagnose consent, adblock, attribution or event-collection failures. Google's [ecommerce validation guide](https://developers.google.com/analytics/devguides/collection/ga4/validate-ecommerce) explains how to check live collection. Events discarded or deduplicated by GA4 cannot be reconstructed by this report.

#### Can I upload a standard order CSV unchanged?

Only if its mapped fields already meet the normalized contract. Per-row identity, real timestamps, currencies and comparable values must be available. The Actor does not guess tax/shipping inclusion or supply missing fields from account credentials. Upload only the opaque IDs and data needed for this comparison; inputs and results are retained in Apify run storage.

#### What should I share when asking for help?

Use this Actor's **Issues** tab and describe the input shape and finding code with a small anonymized example. Keep the original exports locally for your own review. The report is bounded evidence for human investigation, not accounting advice or a tracking certification.

[Download the synthetic worked HTML report](https://api.apify.com/v2/key-value-stores/5RcQTbBk69ksjiTjv/records/ga4-order-reconciliation-demo.html?attachment=true). Open it locally to inspect the sample before starting a paid run.

# Actor input Schema

## `propertyScope` (type: `string`):

Opaque label identifying the single GA4 property represented by these rows. Do not include credentials. Mixing properties under one transaction namespace is unsupported.

## `exportScope` (type: `string`):

Explicit source/workflow scope, e.g. daily purchase events and paid backend orders. IDs are compared only as exact supplied strings within this declared scope.

## `purchaseValueBasis` (type: `string`):

Caller-declared exact basis for purchase values, e.g. merchandise net of discounts, excluding tax/shipping. Must exactly equal orderValueBasis for monetary comparison; no normalization is inferred.

## `orderValueBasis` (type: `string`):

Caller-declared exact basis for backend values. Use a normalized comparable value column; different labels remain unresolved.

## `tolerance` (type: `string`):

Nonnegative decimal STRING in each same-currency pair; 18 integer and at most6 fractional digits. Inclusive boundary. No percentages or currency conversion.

## `window` (type: `object`):

Required start/end RFC3339 timestamps, start inclusive and end exclusive, plus timezone as Z or fixed offset such as +05:30. Every known source timestamp must use that exact offset. Normalize DST windows before upload. Unknown timestamp is null. Real dates with seconds required.

## `purchaseCoverage` (type: `string`):

Mark complete only if this source includes every relevant record for the declared scope/window. Partial or unknown coverage prevents missing-counterpart conclusions and complete-outcome claims.

## `orderCoverage` (type: `string`):

Mark complete only if this source includes every relevant record for the declared scope/window. Partial or unknown coverage prevents missing-counterpart conclusions and complete-outcome claims.

## `purchases` (type: `object`):

Supply exactly {rows:\[...]} or {csv:"...",mapping:{transactionId:"column",timestamp:"column",currency:"column",value:"column",rowId:"optional column"}}. Each normalized row requires transactionId (string/null), timestamp (RFC3339/null), currency (uppercase3-letter string/null), value (decimal STRING/null); optional rowId string. Empty rows arrays allowed. Missing fields must explicitly be null; unknown keys rejected. CSV blank cells become null; quoted fields/BOM supported, duplicate headers and irregular rows rejected. Combined sources<=5000 rows, total JSON<=4 MB.

## `orders` (type: `object`):

Supply exactly {rows:\[...]} or {csv:"...",mapping:{transactionId:"column",timestamp:"column",currency:"column",value:"column",rowId:"optional column"}}. Each normalized row requires transactionId (string/null), timestamp (RFC3339/null), currency (uppercase3-letter string/null), value (decimal STRING/null); optional rowId string. Empty rows arrays allowed. Missing fields must explicitly be null; unknown keys rejected. CSV blank cells become null; quoted fields/BOM supported, duplicate headers and irregular rows rejected. Combined sources<=5000 rows, total JSON<=4 MB.

## Actor input object example

```json
{
  "propertyScope": "demo-property-opaque",
  "exportScope": "daily-purchase-and-paid-order-exports",
  "purchaseValueBasis": "merchandise net of discounts; excludes tax and shipping",
  "orderValueBasis": "merchandise net of discounts; excludes tax and shipping",
  "tolerance": "0.01",
  "window": {
    "start": "2026-09-30T00:00:00Z",
    "end": "2026-10-01T00:00:00Z",
    "timezone": "Z"
  },
  "purchaseCoverage": "complete",
  "orderCoverage": "complete",
  "purchases": {
    "rows": [
      {
        "rowId": "00001",
        "transactionId": "00001",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "10.000000"
      },
      {
        "rowId": "00002",
        "transactionId": "00002",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "15.20"
      },
      {
        "rowId": "event-only",
        "transactionId": "event-only",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "4.00"
      },
      {
        "rowId": "duplicate",
        "transactionId": "duplicate",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "12.00"
      },
      {
        "rowId": "duplicate",
        "transactionId": "duplicate",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "12.00"
      },
      {
        "rowId": "currency",
        "transactionId": "currency",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "EUR",
        "value": "9.00"
      },
      {
        "rowId": "missing-id-row",
        "transactionId": null,
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "8.00"
      },
      {
        "rowId": "old",
        "transactionId": "old",
        "timestamp": "2026-09-29T12:00:00Z",
        "currency": "USD",
        "value": "6.00"
      }
    ]
  },
  "orders": {
    "rows": [
      {
        "rowId": "00001",
        "transactionId": "00001",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "10.01"
      },
      {
        "rowId": "00002",
        "transactionId": "00002",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "15.00"
      },
      {
        "rowId": "order-only",
        "transactionId": "order-only",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "2.00"
      },
      {
        "rowId": "duplicate",
        "transactionId": "duplicate",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "12.00"
      },
      {
        "rowId": "currency",
        "transactionId": "currency",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "9.00"
      }
    ]
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

One item containing summary, policy, rows and limitations.

## `json` (type: `string`):

No description

## `evidence` (type: `string`):

No description

## `findings` (type: `string`):

No description

## `html` (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 = {
    "propertyScope": "demo-property-opaque",
    "exportScope": "daily-purchase-and-paid-order-exports",
    "purchaseValueBasis": "merchandise net of discounts; excludes tax and shipping",
    "orderValueBasis": "merchandise net of discounts; excludes tax and shipping",
    "tolerance": "0.01",
    "window": {
        "start": "2026-09-30T00:00:00Z",
        "end": "2026-10-01T00:00:00Z",
        "timezone": "Z"
    },
    "purchaseCoverage": "complete",
    "orderCoverage": "complete",
    "purchases": {
        "rows": [
            {
                "rowId": "00001",
                "transactionId": "00001",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "10.000000"
            },
            {
                "rowId": "00002",
                "transactionId": "00002",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "15.20"
            },
            {
                "rowId": "event-only",
                "transactionId": "event-only",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "4.00"
            },
            {
                "rowId": "duplicate",
                "transactionId": "duplicate",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "12.00"
            },
            {
                "rowId": "duplicate",
                "transactionId": "duplicate",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "12.00"
            },
            {
                "rowId": "currency",
                "transactionId": "currency",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "EUR",
                "value": "9.00"
            },
            {
                "rowId": "missing-id-row",
                "transactionId": null,
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "8.00"
            },
            {
                "rowId": "old",
                "transactionId": "old",
                "timestamp": "2026-09-29T12:00:00Z",
                "currency": "USD",
                "value": "6.00"
            }
        ]
    },
    "orders": {
        "rows": [
            {
                "rowId": "00001",
                "transactionId": "00001",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "10.01"
            },
            {
                "rowId": "00002",
                "transactionId": "00002",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "15.00"
            },
            {
                "rowId": "order-only",
                "transactionId": "order-only",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "2.00"
            },
            {
                "rowId": "duplicate",
                "transactionId": "duplicate",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "12.00"
            },
            {
                "rowId": "currency",
                "transactionId": "currency",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "9.00"
            }
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("h_murdock/ga4-order-reconciliation").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 = {
    "propertyScope": "demo-property-opaque",
    "exportScope": "daily-purchase-and-paid-order-exports",
    "purchaseValueBasis": "merchandise net of discounts; excludes tax and shipping",
    "orderValueBasis": "merchandise net of discounts; excludes tax and shipping",
    "tolerance": "0.01",
    "window": {
        "start": "2026-09-30T00:00:00Z",
        "end": "2026-10-01T00:00:00Z",
        "timezone": "Z",
    },
    "purchaseCoverage": "complete",
    "orderCoverage": "complete",
    "purchases": { "rows": [
            {
                "rowId": "00001",
                "transactionId": "00001",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "10.000000",
            },
            {
                "rowId": "00002",
                "transactionId": "00002",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "15.20",
            },
            {
                "rowId": "event-only",
                "transactionId": "event-only",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "4.00",
            },
            {
                "rowId": "duplicate",
                "transactionId": "duplicate",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "12.00",
            },
            {
                "rowId": "duplicate",
                "transactionId": "duplicate",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "12.00",
            },
            {
                "rowId": "currency",
                "transactionId": "currency",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "EUR",
                "value": "9.00",
            },
            {
                "rowId": "missing-id-row",
                "transactionId": None,
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "8.00",
            },
            {
                "rowId": "old",
                "transactionId": "old",
                "timestamp": "2026-09-29T12:00:00Z",
                "currency": "USD",
                "value": "6.00",
            },
        ] },
    "orders": { "rows": [
            {
                "rowId": "00001",
                "transactionId": "00001",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "10.01",
            },
            {
                "rowId": "00002",
                "transactionId": "00002",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "15.00",
            },
            {
                "rowId": "order-only",
                "transactionId": "order-only",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "2.00",
            },
            {
                "rowId": "duplicate",
                "transactionId": "duplicate",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "12.00",
            },
            {
                "rowId": "currency",
                "transactionId": "currency",
                "timestamp": "2026-09-30T12:00:00Z",
                "currency": "USD",
                "value": "9.00",
            },
        ] },
}

# Run the Actor and wait for it to finish
run = client.actor("h_murdock/ga4-order-reconciliation").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 '{
  "propertyScope": "demo-property-opaque",
  "exportScope": "daily-purchase-and-paid-order-exports",
  "purchaseValueBasis": "merchandise net of discounts; excludes tax and shipping",
  "orderValueBasis": "merchandise net of discounts; excludes tax and shipping",
  "tolerance": "0.01",
  "window": {
    "start": "2026-09-30T00:00:00Z",
    "end": "2026-10-01T00:00:00Z",
    "timezone": "Z"
  },
  "purchaseCoverage": "complete",
  "orderCoverage": "complete",
  "purchases": {
    "rows": [
      {
        "rowId": "00001",
        "transactionId": "00001",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "10.000000"
      },
      {
        "rowId": "00002",
        "transactionId": "00002",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "15.20"
      },
      {
        "rowId": "event-only",
        "transactionId": "event-only",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "4.00"
      },
      {
        "rowId": "duplicate",
        "transactionId": "duplicate",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "12.00"
      },
      {
        "rowId": "duplicate",
        "transactionId": "duplicate",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "12.00"
      },
      {
        "rowId": "currency",
        "transactionId": "currency",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "EUR",
        "value": "9.00"
      },
      {
        "rowId": "missing-id-row",
        "transactionId": null,
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "8.00"
      },
      {
        "rowId": "old",
        "transactionId": "old",
        "timestamp": "2026-09-29T12:00:00Z",
        "currency": "USD",
        "value": "6.00"
      }
    ]
  },
  "orders": {
    "rows": [
      {
        "rowId": "00001",
        "transactionId": "00001",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "10.01"
      },
      {
        "rowId": "00002",
        "transactionId": "00002",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "15.00"
      },
      {
        "rowId": "order-only",
        "transactionId": "order-only",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "2.00"
      },
      {
        "rowId": "duplicate",
        "transactionId": "duplicate",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "12.00"
      },
      {
        "rowId": "currency",
        "transactionId": "currency",
        "timestamp": "2026-09-30T12:00:00Z",
        "currency": "USD",
        "value": "9.00"
      }
    ]
  }
}' |
apify call h_murdock/ga4-order-reconciliation --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,h_murdock/ga4-order-reconciliation"
        }
    }
}
```

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/2vhgJuqiZX6kqyxWB/builds/RW5jgYV2i3d6ZW57N/openapi.json
