# Campaign Spend vs Daily Plan Evidence Report (`h_murdock/campaign-spend-plan-evidence`) Actor

Compare daily cross-platform media plans with supplied spend exports. Trace cumulative and daily variance, missing-day coverage, currency/cost-basis scopes and remaining declared plan arithmetic. Mapped CSV/JSON; downloadable evidence; no account access.

- **URL**: https://apify.com/h_murdock/campaign-spend-plan-evidence.md
- **Developed by:** [Gilad Ronen](https://apify.com/h_murdock) (community)
- **Categories:** Marketing, Automation
- **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

## Campaign Spend vs Daily Plan Evidence Report

Compare your supplied daily media plan with authorized spend exports from several advertising platforms, without connecting an ad account. This report is for analysts and agencies who already keep campaign plans in spreadsheets and need a repeatable handoff showing which comparisons are supported by the export, which days remain unknown, and where arithmetic differs from the declared plan.

### What you receive

Each completed run produces one complete report dataset item. Its campaign view shows planned and actual amounts through the declared cutoff, cumulative variance, the full declared plan, and the remaining declared plan amount when the evidence is complete. Its daily evidence view keeps the plan row, observed spend, coverage declaration, identifiers and source references together. Download full JSON, daily evidence CSV, findings CSV and a standalone HTML report with campaign summaries and daily detail.

A positive variance means actual minus the caller's plan is positive. It does not establish an overcharge, a platform spending-limit violation, or poor campaign performance. Google and other platforms have their own budget and billing rules; this tool compares your supplied allocations rather than enforcing those rules.

### Input and workflow

1. Choose a `snapshotId` and `planVersion`. Declare `windowStart`, `windowEnd` and `asOfDate` as real `YYYY-MM-DD` calendar dates. The cutoff includes the entire as-of date. Normalize all exports to your chosen reporting timezone before upload; the Actor does not reconcile platform timezones.
2. Supply `plans`, `actuals` and `coverage` arrays, including an explicit empty array for an empty table. Alternatively supply the corresponding CSV and remove that array. CSV supports a UTF-8 BOM, quoted cells and a complete canonical-field to header mapping. Duplicate or unmapped headers, ragged rows and unsupported dates are rejected.
3. Each plan and actual row needs `recordId`, `sourceId`, `campaignId`, `date`, `currency`, `costBasis` and `amount`. Amounts must be decimal **strings**, such as `"12.3456"`, with at most twelve integer and six fractional digits. A source/campaign scope has exactly one currency and one literal cost basis, for example `billed` or `served`. The Actor never converts currencies or combines different cost bases.
4. Each coverage row needs `recordId`, `sourceId`, `campaignId`, `currency`, `costBasis`, `startDate`, `endDate` and `completeness` (`complete`, `incomplete` or `unknown`). Ranges include both boundary dates and cannot overlap within the same source/campaign scope.
5. Set `missingPlannedDayPolicy` to `zero` only when an omitted plan allocation means zero in your declared plan. Otherwise use `unknown`. Review the report before using it in a media-plan handoff.

Full daily actual totals require caller-declared **complete export coverage**, even when an actual row is present. An observation under incomplete, unknown or absent complete coverage remains a known lower-bound amount; its complete actual total and variance stay unknown. An absent actual row becomes zero only inside complete coverage for that exact scope. Your coverage declaration is not independently verified. Duplicate source/campaign/date rows are rejected, including identical repeats, because accidental duplication and distinct spend components cannot be distinguished safely. Aggregate legitimate components in your export before upload and preserve the correct cost basis.

### Interpreting remaining amounts

The report uses exact fixed-point arithmetic, not floating-point money sums. When full-plan and through-cutoff actual evidence are complete, remaining declared plan equals full supplied plan minus actual through cutoff. A negative amount is retained. The optional remaining-per-positive-planned-day value is an exact numerator and denominator, counting future dates with explicit positive allocations. It is an arithmetic expression, not a forecast, budget recommendation or automatically rounded daily setting. If there are no such future dates, the expression is null.

Future actual observations and out-of-window rows remain traceable in the report but do not enter comparison totals. Unknowns are null, distinct from zero. Different source/campaign scopes remain separate; there is no misleading monetary total across currencies or cost bases.

### Limits, privacy and pricing

Input is limited to 4 MB and 5,000 combined rows. A window contains at most 366 dates and expansion at most 10,000 daily evidence rows. Large export artifacts are rejected before charging: complete JSON must stay below 8 MB and each download below 9 MB. Shorten the window or split campaign scopes when limits are reached.

Use opaque identifiers and authorized exports only. This Actor makes no external network requests, reads no account credentials, changes no campaigns and calls no paid models. Apify retains cloud input and report artifacts according to its platform settings. HTML escapes supplied content; CSV neutralizes spreadsheet formula prefixes.

Pricing is **$0.25 per completed report**, with platform usage included. Invalid input or insufficient report budget is not charged a report event. A fresh run is a new billable report. Restarting the same run recovers durable exports and preserves one report item and one event; interrupted exports may temporarily be partial until that run resumes. This evidence report does not diagnose ROAS, attribution or campaign performance and does not replace native platform reports.

# Actor input Schema

## `snapshotId` (type: `string`):

Opaque literal identifier, no surrounding whitespace or controls; leading zeros retained.

## `planVersion` (type: `string`):

Opaque literal identifier, no surrounding whitespace or controls; leading zeros retained.

## `windowStart` (type: `string`):

Real ISO calendar date YYYY-MM-DD. Caller must normalize reporting timezone. Window1–366dates; asOfDate inside window includes the whole date. No ambiguous slash dates.

## `windowEnd` (type: `string`):

Real ISO calendar date YYYY-MM-DD. Caller must normalize reporting timezone. Window1–366dates; asOfDate inside window includes the whole date. No ambiguous slash dates.

## `asOfDate` (type: `string`):

Real ISO calendar date YYYY-MM-DD. Caller must normalize reporting timezone. Window1–366dates; asOfDate inside window includes the whole date. No ambiguous slash dates.

## `missingPlannedDayPolicy` (type: `string`):

Explicitly declare whether omitted daily plan allocations mean zero. unknown prevents complete plan totals when a day is omitted. This is caller plan policy, not a platform budget rule.

## `plans` (type: `array`):

Rows: recordId, sourceId, campaignId, date, currency, costBasis, amount. Amount is a nonnegative decimal STRING, max12integer/6fractionaldigits. One row per source/campaign/date, one currency and cost basis per source/campaign; duplicates or mixing rejected. Arrays OR CSV, never both.5,000combinedrows/4MB;10,000expanded daily evidence rows.

## `plansCsv` (type: `string`):

Alternative to array: remove corresponding array before supplying nonempty CSV. Canonical headers or explicit mapping; BOM/quoted cells accepted. Unknown/duplicate headers and ragged rows rejected. Dates/money must be canonical; no URL fetch.

## `plansColumns` (type: `object`):

Optional complete canonical-key→CSV-header mapping: recordId, sourceId, campaignId, date, currency, costBasis, amount. Distinct headers only. Custom mapping requires CSV; omit for canonical headers.

## `actuals` (type: `array`):

Rows: recordId, sourceId, campaignId, date, currency, costBasis, amount. Amount is a nonnegative decimal STRING, max12integer/6fractionaldigits. One row per source/campaign/date, one currency and cost basis per source/campaign; duplicates or mixing rejected. Arrays OR CSV, never both.5,000combinedrows/4MB;10,000expanded daily evidence rows.

## `actualsCsv` (type: `string`):

Alternative to array: remove corresponding array before supplying nonempty CSV. Canonical headers or explicit mapping; BOM/quoted cells accepted. Unknown/duplicate headers and ragged rows rejected. Dates/money must be canonical; no URL fetch.

## `actualsColumns` (type: `object`):

Optional complete canonical-key→CSV-header mapping: recordId, sourceId, campaignId, date, currency, costBasis, amount. Distinct headers only. Custom mapping requires CSV; omit for canonical headers.

## `coverage` (type: `array`):

Rows: recordId, sourceId, campaignId, currency, costBasis, startDate, endDate, completeness complete/incomplete/unknown. Ranges inclusive; no overlap per scope. Only complete caller-declared actual export coverage establishes a full daily actual total, including observed rows. Observed amounts without complete coverage are retained as lower bounds; missing actual is zero only inside complete coverage. Arrays OR CSV;5,000combinedrows/4MB.

## `coverageCsv` (type: `string`):

Alternative to array: remove corresponding array before supplying nonempty CSV. Canonical headers or explicit mapping; BOM/quoted cells accepted. Unknown/duplicate headers and ragged rows rejected. Dates/money must be canonical; no URL fetch.

## `coverageColumns` (type: `object`):

Optional complete canonical-key→CSV-header mapping: recordId, sourceId, campaignId, currency, costBasis, startDate, endDate, completeness. Distinct headers only. Custom mapping requires CSV; omit for canonical headers.

## Actor input object example

```json
{
  "snapshotId": "demo-2026-10-02",
  "planVersion": "media-plan-v3",
  "windowStart": "2026-10-01",
  "windowEnd": "2026-10-03",
  "asOfDate": "2026-10-02",
  "missingPlannedDayPolicy": "zero",
  "plans": [
    {
      "recordId": "pgoogle1",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-01",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.1"
    },
    {
      "recordId": "pgoogle2",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-02",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.2"
    },
    {
      "recordId": "pgoogle3",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-03",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.3"
    },
    {
      "recordId": "pmeta1",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-10-01",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "10"
    },
    {
      "recordId": "pmeta2",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-10-02",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "10"
    },
    {
      "recordId": "pmeta3",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-10-03",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "15"
    }
  ],
  "plansColumns": {
    "recordId": "recordId",
    "sourceId": "sourceId",
    "campaignId": "campaignId",
    "date": "date",
    "currency": "currency",
    "costBasis": "costBasis",
    "amount": "amount"
  },
  "actuals": [
    {
      "recordId": "a0",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-01",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.1"
    },
    {
      "recordId": "a1",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-02",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.25"
    },
    {
      "recordId": "a2",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-03",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.15"
    },
    {
      "recordId": "a3",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-10-01",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "8"
    },
    {
      "recordId": "a4",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-09-30",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "99"
    }
  ],
  "actualsColumns": {
    "recordId": "recordId",
    "sourceId": "sourceId",
    "campaignId": "campaignId",
    "date": "date",
    "currency": "currency",
    "costBasis": "costBasis",
    "amount": "amount"
  },
  "coverage": [
    {
      "recordId": "cgoogle",
      "sourceId": "google",
      "campaignId": "0001",
      "currency": "USD",
      "costBasis": "billed",
      "startDate": "2026-10-01",
      "endDate": "2026-10-02",
      "completeness": "complete"
    },
    {
      "recordId": "cmeta",
      "sourceId": "meta",
      "campaignId": "0001",
      "currency": "EUR",
      "costBasis": "served",
      "startDate": "2026-10-01",
      "endDate": "2026-10-02",
      "completeness": "unknown"
    }
  ],
  "coverageColumns": {
    "recordId": "recordId",
    "sourceId": "sourceId",
    "campaignId": "campaignId",
    "currency": "currency",
    "costBasis": "costBasis",
    "startDate": "startDate",
    "endDate": "endDate",
    "completeness": "completeness"
  }
}
```

# Actor output Schema

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

One report: campaigns, daily evidence rows, findings, excluded inputs and scope notes.

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

No description

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

No description

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

No description

## `html` (type: `string`):

Escaped static report, downloaded for local viewing.

# 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 = {
    "snapshotId": "demo-2026-10-02",
    "planVersion": "media-plan-v3",
    "windowStart": "2026-10-01",
    "windowEnd": "2026-10-03",
    "asOfDate": "2026-10-02",
    "missingPlannedDayPolicy": "zero",
    "plans": [
        {
            "recordId": "pgoogle1",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-01",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.1"
        },
        {
            "recordId": "pgoogle2",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-02",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.2"
        },
        {
            "recordId": "pgoogle3",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-03",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.3"
        },
        {
            "recordId": "pmeta1",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-10-01",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "10"
        },
        {
            "recordId": "pmeta2",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-10-02",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "10"
        },
        {
            "recordId": "pmeta3",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-10-03",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "15"
        }
    ],
    "plansCsv": "",
    "plansColumns": {
        "recordId": "recordId",
        "sourceId": "sourceId",
        "campaignId": "campaignId",
        "date": "date",
        "currency": "currency",
        "costBasis": "costBasis",
        "amount": "amount"
    },
    "actuals": [
        {
            "recordId": "a0",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-01",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.1"
        },
        {
            "recordId": "a1",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-02",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.25"
        },
        {
            "recordId": "a2",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-03",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.15"
        },
        {
            "recordId": "a3",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-10-01",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "8"
        },
        {
            "recordId": "a4",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-09-30",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "99"
        }
    ],
    "actualsCsv": "",
    "actualsColumns": {
        "recordId": "recordId",
        "sourceId": "sourceId",
        "campaignId": "campaignId",
        "date": "date",
        "currency": "currency",
        "costBasis": "costBasis",
        "amount": "amount"
    },
    "coverage": [
        {
            "recordId": "cgoogle",
            "sourceId": "google",
            "campaignId": "0001",
            "currency": "USD",
            "costBasis": "billed",
            "startDate": "2026-10-01",
            "endDate": "2026-10-02",
            "completeness": "complete"
        },
        {
            "recordId": "cmeta",
            "sourceId": "meta",
            "campaignId": "0001",
            "currency": "EUR",
            "costBasis": "served",
            "startDate": "2026-10-01",
            "endDate": "2026-10-02",
            "completeness": "unknown"
        }
    ],
    "coverageCsv": "",
    "coverageColumns": {
        "recordId": "recordId",
        "sourceId": "sourceId",
        "campaignId": "campaignId",
        "currency": "currency",
        "costBasis": "costBasis",
        "startDate": "startDate",
        "endDate": "endDate",
        "completeness": "completeness"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("h_murdock/campaign-spend-plan-evidence").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 = {
    "snapshotId": "demo-2026-10-02",
    "planVersion": "media-plan-v3",
    "windowStart": "2026-10-01",
    "windowEnd": "2026-10-03",
    "asOfDate": "2026-10-02",
    "missingPlannedDayPolicy": "zero",
    "plans": [
        {
            "recordId": "pgoogle1",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-01",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.1",
        },
        {
            "recordId": "pgoogle2",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-02",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.2",
        },
        {
            "recordId": "pgoogle3",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-03",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.3",
        },
        {
            "recordId": "pmeta1",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-10-01",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "10",
        },
        {
            "recordId": "pmeta2",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-10-02",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "10",
        },
        {
            "recordId": "pmeta3",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-10-03",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "15",
        },
    ],
    "plansCsv": "",
    "plansColumns": {
        "recordId": "recordId",
        "sourceId": "sourceId",
        "campaignId": "campaignId",
        "date": "date",
        "currency": "currency",
        "costBasis": "costBasis",
        "amount": "amount",
    },
    "actuals": [
        {
            "recordId": "a0",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-01",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.1",
        },
        {
            "recordId": "a1",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-02",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.25",
        },
        {
            "recordId": "a2",
            "sourceId": "google",
            "campaignId": "0001",
            "date": "2026-10-03",
            "currency": "USD",
            "costBasis": "billed",
            "amount": "0.15",
        },
        {
            "recordId": "a3",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-10-01",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "8",
        },
        {
            "recordId": "a4",
            "sourceId": "meta",
            "campaignId": "0001",
            "date": "2026-09-30",
            "currency": "EUR",
            "costBasis": "served",
            "amount": "99",
        },
    ],
    "actualsCsv": "",
    "actualsColumns": {
        "recordId": "recordId",
        "sourceId": "sourceId",
        "campaignId": "campaignId",
        "date": "date",
        "currency": "currency",
        "costBasis": "costBasis",
        "amount": "amount",
    },
    "coverage": [
        {
            "recordId": "cgoogle",
            "sourceId": "google",
            "campaignId": "0001",
            "currency": "USD",
            "costBasis": "billed",
            "startDate": "2026-10-01",
            "endDate": "2026-10-02",
            "completeness": "complete",
        },
        {
            "recordId": "cmeta",
            "sourceId": "meta",
            "campaignId": "0001",
            "currency": "EUR",
            "costBasis": "served",
            "startDate": "2026-10-01",
            "endDate": "2026-10-02",
            "completeness": "unknown",
        },
    ],
    "coverageCsv": "",
    "coverageColumns": {
        "recordId": "recordId",
        "sourceId": "sourceId",
        "campaignId": "campaignId",
        "currency": "currency",
        "costBasis": "costBasis",
        "startDate": "startDate",
        "endDate": "endDate",
        "completeness": "completeness",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("h_murdock/campaign-spend-plan-evidence").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 '{
  "snapshotId": "demo-2026-10-02",
  "planVersion": "media-plan-v3",
  "windowStart": "2026-10-01",
  "windowEnd": "2026-10-03",
  "asOfDate": "2026-10-02",
  "missingPlannedDayPolicy": "zero",
  "plans": [
    {
      "recordId": "pgoogle1",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-01",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.1"
    },
    {
      "recordId": "pgoogle2",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-02",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.2"
    },
    {
      "recordId": "pgoogle3",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-03",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.3"
    },
    {
      "recordId": "pmeta1",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-10-01",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "10"
    },
    {
      "recordId": "pmeta2",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-10-02",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "10"
    },
    {
      "recordId": "pmeta3",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-10-03",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "15"
    }
  ],
  "plansCsv": "",
  "plansColumns": {
    "recordId": "recordId",
    "sourceId": "sourceId",
    "campaignId": "campaignId",
    "date": "date",
    "currency": "currency",
    "costBasis": "costBasis",
    "amount": "amount"
  },
  "actuals": [
    {
      "recordId": "a0",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-01",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.1"
    },
    {
      "recordId": "a1",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-02",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.25"
    },
    {
      "recordId": "a2",
      "sourceId": "google",
      "campaignId": "0001",
      "date": "2026-10-03",
      "currency": "USD",
      "costBasis": "billed",
      "amount": "0.15"
    },
    {
      "recordId": "a3",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-10-01",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "8"
    },
    {
      "recordId": "a4",
      "sourceId": "meta",
      "campaignId": "0001",
      "date": "2026-09-30",
      "currency": "EUR",
      "costBasis": "served",
      "amount": "99"
    }
  ],
  "actualsCsv": "",
  "actualsColumns": {
    "recordId": "recordId",
    "sourceId": "sourceId",
    "campaignId": "campaignId",
    "date": "date",
    "currency": "currency",
    "costBasis": "costBasis",
    "amount": "amount"
  },
  "coverage": [
    {
      "recordId": "cgoogle",
      "sourceId": "google",
      "campaignId": "0001",
      "currency": "USD",
      "costBasis": "billed",
      "startDate": "2026-10-01",
      "endDate": "2026-10-02",
      "completeness": "complete"
    },
    {
      "recordId": "cmeta",
      "sourceId": "meta",
      "campaignId": "0001",
      "currency": "EUR",
      "costBasis": "served",
      "startDate": "2026-10-01",
      "endDate": "2026-10-02",
      "completeness": "unknown"
    }
  ],
  "coverageCsv": "",
  "coverageColumns": {
    "recordId": "recordId",
    "sourceId": "sourceId",
    "campaignId": "campaignId",
    "currency": "currency",
    "costBasis": "costBasis",
    "startDate": "startDate",
    "endDate": "endDate",
    "completeness": "completeness"
  }
}' |
apify call h_murdock/campaign-spend-plan-evidence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,h_murdock/campaign-spend-plan-evidence"
        }
    }
}
```

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/Ytg7iP2sg2eCRigiQ/builds/IoeavpGagqngYefX9/openapi.json
