# Waterfall templates (/docs/concepts/waterfall-templates)



A template is a prebuilt [waterfall](/docs/concepts/waterfalls). Each step names a capability rather
than a vendor, so the router chooses the vendors unless you pin them. Browse them with the
explanations of each step at [/waterfalls/templates](/waterfalls/templates). This page is
generated from the same library as the API (`GET /v1/waterfalls/templates`).

## Status [#status]

| Status  | Meaning                                                                                                                                                                                                       |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ready   | Routed vendors can run every stage today on your own vendor keys. `availability.vendor_keys` lists the keys that unlock it; one key per stage is enough.                                                      |
| Sandbox | Runs on the `sandbox-*` vendors with a `grid_test_` key, no vendor key needed. Sandbox calls are priced like real ones and draw on your credit. Use the `scenario` input to script hits, misses and timeouts. |
| Preview | Vendors document the capability publicly, but none is routed yet. You can read the steps; creating one returns `422 validation_failed`.                                                                       |

Costs are list prices per run from the catalog: the minimum is the cheapest vendor per stage and the
maximum is every eligible vendor trying, capped by the template's `max_cost_micro`. Conditional
stages count 0 toward the minimum. With your own keys, GridRouter charges $0 and the vendor bills its
own rate.

## Contacts [#contacts]

| Template | Status | Inputs | Outputs | Capabilities | Speed · mode | Per run |
| --- | --- | --- | --- | --- | --- | --- |
| `work-email` Work email finder: Name + company domain → a verified work email. | Ready | `first_name`, `last_name`, `domain` | `email`, `confidence`, `status`, `mx_provider` | `people.email.find` → `email.verify` | Balanced: one at a time, hedged · Sync (one request) | $0.012–$0.078 |
| `email-from-profile` Email from a profile URL: B2B profile URL → name and employer → verified work email. | Ready | `profile_url` | `full_name`, `title`, `company_name`, `company_website`, `email`, `confidence`, `status`, `mx_provider` | `people.enrich` → `people.email.find` → `email.verify` | Balanced: one at a time, hedged · Sync (one request) | $0.012–$0.090 |
| `mobile-number` Mobile number finder: Profile URL or email → a mobile / direct dial. | Ready | `profile_url`?, `work_email`?, `personal_email`? (Send at least one of profile_url, work_email or personal_email.) | `mobile_number` | `phone.mobile.find` | Thorough: cheapest first · Sync (one request) | $0.060 |
| `email-verification` Email verification (consensus): One address → a verdict that several verifiers agree on. | Ready | `email` | `status`, `mx_provider` | `email.verify` | Fast: vendors race · Batch (lists) | $0.016 |
| `catch-all-resolution` Catch-all resolution: Keep verifying until a verifier gives a definitive valid or invalid. | Ready | `email` | `status`, `mx_provider` | `email.verify` | Thorough: cheapest first · Batch (lists) | $0.0035–$0.016 |
| `reverse-email-lookup` Reverse email lookup: Email → the person behind it: profile, title, employer. | Ready | `email` | `profile_url`, `full_name`, `first_name`, `last_name`, `title`, `company_name`, `company_website`, `location`, `country`, `work_experience` | `people.profile.find` → `people.enrich` | Balanced: one at a time, hedged · Sync (one request) | $0.120–$0.132 |
| `phone-validation` Phone validation: Phone number → valid, line type and carrier. | Preview | `phone` | `valid`, `line_type`, `carrier_name`, `country_code`, `ported` | `phone.lookup` | Fast: vendors race · Batch (lists) | — |
| `dnc-check` Do-not-call check: Phone number → line type, then DNC and litigator lists before dialing. | Preview | `phone` | `line_type`, `listed`, `lists`, `litigator`, `reassigned` | `phone.lookup` → `compliance.dnc.check` | Balanced: one at a time, hedged · Batch (lists) | — |
| `sandbox-work-email` Work email finder (sandbox): Swift, then Deep, then Sure on the sandbox vendors: runs on a test key, no vendor key needed. | Sandbox | `first_name`, `last_name`, `domain`, `scenario`? | `email`, `confidence` | `people.email.find` | Balanced: one at a time, hedged · Sync (one request) | $0.004–$0.028 |
| `sandbox-mobile-number` Mobile number finder (sandbox): Cheapest-first mobile waterfall over the sandbox vendors. | Sandbox | `profile_url`?, `work_email`?, `scenario`? (Send profile_url or work_email.) | `mobile_number` | `phone.mobile.find` | Thorough: cheapest first · Sync (one request) | $0.015–$0.090 |

## People [#people]

| Template | Status | Inputs | Outputs | Capabilities | Speed · mode | Per run |
| --- | --- | --- | --- | --- | --- | --- |
| `person-enrichment` Person enrichment: Profile URL or email → title, seniority, employer and history. | Ready | `profile_url`?, `email`? (Send profile_url, or email when you don't have it.) | `profile_url`, `full_name`, `first_name`, `last_name`, `title`, `company_name`, `company_website`, `location`, `country`, `work_experience` | `people.profile.find` → `people.enrich` | Balanced: one at a time, hedged · Sync (one request) | $0.012–$0.132 |
| `job-change-detection` Job change detection: Profile URL + the company you know them at → did they move, and where. | Ready | `profile_url`, `domain`? | `job_change_detected`, `current_company`, `expected_company`, `summary`, `status` | `signals.job_change` | Balanced: one at a time, hedged · Batch (lists) | $0.036 |
| `decision-makers` Decision maker by role: Company domain + job title → the person who holds it. | Ready | `domain`, `job_title` | `name`, `first_name`, `last_name`, `profile_url`, `company_name` | `people.role.find` | Balanced: one at a time, hedged · Sync (one request) | $0.024 |
| `employee-list` Employee list: Company domain → people who work there, billed per row. | Ready | `domain`, `limit`? | `people`, `total_count` | `people.search` | Balanced: one at a time, hedged · Sync (one request) | $0.006–$0.036 |
| `social-profiles` Social profiles: Email or name → the person's social profiles and handles. | Preview | `email` | `profile_url`, `platform`, `handle`, `followers` | `social.profile.find` | Balanced: one at a time, hedged · Sync (one request) | — |

## Company [#company]

| Template | Status | Inputs | Outputs | Capabilities | Speed · mode | Per run |
| --- | --- | --- | --- | --- | --- | --- |
| `company-enrichment` Company enrichment: Domain → firmographics: headcount, industry, revenue, funding, stack. | Ready | `domain` | `name`, `employees`, `industry`, `website`, `description`, `founded_year`, `revenue`, `total_funding`, `technologies` | `company.enrich` | Balanced: one at a time, hedged · Sync (one request) | $0.012 |
| `technographics` Technographics: Domain → the technologies a company runs. | Preview | `domain` | `technologies`, `technology_category`, `last_detected` | `company.technographics` | Fast: vendors race · Sync (one request) | — |
| `funding-financials` Funding and financials: Domain → funding rounds, investors, revenue and filings. | Preview | `domain` | `total_funding_usd`, `last_round_type`, `last_round_date`, `investors`, `revenue_usd`, `fiscal_year` | `company.funding` → `company.financials` | Balanced: one at a time, hedged · Sync (one request) | — |
| `hiring-signals` Hiring signals: Domain → open roles by department and hiring velocity. | Preview | `domain` | `open_roles`, `roles_by_department`, `growth_rate`, `job_title` | `signals.hiring` → `jobs.company_postings` | Balanced: one at a time, hedged · Sync (one request) | — |
| `intent-signals` Intent surge by topic: Topic → accounts researching it more than usual this week. | Preview | `topic` | `company_domain`, `score`, `surging`, `week` | `signals.intent` | Balanced: one at a time, hedged · Async (poll or webhook) | — |
| `news-monitoring` Company news: Domain or name → recent news mentions and events. | Preview | `domain` | `title`, `url`, `published_at`, `source_name`, `summary` | `news.company_mentions` | Balanced: one at a time, hedged · Sync (one request) | — |
| `reviews-reputation` Reviews and reputation: Business domain or place → average rating, review count and recent reviews. | Preview | `domain`?, `place_id`? (Send domain or place_id.) | `average_rating`, `review_count`, `text`, `platform` | `reviews.business` | Balanced: one at a time, hedged · Sync (one request) | — |
| `kyb-verification` KYB and sanctions screening: Company → registry record, officers and a sanctions/PEP screen. | Preview | `name`, `jurisdiction`? | `registration_number`, `status`, `incorporation_date`, `registered_address`, `role`, `match_count`, `lists` | `registry.company_lookup` → `registry.officers` → `compliance.sanctions.screen` | Thorough: cheapest first · Async (poll or webhook) | — |
| `local-business-lookup` Local business lookup: Business name + area → address, phone, website, rating and hours. | Preview | `query`, `near` | `name`, `address`, `phone`, `website`, `rating`, `opening_hours` | `places.search` → `places.details` | Balanced: one at a time, hedged · Sync (one request) | — |
| `ads-intelligence` Ads intelligence: Advertiser → what they run on Meta, Google and LinkedIn. | Preview | `domain`, `query`? | `advertiser_name`, `headline`, `landing_url`, `first_seen`, `platform` | `ads.meta.search` → `ads.google.search` → `ads.linkedin.search` | Fast: vendors race · Async (poll or webhook) | — |
| `seo-presence` SEO and SERP presence: Domain → traffic, backlinks and where it ranks for a keyword. | Preview | `domain`, `query`? | `visits`, `referring_domains`, `authority`, `position` | `seo.traffic` → `seo.backlinks` → `serp.google.search` | Balanced: one at a time, hedged · Async (poll or webhook) | — |
| `ip-to-company` IP to company: Visitor IP → the company behind it, with firmographics. | Preview | `ip` | `company_name`, `company_domain`, `is_isp`, `confidence`, `employees`, `industry` | `ip.company_lookup` → `company.enrich` | Fast: vendors race · Sync (one request) | — |
| `sandbox-company-enrichment` Company enrichment (sandbox): Race all three sandbox vendors and merge field by field. | Sandbox | `domain`, `scenario`? | `name`, `employees`, `industry`, `technologies` | `company.enrich` | Fast: vendors race · Sync (one request) | $0.018 |

## Composite [#composite]

| Template | Status | Inputs | Outputs | Capabilities | Speed · mode | Per run |
| --- | --- | --- | --- | --- | --- | --- |
| `full-lead-enrichment` Full lead enrichment: Name + domain → verified email, profile, title, mobile and company. | Ready | `first_name`, `last_name`, `domain`, `profile_url`? | `email`, `confidence`, `status`, `mx_provider`, `profile_url`, `full_name`, `title`, `company_name`, `company_website`, `location`, `country`, `work_experience`, `mobile_number`, `name`, `employees`, `industry`, `website`, `description`, `founded_year`, `revenue`, `total_funding`, `technologies` | `people.email.find` → `email.verify` → `people.profile.find` → `people.enrich` → `phone.mobile.find` → `company.enrich` | Balanced: one at a time, hedged · Async (poll or webhook) | $0.084–$0.282 |
| `account-research-brief` Account research brief: Domain → firmographics, tech stack, hiring and news in one record. | Preview | `domain` | `name`, `employees`, `industry`, `website`, `technologies`, `open_roles`, `title` | `company.enrich` → `company.technographics` → `signals.hiring` → `news.company_mentions` | Balanced: one at a time, hedged · Async (poll or webhook) | — |
| `inbound-lead-enrichment` Inbound lead enrichment: Form fill (email) → verified, with the person and company for routing. | Ready | `email`, `domain`? | `status`, `mx_provider`, `profile_url`, `full_name`, `first_name`, `last_name`, `title`, `company_name`, `company_website`, `location`, `country`, `work_experience`, `name`, `employees`, `industry`, `website`, `description`, `founded_year`, `revenue`, `total_funding`, `technologies` | `email.verify` → `people.profile.find` → `people.enrich` → `company.enrich` | Fast: vendors race · Sync (one request) | $0.120–$0.172 |
| `crm-hygiene` CRM hygiene: CRM record → re-verified email, job change check and refreshed company. | Ready | `email`?, `profile_url`?, `domain`? (Send whichever of email, profile_url and domain the record has.) | `status`, `mx_provider`, `job_change_detected`, `current_company`, `name`, `employees`, `industry`, `website` | `email.verify` → `signals.job_change` → `company.enrich` | Thorough: cheapest first · Batch (lists) | $0–$0.064 |
| `decision-maker-emails` Decision maker + verified email: Domain + job title → the role holder and their verified work email. | Ready | `domain`, `job_title` | `name`, `profile_url`, `company_name`, `email`, `confidence`, `status`, `mx_provider` | `people.role.find` → `people.email.find` → `email.verify` | Balanced: one at a time, hedged · Batch (lists) | $0.024–$0.102 |
| `sandbox-email-then-mobile` Email, then mobile (sandbox): Two sandbox stages: find the work email, then feed it to a mobile waterfall. | Sandbox | `first_name`, `last_name`, `domain`, `scenario`? | `email`, `mobile_number` | `people.email.find` → `phone.mobile.find` | Balanced: one at a time, hedged · Sync (one request) | $0.004–$0.088 |

## On the roadmap [#on-the-roadmap]

These need a capability that no integrated vendor exposes through a public API yet, or an engine
feature. They ship when one does.

| Template | Category | Waiting on |
| --- | --- | --- |
| `personal-email` Personal email finder: Profile URL → a personal address. | contacts | No catalog capability returns personal addresses, and no listed vendor documents a public API for it. |
| `company-domain-lookup` Company name to domain: Company name → its website domain. | company | The catalog's company search filters by industry and size, not by name; no name-to-domain capability is defined yet. |
| `lookalike-companies` Lookalike companies: Seed domain → companies like it. | company | No lookalike capability in the catalog; only one listed vendor documents lookalike search publicly, below the bar for a new capability. |
| `competitors` Competitors: Domain → the company's direct competitors. | company | No competitor capability; listed vendors offer it behind sales-gated APIs or only as SEO keyword overlap. |
| `company-profile-firmographics` Company profile URL → firmographics: B2B company page URL → firmographics. | company | Company enrichment takes a domain; no catalog capability takes a company profile URL as input yet. |
| `ecommerce-store-data` E-commerce store data: Store domain → platform, apps, products and estimated sales. | company | commerce.store_lookup is in the catalog, but its one listed vendor has no public API docs. |
| `ai-lead-scoring` AI lead scoring: Enriched lead → a fit score with reasons. | composite | A stage input maps one field, so a model step can't be given the whole enriched record as its prompt, and no model endpoint is routed yet. Score the Inbound lead enrichment output in your CRM for now. |
| `ai-account-brief` AI-written account brief: Account research record → a five-line brief written by a model. | composite | Same gap as AI lead scoring: composing a prompt from several stages needs a prompt-template step the engine doesn't have yet. |
| `icp-list-building` ICP list building: ICP filters → companies → people → verified emails. | composite | Company search is not routed yet and a run returns one record (no fan-out). Today: batch-run Decision maker + verified email over your target domains. |
| `crm-dedupe` CRM dedupe and normalize: Merge duplicate records and normalize names, titles and domains. | composite | Dedupe works across rows and no capability does it; CRM hygiene covers the per-record re-verification. |

## Use one [#use-one]

| Surface   | Call                                                                                                                                         |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| API       | `POST /v1/waterfalls/from-template` `{"template":"work-email","pins":{"email":["hunter"]},"speed":"balanced","max_cost_micro":100000}`       |
| MCP       | `waterfall_templates`, `waterfall_template_get`, `waterfall_create_from_template`, `waterfall_estimate`, `waterfall_run`, `waterfall_status` |
| SDK       | `grid.waterfalls.templates.list()`, `grid.waterfalls.fromTemplate("work-email")`, `grid.waterfalls.run(id, input)`                           |
| Dashboard | Waterfalls → Templates → Use template opens it in the builder with its sample input in the test runner                                       |

`pins` maps a stage id to the vendor slugs tried first. The router still falls back to other vendors
unless `pins_only` is `true`. `speed` is `fast` (race), `balanced` (one at a time, hedged) or
`thorough` (cheapest first, 90 s deadline). The new waterfall is published as `1.0.0` unless you pass
`"publish": false`.

