Playbooks / Recipe

List Build and Verify: Search, Find, Verify, In That Order

The most common chain in the catalog: people_search to build the list, email_finder to get addresses, email_verifier to check them. The search leg bills per row returned; the finder and verifier legs are waterfall calls where a miss costs zero.

Pattern: people_search (or a company employee search) → dedupe and filter → email_finder → email_verifier. The order is the whole recipe. Reverse any two steps and you pay for rows you should never have touched.

In short: The standard RichAPI list-building chain is three calls in a fixed order. First people_search or linkedin_company_employees_search (per-result pricing, billed on every row returned on any 2xx response) filtered by domain, job_title, industry, employee_size_start/employee_size_end and location, with page and limit acting as cost controls. Second email_finder, which accepts either first_name plus last_name plus company_domain, or a linkedin_url. Third email_verifier, which accepts a single email address. email_finder and email_verifier are waterfall endpoints: a call where the sources run and return nothing comes back 2xx with success:false and billed:false and costs zero credits. The search leg is not a waterfall endpoint and bills on any 2xx, including one returning few or no rows. Base URL https://api.richapi.ai/api/v1/, auth via an x-api-key header. There is no prospecting UI, no CSV upload screen and no sending or sequencing; the API returns data and the reader stores it. New accounts get 100 free credits with no credit card.

Last updated November 4, 2026

Credit math

A 500-row build: people_search at 0.1 credits per result × 500 rows = 50 credits, billed on every row the search returns. Filter to 320 real targets. email_finder at 5 credits per call × 320, minus every miss, which returns billed:false and costs zero. email_verifier at 2 credits per call on the hits only, never on the whole 500. Run the numbers for your own hit rate at /tools/waterfall-cost-calculator.

ROI math

The saving is in step order, not in a discount. Verifying before filtering means paying 2 credits a row on rows you were going to drop; finding before filtering means paying 5. Filter first and the finder runs on the smallest defensible list. Credit tiers at /pricing.

Owned internally by

Whoever owns the list. Usually one GTM engineer, a script, and a table.

Best for

Anyone building a few hundred to a few thousand rows a month who is currently paying per seat for a UI they use as an export button.

  1. 01

    Write the search filter before you write any code.

    Domain list, titles, headcount band, geography. A filter you can describe in one sentence produces a list you can write one first line for.

  2. 02

    Page deliberately.

    people_search bills per row returned, so limit and page are cost controls. Pull one page, look at it, then decide whether to pull the next.

  3. 03

    Dedupe on the LinkedIn URL, not the name.

    Two people called the same thing at the same company is rarer than one person appearing in two pages of results.

  4. 04

    Filter to the rows you will actually contact.

    This step costs nothing and removes the most expensive calls downstream.

  5. 05

    Run email_finder on the survivors.

    Prefer the LinkedIn URL over name-plus-domain when you have it. Same price, better input.

  6. 06

    Run email_verifier on the found addresses only, then store the status with the row.

    Do not re-verify a row you verified last week.

Example
# Step 1 — search. Per-result billing: every row returned is billed,
# so limit is a budget control, not a display preference.
curl -s https://api.richapi.ai/api/v1/people_search \
  -H "x-api-key: $RICHAPI_KEY" \
  -H "content-type: application/json" \
  -d '{
    "page": 0,
    "limit": 50,
    "domain": ["acme.com", "globex.com"],
    "job_title": ["Head of Revenue Operations", "RevOps Manager"],
    "employee_size_start": 50,
    "employee_size_end": 500,
    "location": ["United Kingdom"]
  }'

# Step 2 — find, on the filtered rows only. Waterfall: a miss returns
# 2xx with success:false, billed:false, zero credits.
curl -s https://api.richapi.ai/api/v1/email_finder \
  -H "x-api-key: $RICHAPI_KEY" \
  -H "content-type: application/json" \
  -d '{"linkedin_url": "https://www.linkedin.com/in/dana-weiss-example/"}'

# Step 3 — verify, on the hits only.
curl -s https://api.richapi.ai/api/v1/email_verifier \
  -H "x-api-key: $RICHAPI_KEY" \
  -H "content-type: application/json" \
  -d '{"email": "dana.weiss@acme.com"}'

List build and verify: search, find, verify, in that order

This is the chain most people are looking for when they find us, and the one most often run in the wrong sequence. Three calls: search for the people, find their addresses, verify what you found. Get the order right and the expensive call runs on the smallest possible list. Get it wrong and you pay full price for rows you were always going to delete.

Why the order is the recipe

The three legs have different billing behaviour, and that's what fixes the sequence.

people_search is per-result. It bills 0.1 credits per result on every row it hands back, on any 2xx response. limit is not a display setting. It is how much you are agreeing to spend on that call.

email_finder is a waterfall, at 5 credits per call. sources run cheapest-first; if none of them returns an address, you get a 2xx with success: false and billed: false, and the call costs zero. You are paying for found addresses, not attempts.

email_verifier is also a waterfall, at 2 credits per call.

So: the cheap-per-row call comes first and defines the universe. The filtering happens in your own code, for free. The expensive-per-row calls come last, on the smallest list you can defend. Any other order means paying finder or verifier prices on rows that a free filter would have removed.

The chain, concretely

Start with people_search, which takes domain, job_title, industry, employee_size_start/employee_size_end, location, plus page and limit. If you already have target accounts, linkedin_company_employees_search is the narrower door, on the same per-result model, scoped to one company.

Then filter. Drop the rows whose titles matched the string but not the job. Drop the people who left. Drop your existing customers, which is the one that actually embarrasses you if you skip it.

Then email_finder on what's left. It takes either name plus company domain, or a LinkedIn URL. If you have the LinkedIn URL from step one, use it. It's the same price and a better input than a guessed domain.

Then email_verifier on the addresses you got. Store the verdict next to the row with a timestamp.

The failure mode: verifying everything

The most common way to burn credits on this chain is to treat verification as a hygiene pass over the whole list instead of a check on the rows that produced an address.

Two specific versions of it. First, verifying rows the finder missed, where there's nothing to verify, and a blank address isn't a verifier input. Second, re-verifying the same list every export because it's the last step in a script nobody has read since March. A verified address doesn't decay in a week. Store the status, store the date, and only re-run when the date is old enough to matter for your sending volume.

The mirrored mistake is running email_finder on an unfiltered search dump. A miss costs you nothing, true, but a hit on someone you'll never contact costs full price, and unfiltered lists are full of them.

What this doesn't include

No UI. There is no screen to upload a CSV into, no saved list, no table to click through. You get JSON, you store it. If you want a table you can click, Clay is a better purchase.

No sending. The chain ends with a verified address in your own store. Whatever puts it into a sequence is yours. See enrichment backend for platforms if the thing consuming the list is your own product.

Bulk endpoints exist for the enrichment legs (enrich_companies_bulk, enrich_profiles_bulk, both per-result at 1 credit per result), but the finder and verifier legs are per-call. Loop them yourself.

List build and verify FAQ

What do I do with a catch-all verdict? Treat it as its own bucket, not as valid and not as invalid. A catch-all domain accepts everything at the MX layer, so the verifier can't prove the mailbox exists. Some teams send anyway at low volume; some route those rows to a different channel.

Does a search that returns nothing cost anything? A 2xx with no rows still ran, and per-result endpoints bill on 2xx. Only the waterfall endpoints (email_finder, email_verifier, phone_finder) return genuinely free misses.

How do I avoid paying twice for the same person? Dedupe on LinkedIn URL before the finder leg, and keep a table of every address you've already found. The API has no memory of your previous calls and won't stop you buying the same row twice.

Can I do this from a chat window instead of a script? For a dozen rows, yes: agent driven account research. For five hundred, write the script.

Do I need a card? No. 100 free credits on signup, which covers a small search page plus a handful of finder and verifier calls end to end.

Where to go after list build and verify

people search and email finder for the endpoint detail, and the use cases hub for the rest of the plays. waterfall email then verify goes deeper on the last two legs, signal based prospecting replaces step one with an event instead of a filter, and Hunter covers how this differs from a per-lookup credit model. Tiers on pricing.

100 free credits, no card. Build one page of results and take it all the way to verified.

FAQ

Frequently asked

Treat it as its own bucket, not as valid and not as invalid. A catch-all domain accepts everything at the MX layer, so the verifier can't prove the mailbox exists. Some teams send anyway at low volume; some route those rows to a different channel.
A 2xx with no rows still ran, and per-result endpoints bill on 2xx. Only the waterfall endpoints (`email_finder`, `email_verifier`, `phone_finder`) return genuinely free misses.
Dedupe on LinkedIn URL before the finder leg, and keep a table of every address you've already found. The API has no memory of your previous calls and won't stop you buying the same row twice.
For a dozen rows, yes: [agent driven account research](/use-cases/agent-driven-account-research). For five hundred, write the script.
No. 100 free credits on signup, which covers a small search page plus a handful of finder and verifier calls end to end.

More playbooks

Related playbooks