
Waterfall enrichment is a simple concept. Query data source A. If it returns empty, try data source B. If that is also empty, try data source C. Stop as soon as you get a valid result.
The order matters. Cheaper and faster sources go first. Expensive or rate-limited sources serve as fallbacks. You stop as soon as you get a valid result.
Why most Clay tables break at scale
I have rebuilt dozens of Clay tables that worked in demos but failed in production. The failure modes are predictable.
First, API rate limits. Every enrichment provider has them. When you run 5,000 rows through a table, you hit limits that never appeared in your 50-row test.
Second, enrichment cascades. Column B depends on Column A. Column C depends on Column B. If Column A fails, everything downstream produces garbage. No error handling means silent failures.
Third, no deduplication. You import 5,000 leads. 800 of them are duplicates. You just paid for 800 unnecessary enrichment calls.
The column architecture I use
I organize every table into four zones: Input, Enrichment, Scoring, and Output. Each zone has a naming convention.
Input columns are prefixed with input_ and contain your raw data. Domain, name, title, LinkedIn URL. These never change during enrichment.
Enrichment columns are prefixed with enrich_ and include the source name. For example: enrich_email_apollo, enrich_email_hunter, enrich_email_dropcontact. Each one has conditional logic: only run if the previous source returned empty.
Scoring columns are prefixed with score_ and contain calculated values. ICP fit score, engagement score, total priority score.
Output columns are prefixed with output_ and contain the final clean data that goes to your CRM. The output_email column takes the first non-empty value from the enrichment waterfall.
This structure makes tables readable at 30+ columns. More importantly, it makes debugging possible when something breaks.

