github.com/growthenginenowoslawski/autoclaybuilder

AutoClayBuilder
Builds Clay tables — correctly, verifiably, the first time.

Clay tables are intricate stacks of formulas, AI columns, and API integrations, and a single wrong setting breaks a run silently. AutoClayBuilder makes building one safe and provable: describe the table you want, it forces an exact build plan you approve before anything is created, builds it into a throwaway scratch table, then mathematically proves the result matches the spec. Reverse-engineering an existing table is part of it — but only as the calibration step that proves the build payloads are right.

Show the technical detail
Plain-English by default. Flip this for the API calls, ID remapping, and parity scoring.
Why this exists

The problem it solves

Building a Clay table by hand is slow and silently error-prone. Cloning one to "learn how it works" still leaves you guessing whether your next build is right. AutoClayBuilder turns building into a planned, verified process.

By hand Build and hope

Click 100+ columns into existence from memory. One wrong field type or missing input binding and the run produces wrong output — with no error to tell you.

AutoClayBuilder Plan → build → prove

An approved plan first, a scratch build second, then a field-by-field parity score against the spec. You ship a number, not a guess.

The headline feature

Plan mode, the moment you open the repo

No setup, no command to remember. The repo self-activates into a planning gate.

It refuses to build blind.

The repo ships a CLAUDE.md at its root. Any AI coding agent (Claude Code, etc.) loads it automatically the instant the repo is opened.

That note hard-gates building behind an approved plan: the agent must lock the spec, read every past scar in docs/learnings/, fill in plans/TEMPLATE.md, and get your explicit "go" — before a single Clay API call fires.

So "how should this table be built?" is answered in writing, by the repo itself, every time — not improvised mid-build.

# you clone the repo and open it $ git clone …/autoclaybuilder && claude ✓ CLAUDE.md loaded — plan mode active you › build me a table that finds a company's funding news claude › Before I build: I need the spec locked. What's the source of truth, and what columns + types? I'll write a plan to plans/ and you approve it before I touch Clay. # no silent build. ever.
The core workflow

From "I want a table" to a proven build — 7 steps

Steps 1–4 happen before anything is created. Step 4 is a hard approval gate. The build itself only ever touches a throwaway scratch table, with action columns saved without running so no real API calls fire by accident.

1

Lock the spec

Interview until the goal, the source of truth, every column and its type, and the non-goals are unambiguous. You can't build what you can't state exactly.

If a reference Clay table exists, treat it as the spec and read its real config via the API (the calibration loop) instead of guessing from the UI. Output: a filled plans/TEMPLATE.md draft.
2

Read the accumulated knowledge don't skip

Pull in the reusable column patterns and — critically — every past failure already paid for, so this build doesn't repeat one.

  • docs/recent-table-patterns.md — reusable column/integration patterns
  • docs/frontend-api-patterns.md — which endpoints are verified vs inferred
  • docs/learnings/ — the scars. If a learning flagged a column type as unstable, the plan must call it out with a link.
3

Write the plan plans/TEMPLATE.md

Fill a 10-section build plan: goal, exact target shape column-by-column, field mapping, every endpoint marked verified or inferred, risks from past scars, non-goals, verification plan, and the ordered runbook.

A reader of the finished plan should be able to predict every API call the build will make. "Inferred" endpoints are higher risk and are flagged explicitly in the approval ask.
4

Approval gate no silent builds

Present the plan, ask for an unambiguous yes. Silence, enthusiasm, or "looks good" on one section is not approval. Pushback → edit plan → re-ask. Nothing is created in Clay until this clears.

Once approved, the plan is the contract for the build; deviations get logged in the learnings file with the reason.
5

Build into a scratch table source untouched

Recreate every column, formula, AI prompt, integration, field group, view order, and seed row in a brand-new disposable table — saved without running it.

  • POST /v3/workbooksPOST /v3/tables (template:"no_views")
  • Action columns created as full actions up front — Clay won't promote a text field later
  • Clay generates its own field IDs → build a source→target ID map and remap IDs everywhere (formulas, inputsBinding, inputFieldIds, extracted fields, views, cross-table refs)
  • Seed first 10 rows, scalar values. Verify cellCount = 0 so no placeholder API calls fire.
6

Calibrate & verify math, not vibes

Re-fetch the scratch table fresh — a "200 OK" write isn't proof Clay kept what you sent; it silently normalizes. Score config parity against the spec field-by-field.

scripts/score_clay_parity.py: strips volatile keys, remaps target IDs back to source IDs, deep-compares each field. Outputs score (matched/total), status (perfect_config_parity / config_mismatch), and typed mismatches. The fresh readback is the only authority.
7

Write the learning compound

End every build with a redacted learnings file: what worked, what didn't, the mistakes, what the next builder should do differently. Then ask before opening a PR.

docs/learnings/YYYY-MM-DD-<slug>.md. The next build inherits the scar, not the wound. Never auto-push.
Steps 5–6 loop until a stop condition. Either perfect config parity (100% score + 10-row seed check + browser evidence for UI-only settings) — or an evidence-backed blocker: the exact failing step, fresh readback, redacted request/response, and proof no remaining path bypasses it.
Calibration strategy

Four ways to prove a build, run in parallel

When calibrating against a known table, the same target is rebuilt four different ways at once. Whichever reaches perfect parity first wins; the rest are marked "abandoned by better path." This is how the builder earns confidence in its payloads.

api-first

Configure entirely via the frontend API. Browser only for gaps and final verification.

browser-first

Recreate through the Clay UI like a human would, then verify with an API snapshot.

duplicate-then-patch

Use Clay's native duplicate endpoint as a head start, then patch the mismatches.

from-scratch-api-browser

API-built scratch base, with the browser handling un-reproducible columns.

Data flow

What goes in, what comes out

Everything in the middle stays local and gitignored. Only redacted, public-safe artifacts ever leave the machine.

Inputs

  • The table you want spec, field list, or a reference URL
  • Authenticated Clay session real Chrome cookies, never committed
  • Optional build outline bullets, screenshot
Plan → Build → Prove
spec · plan · approve
scratch build · score

Local only (gitignored)

  • Approved build plan
  • Scratch workbook + target readback
  • Source→target field-ID map
  • Browser-state screenshots

Outputs

  • A working scratch table matching the spec
  • Parity score report JSON
  • Append-only run log TSV: parity, status, notes
  • Learnings doc "the scars" future builds inherit
Integrations

What it talks to

Two systems are called directly. The rest are Clay column types the builder must recreate faithfully — not services this tool calls itself.

Clay frontend API · primary, undocumented
browser-use + Chrome · UI verification
GitHub Actions · minimal CI

Column types it must build exactly:

OpenAI / Claygent (use-ai)
HTTP API v2
Smartlead
Slack
Google Sheets
HubSpot
Mixrank
Cross-table lookups
Subroutines & normalizers
Proven by calibration

The benchmark — and the one wall it found

Calibration run on 2026-05-03 against a real 103-field table.

98.45%config parity

The best non-duplicate rebuild recreated 103 fields, 2 views, 7 field groups, and 10 seed rows faithfully — proving the build payloads are correct.

The only mismatch: 4 Claygent / use-ai fields where a hidden rate-limit setting was silently normalized from 200 → workspace default 5 despite Clay returning 200 OK. No UI control to override — a documented, evidence-backed blocker, not a build error.

Durable lesson: a fresh API readback is always authoritative. Config parity is a stricter, more honest bar than "the sample rows ran fine" — which is exactly why the builder is gated on it.