Skip to main content
Patronage logo
Patronage Loop · Open source

Your marketing data, ready for your agent.

Patronage Loop is built on two open-source foundations you can run on your own infrastructure with your own credentials. Marketing Connectors give an agent live access to ad platforms. Ads Sync retains a queryable history of reporting data. Together they let an agent investigate a marketing question instead of reading a dashboard.

See how an agent uses it
01

Connectors

Live reads · guarded mutations

02

Ads Sync

Retained, queryable history

03

Your agent

Claude · Codex · Cursor

What is open

Two tools. Independently useful.

No Loop account is required for either one. Each ships as a public package, runs on your own account and credentials, and is documented on its own site. Ads Sync is not a separate paid service.

Marketing Connectors

Worker-safe packages that turn provider APIs into typed reads, deterministic plans, and guarded mutations. Your agent calls them directly from a Cloudflare Worker or a local CLI.

  • @patronage/google-ads
  • @patronage/meta-ads
  • @patronage/linkedin-ads
  • @patronage/reddit-ads
  • @patronage/tiktok-ads
  • @patronage/connector-lifecycle
marketing-connectors.patronage.com

Ads Sync

An ingestion toolkit that runs on your Cloudflare account and lands Google Ads, Google Search Console, and Meta Ads reporting in your own Postgres on a schedule. The config names each secret and never holds its value.

  • @patronage/ads-sync on npm
  • current version in the docs
adsync.patronage.com

Retained by Ads Sync

Google Search Console
Google Ads
Meta Ads

Live connector access

LinkedIn Ads
Reddit Ads
TikTok Ads
X

Ads Sync retains history for the first three. The rest are live access only.

Conversational investigation

Ask what changed. Then keep going.

Retained history means the agent can answer the follow-up, not just the first question. This sequence uses Google Search Console query and page rows that Ads Sync has kept in your own Postgres. The agent reads them with SQL and needs nothing from Loop.

The transcript is illustrative and the rows are synthetic. Search Console finalizes data two to three days after the fact, so the agent reads to that horizon by default.

Investigation

Operator · Agent · Source: search_analytics_query_page · Read mode: final

Open source path
  1. 01
    What changed in Search Console for the resource pages over the last two weeks?

    Comparing the fourteen final days ending three days ago with the fourteen before. Three resource pages moved.

    PageClicks, priorClicks, recentImpressions, recent
    /resources/grant-writing-checklist4122869,140
    /resources/donor-retention-guide1982416,380
    /resources/annual-report-template1561724,910
  2. 02
    Show me the queries behind the page that dropped.

    Query rows for /resources/grant-writing-checklist, web search, same two windows.

    QueryClicks, priorClicks, recent
    grant writing checklist17198
    nonprofit grant checklist9671
    grant proposal checklist template6455
    what should a grant application include1231
  3. 03
    Compare the shape of those queries to the same weeks last month.

    Same site, search type, and page. Short head terms lost clicks. Longer, question-shaped queries appeared that were not in last month’s rows.

    QueryLast monthClicks, recent
    what should a grant application includenot present31
    how do I write a grant checklist for a small nonprofitnot present19
    grant writing checklistpresent98

    Query phrasing is evidence for a later review, not proof of where a search came from. Search Console does not tell you which surface produced a query.

  4. 04
    Pull the full query and page rows for that page so I can look myself.

    Reading every row for /resources/grant-writing-checklist from your Postgres: site, search type, date, query, page, clicks, impressions, CTR, position. Window is the last thirty final days. Source is the search_analytics_query_page stream from the scheduled Ads Sync run.

    Available · your database312 rows written to a CSV in your working directory.
Honest about the boundary

Available now. Intended for Loop.

Every line below carries one of two labels. Available means you can run it today from the public packages. Intended means managed Loop is being built to do it, and it is not shipped.

  • Marketing Connectors for Google Ads, Meta Ads, LinkedIn Ads, Reddit Ads, and TikTok Ads on npm.

    Available
  • Ads Sync on npm with Google Search Console, Google Ads, and Meta Ads providers.

    Available
  • Your Cloudflare account, your Postgres, your provider credentials. Nothing routes through Patronage.

    Available
  • Search Console query and page history, read to the final-data horizon by default.

    Available
  • A fresh thirty-day start, daily final ingestion, then explicitly enabled bounded backfill.

    Intended
  • Managed Loop selects qualified sources centrally and reports coverage and freshness separately.

    Intended
  • Tenant-authorized downloadable extracts for large results inside Loop.

    Intended
  • Downstream classification of conversational queries, using retained history as evidence.

    Intended

Intended items describe where managed Loop is going. They are not a guarantee of dates, completeness, or real-time delivery.

Pick your path

Run it yourself, or let Loop run it.

Both paths use the same packages. The difference is who operates them and who keeps the record of what ran.

Open source, on your own

No Loop account. Your infrastructure, your credentials.

Deploy Ads Sync to your Cloudflare account and Postgres. Give your agent the connectors and a database connection. It queries Postgres and calls the provider APIs directly.

Managed Loop

The same foundations, operated for your Projects.

Loop runs the connectors and Ads Sync for each Project, keeps an activity record with a name on every action, and is intended to select qualified sources centrally so the agent does not have to.

About Patronage Loop

A Loop tenant can leave and resume single-tenant on the open-source core. The procedure is documented: Eject from Loop.

Open where it should be open. Managed where your team needs it.