Case study
Folio
An outreach agent I built with Claude Code. It finds contacts, checks every email, sends on a schedule, reads the replies, and rewrites its own emails when they stop working.
The dashboard is private, so the live app opens at a login. Ask me for a walkthrough.
- Domain-sales campaigns
- 9
- Outreach pipelines
- 2
- Scheduled jobs
- 4
- Bounce rate that auto-pauses a campaign
- 15%
Two pipelines, one agent.
Folio is a private dashboard. Underneath it, an agent watches its own results and decides what to change.
It runs two outreach pipelines side by side. One sells domains across nine campaigns. The other finds Malaysian small businesses with weak websites, scores each site, and offers them a better one by email or WhatsApp.
I built it with Claude Code on Next.js, and it runs on a schedule with nobody at the keyboard.
A day in Folio
Purge
Deletes bounced and passed contacts, and anyone who never replied after 60 days. I added it after a PDPA review.
The Brain
Validates every email, writes a Gmail draft for each contact due today, sorts replies into interested or passed, and checks for bounces. Then it logs the run and hands the numbers to Claude.
The Hands
Sends the drafts one at a time, 15 to 45 minutes apart, up to the daily limit I set in Settings. It reads that limit live, so changing it needs no redeploy.
Prospecting
Once a week it searches for new companies and finds real contact emails, then adds them to the queue. It caps itself at six new companies per campaign.
It edits itself.
After every run, Folio asks Claude to read the numbers.
Claude reads each campaign's stats, every email template, and the last 14 recorded runs. It writes a short reflection in the first person about what is working and what is not.
Where a template underperforms, Claude rewrites it, without being told to. A Telegram message tells me what changed, and the Strategy Log keeps a before and after for every edit.
Automation with brakes.
One-click pause
Both daily jobs check the system status before every action.
Per-campaign switches
Any campaign can be turned off without touching the others.
A daily send limit
From 5 to 25 a day, read live on every run.
Auto-pause on bounces
If a campaign's bounce rate reaches 15%, Folio pauses it and tells me.
Validation first
Every address is checked before a draft is written. Undeliverable ones are skipped.
People, not inboxes
Generic addresses like info@ are filtered out, so mail goes to a named person.
Locked down
A login with 12-hour sessions, and every server action checks the session first.
Built for the PDPA
The nightly purge keeps personal data from sitting around longer than it should.
Two things that went wrong.
The brake was too tight.
My first bounce limit was 10%. It kept pausing a campaign at normal cold-email bounce rates, so I raised it to 15% and switched the campaign back on.
The privacy fix hid the results.
After I added the purge, the dashboard showed zero replies even though real people had answered. The purge was deleting contacts before they were counted. I fixed it with running totals that hold no personal data.
Under the hood.
- App
- Next.js, TypeScript, Tailwind CSS and shadcn/ui
- Data
- SQLite locally, Turso in production
- AI
- Claude for the reflection loop, Gemini Flash for sorting replies
- Scheduling
- Google Apps Script and Vercel Cron
- Prospecting
- Apify, Hunter, Firecrawl and Abstract API
- Alerts
- Telegram
- Hosting
- Vercel
Want one for your business?
The same pattern fits any repeat job: find, check, write, send, learn.
I build these as part of the Codex tier, scoped to your workflow. You own the code and the accounts.