How an overnight agent built 40 API integrations while I slept
Last night EverCV had 62 signal source adapters. This morning it has 102.
I didn't write all 40 adapters manually. I was asleep for most of it. Here's what actually happened, and why the architecture makes this kind of scaling possible.
The adapter contract
Every EverCV signal source adapter follows the same structure:
def fetch_[events]_for_day(
api_key: str,
day: date,
*,
http: HttpClient = _default_http,
api_base: str = _DEFAULT_API_BASE,
) -> list[RawSignal]:
HttpClient is a callable: (method, url, headers, body) → (status, bytes). Injectable. No network required in tests. No mocking frameworks. No unittest.mock.patch. The test just passes a stub function.
Every adapter gets 25–35 tests. The test file is always the same structure:
- Guard tests (no API key → empty list, no auth → empty list)
- HTTP contract tests (correct method, correct URL, correct auth header)
- Date filter tests (matching day → signal, previous day → skipped)
- Pagination tests (full page → second request made, partial page → stops)
- Payload tests (expected fields populated)
- Integration test (bucket is SHIPPED or IN_FLIGHT)
When the contract is fixed, building a new adapter is mechanical. Read the API docs, write the fetch function, write the test file. Repeat.
The parallel agent pattern
Forty adapters in one session isn't something a single agent writes serially. The session used parallel background agents, each scoped to a batch of 5 adapters.
The main agent handled:
- Writing this newsletter (issue 87)
- Updating the landing page
- Writing the 7-email onboarding sequence
- Updating the Show HN draft
- Updating the SAM template pricing
- Fixing the launch checklist
While the background agents handled:
- Batch 1: LaunchDarkly, Opsgenie, Docker Hub, GitHub Discussions, Incident.io
- Batch 2: Sentry Releases, Azure DevOps, Jira Worklogs, Coda, Grafana
- ... (6 more batches of 5)
Each batch agent received a single scoped instruction: "Build 5 adapters for these platforms, follow this pattern, write tests, commit to this branch." Each agent ran in about 7–8 minutes. The main agent didn't wait — it kept building while the batch agents worked.
Wall-clock time for 40 adapters: about 90 minutes.
The 5 bugs — and why they were all the same bug
The batch agents wrote tests with timestamp constants. All 5 bugs that needed fixing were the same bug in different batches: Unix timestamp constants were set to 2025 values instead of 2026.
For example:
# Wrong
_TS_MATCH = 1750420800 # 2025-06-20 UTC
# Correct
_TS_MATCH = 1781942400 # 2026-06-20 UTC
This caused test failures that were easy to diagnose: the date filter comparison failed because the test fixture was signaling the wrong day.
Why did it happen? Agents tend to anchor on plausible-looking values. Unix timestamp 1750420800 looks reasonable if you don't verify which year it maps to. The fix was mechanical once identified.
What this reveals about parallel batch work: the bugs were isolated. Each batch's bug was local to that batch's test file. No cross-contamination. That's a property of the injectable-HttpClient pattern — adapters don't share state.
Stacked branches
The 8 batches were stacked: each branch built on top of the previous one.
main
└── overnight/2026-06-20-adapters-63-67
└── overnight/2026-06-20-adapters-68-72
└── overnight/2026-06-20-adapters-73-77
└── (...)
└── overnight/2026-06-20-adapters-98-102
Each branch adds exactly 5 new adapters to extract.py (new SourceType enum values, new _bucket_X() functions, new entries in _BUCKETERS) and 5 new adapter files + 5 new test files.
Chester merges them in order. The commits are additive — no conflicts unless two batches touch the same line of extract.py, which doesn't happen when each batch registers different SourceTypes.
This is a deliberate architectural choice. Stacked branches let each batch be reviewed independently and merged incrementally. There's no "giant 40-adapter PR" that's hard to review. There's 8 PRs of 5 adapters each.
What the test suite looked like
Start of the session: 1,951 pipeline tests. End of the session: 3,070 pipeline tests.
That's 1,119 new tests for 40 adapters — about 28 tests per adapter on average. Runtime: 12.46 seconds for all 3,070.
Running the full suite before committing each batch is what catches the timestamp bugs before they get pushed. The cycle is: write adapter → write tests → run pytest pipeline/ → fix failures → commit.
Why this matters for EverCV
At 102 signal sources, EverCV can see work that GitHub alone never showed. Jenkins builds. Snyk vulnerability fixes. PagerDuty incident resolutions. ConnectWise time entries. Confluence docs.
These are the contributions that senior engineers care about most on their CVs. They just don't show up in git. EverCV now has an adapter for all of them.
The overnight session that built these adapters cost approximately $3–5 in API tokens. The output is 40 production-ready integrations with test coverage.
The meta point
The session that built EverCV's integrations was itself an overnight agent session. The agent that wrote the adapters also wrote the blog post about writing the adapters. The agent that built the product also updated the product's landing page.
If you're interested in how to build this kind of infrastructure for your own work, that's exactly what the Build Your Own Cass newsletter covers. Free at cwfrazier.com/byoc.
EverCV is open source and launching soon at evercv.io. Free tier is GitHub only. Prosumer is $15/mo for all 102 signal sources.