| 2026 | WilowProduct & Growth | Run product and growth for Wilow, creative analytics for Meta advertisers, selling enterprise deals end to end and growing the self-serve plan. | ProductGrowthMeta AdsAI | |
| 2025 | FramerGrowth | Managed an ad spend of $500k+ a month across Google, Meta, YouTube, LinkedIn and Reddit. | Google AdsMeta AdsYouTubeLinkedIn Ads | |
| 2024 | Hoxton CircleMarketing Director | Sole marketer at a B2B recruitment firm placing CFOs, where I migrated the website and lifted traffic 45%. | SEOSite migrationOutbound | |
| 2023 | Kits.aiGrowth | Restructured Google Search ads for a high-growth AI music SaaS and scaled the budget 10x while holding a 3:1 LTV:CAC. | Google AdsSearch | |
| 2022 to 2024 | General AssemblyLecturer | Taught 10-week digital marketing courses in New York, with an NPS in the top 5% of courses. | TeachingPaid media | |
| 2022 | WPPContractor | Sub-contracted to WPP, the global ad agency, on Nestlé's Meta and Twitter accounts. | Meta AdsX Ads | |
| 2014 to 2021 | CroudClient Strategy DirectorAssociate Director, BiddableSenior Biddable ManagerClient Strategy ManagerPaid Search ManagerIntern | 7 years agency-side in London and New York, where I helped grow the US team from 4 to 50. | Google AdsSEOStrategyTeam lead |

Wilow
trywilow.comCreative analytics for Meta ads. See what is working in your own account and your competitors'.
Clerk
Meta
OpenAI
PolarMeta Ads Library tool
trywilow.com/meta-ads-librarySearch any brand and see the Meta ads it is running. One dataset, four surfaces.
Meta
VercelAd Index
trywilow.com/ad-indexMeta ads benchmarks by industry, rebuilt from live ads each week.
Meta
Vercel
Webflow
Schema.org
SlackAd Studio
trywilow.com/ad-studioPick an ad worth learning from and it makes your own version of it.
OpenAI
Meta
Polar
The Keyword
thekeyword.coA marketing newsletter and site. Agents do the mechanical work, people make the calls.
Beehiiv
Webflow
LinkedIn
ClaudeLark
github.com/bkoleo/larkFree Mac dictation app that also records and transcribes meetings, entirely on your machine.
Tauri
Rust
NVIDIA ParakeetOutbound email
A brand's public ads become a personal report, then the system finds the right person and sends it.
Pull the adsA script collects the brand's live ads from Meta's Ad Library. If it can't confirm it has the full set, the report stays a draft.
Gemini learns what the brand sells and to whom, then tags each ad on six dimensions.
A second pass tries to disprove each label. What it can't settle goes to a person, and their corrections become rules for next time.
Build the reportEach brand gets its own report, which stays a draft until each label is checked.
Make sample adsWhere creative is the brand's gap, OpenAI's image model turns its own product photo into three new ad ideas, with the product's details locked.
I choose which sample goes in the report.
Hand off the researchEach brand goes to a Slack channel as a research task for Hermes, a second agent system.
Find the ownerA research agent names the people most likely to run the brand's ads, several in order, so one bad address doesn't end the attempt.
Find the addressThe research agent looks up each person's email in Kitt. If the results disagree, the address is marked as a guess.
Check the researchClaude reviews the research before it reaches the CRM, so no system checks its own work.
Host the reportEach report gets its own private link on Wilow's domain, and visits are logged, so a reply isn't the only sign of interest.
Nothing sends until I approve it, and each email goes to one person, with no colleague copied in.
Send and follow upAgentMail sends from a pool of warmed-up inboxes. Follow-ups stop as soon as someone replies, bounces or is out of office.
What went into it
- Reports never claim to cover a brand's whole ad library, only what was collected.
- Each prospect gets a unique link, so a visit can be traced back to the email.
- A small pool of inboxes warms up over eight weeks, from five sends a day to thirty.
- Sends are logged, and a missed send raises an alarm.
Built with
Meta
Claude
OpenAI
Slack
Hermes Agent
Kitt
AgentMail
VercelProspect research
A free version of my outbound research, run from Claude: live ads, labels it argues with, the right person and a draft.
Find the brandsClaude searches Clay's company database, through its MCP, for US consumer brands with 11 to 200 staff, and drops any owned by a larger group.
Pull the adsA browser script reads each brand's live ads from Meta's public Ad Library, with no login and no paid scraper.
If the advertiser page shows no ads, a keyword search checks again. In the first run the page view missed four of five brands, each running 86 to 214 ads.
Label each brandClaude labels the audience, the offer and the creative format from the ads it collected.
Try to disprove the labelsA second pass argues against each label and rewrites the ones that fail. In the first run it changed three of fifteen.
Find the personClay's people search names a founder or marketing lead at each brand, with their LinkedIn profile and a backup.
Draft the messageOne short message per brand that leads with an offer and uses at most one number or observation, taken from that brand's own ads.
Nothing is sent. The run ends in a dated file for me to read.
What went into it
- The first run covered five US brands and cost nothing in tools.
- Ad counts that stop short of the library's result total are reported as a minimum.
- A brand with no one senior enough to write to is replaced, not messaged.
- It is saved as a skill, so a new batch is one request.
Built with
Claude
Clay
MetaInternal knowledge base
An agent keeps Wilow's product knowledge base true to what actually shipped.
Read what shippedThe knowledge agent starts from the code that shipped that day. Code proves something shipped; a closed ticket doesn't.
Match to the taskThe knowledge agent pairs each change with its ClickUp task to learn what it was meant to do. Unmatched changes go to a review queue.
The knowledge agent reads summaries of the team's recorded calls for the reasoning behind each change.
Scan team chatThe knowledge agent reads the team's Slack channel for decisions made since its last run.
Update the docsThe knowledge agent rewrites one doc section per feature and marks how sure it is: unconfirmed, shipped in code, or confirmed in the app.
Publish to the wikiThe knowledge agent saves to the team wiki, and never overwrites a teammate's edit.
Correct the websiteThe knowledge agent checks trywilow.com against what shipped, fixes outdated claims itself and drafts the rest for me.
What went into it
- Shipped code is the source of truth. A closed task doesn't count as proof.
- Decisions also go to the team wiki, gathered from meetings, Slack and task comments.
- An early version reported success on work it never finished, so it was rebuilt to do the work itself.
- The website check exists because an audit found 9 live pages denying shipped features, on pages bringing in about 65% of search clicks.
Built with
GitHub
ClickUp
Slack
Claude
Vercel
WebflowAgent fleet
More than 30 scheduled agents run my businesses, with written rules on what each may do alone.
Scheduled runs are held during the day and released later, skipping any that a later run already covers.
Claude agentsClaude Code agents start on a schedule, with no one at the keyboard.
Hermes agentsA second platform, Hermes, runs its own agents. They sit in the same list as the Claude ones, so one view shows the whole fleet.
Each agent judges an action by who it reaches and whether it can be undone. Private and reversible, it just does it. Public, it shows me what changed. Permanent or costing money, it asks first.
Wake on a messageA webhook on Vercel turns each new Slack message into a task for a responder agent, so a message doesn't wait for a schedule.
Clear names in SlackEach platform posts in Slack under its own name, so I always know which system said what.
A script compares the live schedules with the written record and flags any agent still running from instructions that were deleted.
What went into it
- The guiding rule: silence is not success. "Nothing needed doing" and "I am broken" must look different.
- The health check's error count sits on my operating dashboard, where it should read zero.
- What an agent may do alone depends on the risk of the action, not its subject.
Built with
Claude
Hermes Agent
Slack
VercelSEO and AEO
A quality bar a page must clear before it publishes, and a checker that reads pages like a search engine.
Find the keywordAn SEO agent starts from Search Console, with searches a page already ranks for in positions 5 to 15. Searches from buyers come first.
Study the competitionThe SEO agent pulls the top 10 results for that search: the pages it has to beat.
Check it can winThe SEO agent checks how strong those sites are in Ahrefs. If they are far stronger, it doesn't write the page.
Map the questionsThe SEO agent breaks the search into the questions behind it, the way AI search does. The page answers each in a sentence or two, so AI tools can quote it.
The page must include something no top-10 result has, such as original data, a real quote or a tool.
Structured dataStructured data is built into the page itself, so search engines and AI tools can read it.
Weekly site checkOn Fridays a site-check agent runs a 20-rule technical check over trywilow.com. Simple fixes ship; bigger ones are queued.
Answer inside AIA connector hosted on Vercel puts Wilow's Ad Library data inside Claude, ChatGPT and other AI assistants, so they can quote it.
What went into it
- The checker's 20 rules cover page structure, indexing, structured data and internal links. It can block a release, not just report.
- It was built after a set of pages passed a weaker check that only counted headings.
- The standard also covers the templates that generate whole families of pages.
Built with
Google Search Console
Exa
Ahrefs
Claude
Schema.org
Webflow
VercelContent pipeline
A chain of agents sources, picks, researches, writes and publishes the news for The Keyword.
Read TechmemeEach morning a news agent reads Techmeme, a tech news feed, for the last two days of stories.
Search the newsThe news agent runs a web-wide news search through Exa.
Read newslettersAn inbox agent reads industry newsletters sent to the publication's inbox and traces each story to its original source.
Collect the storiesBoth agents post their stories to one Slack channel, with duplicates removed.
Pick one or passAn editor agent picks at most one story, using four written tests. If nothing passes, it picks nothing.
Post the pickThe editor agent posts its pick to the newsroom channel.
Find the sourceA research agent finds the official source behind the story. Official pages are linked; trusted outlets are credited.
Check the archiveThe research agent checks the site hasn't covered the story before, then writes a brief.
Write the articleA writing agent drafts from the brief, checks itself against the publication's editorial standards, and rewrites what fails.
PublishThe writing agent publishes to the site with a placeholder cover image.
Share the linkOnce the page is live, the writing agent posts the link in Slack with any facts it couldn't verify, so I know what to check.
Brief the coverLater that morning a cover agent writes the prompt for a cover image in the publication's style.
Generate the coverOpenAI's image model makes the cover, with the company's real logo supplied as an image.
Swap the coverThe cover agent shrinks the image, replaces the placeholder and republishes.
Queue the newsletterThe writing agent adds the story to the next newsletter in Beehiiv. I write the lead article and press send.
What went into it
- Editorial taste is written down as four tests. A story the editor agent is unsure about doesn't pass.
- The tests were drawn from 131 items in 20 past issues, then checked blind against 806 stories.
- My corrections become notes the next draft reads, so the writer learns from them.
Built with
Techmeme
Exa
AgentMail
Slack
Claude
Webflow
Hermes Agent
OpenAI
BeehiivBookkeeping
An agent reads supplier invoices out of email each week and books them in FreeAgent, under the accountants' own rules.
Each week the bookkeeping agent reads the company inbox for supplier invoices from the last nine days, because receipts arrive by email rather than in the accounting system.
Read each invoiceThe bookkeeping agent opens every PDF and reads the supplier, the date and the amounts off the page, so nobody retypes them.
Apply the written rulesThe bookkeeping agent applies a rules document the accountants wrote, which is the only source of VAT and category rules. It never takes guidance from an email and never invents a rule of its own.
Record the invoiceEach invoice goes into FreeAgent through the API, with the VAT treatment the rules document sets.
Suggest the categoriesFor bank transactions the bookkeeping agent learns from the ones already explained, and only suggests a category where the same payee and direction agree across at least two of them. Anything thinner comes back with the reason it was unsure.
Every suggestion arrives switched off, so nothing posts to the books until I turn it on. Each posted row is then stamped with FreeAgent's own timestamp, so a re-run cannot post it twice.
Catch what I paid for myselfCosts paid on my personal card never reach the company bank feed, so the bookkeeping agent records them only on positive evidence that I paid them. A missing bank transaction is not evidence, and treating it as one would double count the cost when the feed catches up.
Anything the rules document does not cover goes on a list for me instead of being guessed.
What went into it
- The accountants' rules live in one document, and it is rewritten only when they send new advice.
- A category is only suggested where the same payee and direction already agree across two explained transactions.
- Every proposed row starts switched off, and a posted row is stamped, so a re-run cannot post it twice.
- Costs paid personally are recorded only on positive evidence, so nothing is counted twice.
Built with
Hermes Agent
FreeAgent
Claude