Work  /  Product  /  08

AdWash — Autonomous Google Ads Management

Built at Yelu Marketing · live SaaS · adwash.ai

Delivered — measured against the live production database, 2026-09-04

23workspaces
90campaigns
202AI generations
2,393automation events
~$234Kad spend tracked

Codebase, counted 2026-09-08: 45,148 lines of TypeScript · 63 API routes · 27 pages · 21 Prisma models · 27 migrations.

An ads dashboard with a bid slider, a sun and a rain cloud beside it, a payment card, coins and a target.

The problem

When a heat wave crosses 95°F, emergency AC searches spike within hours. A campaign adjusted next Tuesday has already missed it.

A contractor spending $5–20K a month on Google Ads can hire an agency and receive a monthly PDF explaining last month, or run it themselves and lose their evenings. Neither reacts to what actually drives the demand.

How it runs

  1. Write the campaign

    01 / 06

    A business profile becomes a complete Search campaign — ad groups, keywords, headlines, sitelinks, negatives — checked against Google’s own field limits.

  2. Critique it

    02 / 06

    A generator, an adversarial critic, a deterministic strength gate and a grounding audit all run before anything reaches a real ad account.

  3. Bid on the weather

    03 / 06

    Service areas are watched against live forecasts and classified per trade; budgets and bid modifiers move, then unwind when conditions normalise.

  4. Hold spend to plan

    04 / 06

    Real spend is ingested from the Google Ads API, and campaigns pause at the plan’s ceiling.

  5. Suggest, and wait

    05 / 06

    Rules over performance data raise suggestions with a concrete action attached; nothing is applied without an opt-in.

  6. Attribute revenue

    06 / 06

    Two-way sync with Housecall Pro and ServiceTitan matches booked jobs back to the click that produced them.

The guards, and what each one prevents

HoverTap a card to read what it prevents.

  • A failed read is not an empty result

    A malformed query once reported “no campaigns exist”, and a caller archived 75 live campaigns on it. Success is now reported separately from results, and callers that write abort instead.

  • The automation can undo itself

    The weather engine keeps a ledger of its own writes and resets only values that still match what it put there. Anything a person has changed since is left alone.

  • AI edits are typed operations

    The model emits operations from a closed vocabulary, applied to a clone of the live plan. A deep comparison refuses the whole change if anything moved that no operation claimed.

  • Success requires evidence of work

    A mutation that returns “ok” while matching nothing live is reported as a failure, not “Done”. Nobody investigates a cheerful success.

  • Writes are off by default

    Without an explicit flag, every Google Ads mutation is validate-only, so a misconfigured environment cannot spend anyone’s money.

  • Deploys assert their own outcome

    The build ID is present, the restart counter advanced, the homepage returns 200 and an authenticated endpoint 401 — or the deploy exits non-zero.

Limits, stated plainly

  • AdWash is Yelu Marketing’s product, built in my employed role as its only engineer. The engineering is mine; the product is not.
  • The headline numbers on adwash.ai — ROAS, time-to-live, the named testimonials — are promotional copy, not telemetry. None of them is on this page.
  • Weather bidding is a forecast-driven heuristic, not a demand model. It does not predict revenue.
  • Revenue attribution needs the CRM connected and the click ID to survive the journey. A call to a number that was never tracked cannot be matched.

Built with

  • Next.js
  • TypeScript
  • PostgreSQL
  • Prisma
  • Google Ads
  • Stripe