The Ad Runner

One intent. Three networks. Nothing spends without you.

Describe the campaign once. It compiles separately for each network against that network's own verified field set, dry-runs against the live API, and creates every object paused. Going live is a different action with a different button and a number on it.

Campaign intent

Q3 contractor range

Objective
Messages
Daily budget
$100.00
Geography
Kathmandu, Pokhara, Biratnagar

Written once.

Google Ads

1 campaign · 2 ad groups · 6 ads

Compiling

Meta Ads

1 campaign · 2 ad sets · 4 ads

Compiling

Microsoft Advertising

Built and conformance-passed

Waiting on a developer token

One intent, compiled three ways. Each network gets its own manifest, validated against its own API.

Early access. The builder, compiler, dry run, publish saga and previews are built and tested. Connecting a live ad account is waiting on platform credentials and app review, so campaign building is available to early-access workspaces first.

Spend

Everything lands paused. Go-live is a separate control.

There is no path in the product that publishes an active campaign in one step. The gate below is what you see before anything can spend, and it is the only thing that can turn spend on.

Q3 contractor range — 3 networks

PAUSED
  • No silent spend

    Every object is created paused. Going live is a separate action that shows projected daily and total spend, per platform and per currency, before you confirm.

  • Dry run before create

    The compiled plan is validated against each network's own API before anything is written. A campaign that would be rejected is rejected in review.

  • Numbers that admit what they are

    Networks count conversions over different windows. A figure that would span two reporting bases is labelled non-reconciled rather than averaged.

  • Partial failure is recoverable

    If one network accepts and another rejects, each platform can be retried on its own from the failed step, under the original idempotency root.

Reporting

Three columns that refuse to become one number

Each network counts a conversion over its own attribution window. Adding them produces a figure that is not true in any of the three, so the Ad Runner reports them separately and labels the row rather than blending it.

Google Ads

30-day click

128

conversions

$1,204.18

spend

Meta Ads

7-day click, 1-day view

96

conversions

$1,048.60

spend

Microsoft Advertising

30-day click

—

conversions

—

spend

Total conversionsNot reconciled

Three attribution windows. A single figure here would be wrong in at least two of them.

Failure

Partial failure is normal, and recoverable

If two networks accept a publish and one rejects it, the two that succeeded stay published and the third retries on its own — from the failed step, under the original idempotency root, so a retry cannot create the campaign twice.

Google Ads

21 objects created · paused

Meta Ads

14 objects created · paused

Microsoft Advertising

Attempt 2 of 5 · same idempotency root

idem:5f2c…a19

  • Google AdsSearch and Performance MaxEarly access
  • Meta AdsFacebook, Instagram, Messenger, Audience NetworkEarly access
  • Microsoft AdvertisingBing SearchIn development
  • TikTok AdsIn-feed videoPlanned