Build a Company List by Industry with the Clay CLI
Build a Company List by Industry with the Clay CLI
Source a targeted company list (a TAM) scoped to one industry vertical using the clay CLI's search commands, page through the full result set, and export it to CSV — no code required beyond a shell script.
What you will build
A bash script that discovers Clay's real filter fields, creates a companies search scoped to a confirmed industry value, and pages through results into a CSV.
clay search filters-mode fields --source-type companies (discover real field names)
↓
clay search filters-mode create --filters '{...}' (create, returns searchId)
↓
clay search filters-mode run <searchId> --limit N (repeat while hasMore)
↓
tam_export.csv
AI Prompt
Using the clay CLI, source a company TAM scoped to one industry vertical.
Requirements:
- Run `clay search filters-mode fields --source-type companies` first and
confirm the real filter field name for industry from the live response --
do not assume it is called "industry".
- The industry filter takes a controlled list of allowed values (returned as
`allowedValues` in the fields response). Confirm your target value against
that list before using it.
- Create the search with `clay search filters-mode create --source-type
companies --filters '{...}'`, then page with `clay search filters-mode run
<searchId> --limit N` repeatedly while `hasMore` is true.
- Write the accumulated `data` rows to tam_export.csv.
- Run the verification step below before finishing.
Prerequisites
- The
clayCLI on PATH (see Set up the Clay CLI) - An authenticated session:
clay login(opens a browser) orclay login --device(device-code flow for headless machines) jqfor JSON handling in the shell (optional but recommended)
1. Confirm the CLI is installed and authenticated
clay --version clay whoami
Expected: a version string, then {"user": {...}, "workspace": {...}}. If whoami fails with auth_required/auth_invalid (exit code 3), run clay login first.
2. Discover the real filter fields
clay search filters-mode fields --source-type companies
This returns every filterable company field, its type, and (where the field has a controlled vocabulary) its allowedValues. Confirmed live: the industry field is named industries (plural, array type), with 457 allowed values — not a free-text industry field.
clay search filters-mode fields --source-type companies | jq '.fields[] | select(.name=="industries") | .allowedValues | length'
Expected: 457.
3. Create the search
clay search filters-mode create --source-type companies --filters '{"industries":["Financial Services"]}'
Expected output:
{ "searchId": "search_XXXXXXXXXXXXXXXXXXXX" }
4. Page through results
clay search filters-mode run <searchId> --limit 5
hasMore: true means more pages remain. Re-run the same command with the same searchId to advance the iterator (it is forward-only — there is no cursor to replay). Stop when hasMore is false.
To collect a full export in one script:
SEARCH_ID=$(clay search filters-mode create --source-type companies --filters '{"industries":["Financial Services"]}' | jq -r '.searchId')
echo "[]" > tam_export.json
HAS_MORE=true
while [ "$HAS_MORE" = "true" ]; do
PAGE=$(clay search filters-mode run "$SEARCH_ID" --limit 100)
echo "$PAGE" | jq '.data' > page.json
jq -s '.[0] + .[1]' tam_export.json page.json > tam_export_tmp.json && mv tam_export_tmp.json tam_export.json
HAS_MORE=$(echo "$PAGE" | jq -r '.hasMore')
done
jq -r '(.[0] | keys_unsorted), (.[] | [.[]]) | @csv' tam_export.json > tam_export.csv
5. Verify the result
This example was tested live against industries: ["Financial Services"].
clay search filters-mode create --source-type companies --filters '{"industries":["Financial Services"]}'
Real output:
{ "searchId": "search_0tjzm258WqiZ4P3Ccho" }
clay search filters-mode run search_0tjzm258WqiZ4P3Ccho --limit 5
Real output (abbreviated): 5 real companies returned — JPMorganChase, J.P. Morgan, Goldman Sachs, Nubank, Citi — each with real domain, size, country, industry, annual_revenue, and total_funding_amount_range_usd fields. hasMore: true, periodQuota: {"limit": 10000000, "used": 21854, "remaining": 9978146}.
How it works
clay search filters-mode is a three-step, forward-only iterator: discover fields, create a search (returns a searchId), then repeatedly run that same id to advance and pull the next page. There is no cursor — the iterator's position lives server-side.
Common issues
validation_error (exit 2) on --filters
Cause: passing a filter value that isn't in the field's allowedValues (e.g. "fintech" instead of the real value "Financial Services"), or malformed JSON.
Fix: always run clay search filters-mode fields --source-type companies first and use one of the real allowedValues for controlled fields.
quota_exceeded (exit 1)
Cause: the workspace has hit a plan's per-request, per-search, or period result cap.
Fix: per the CLI's own documented guidance, do not retry blindly — read the error message to see which cap was hit, reduce --limit if it's a per-request cap, or stop paging if the period cap is exhausted.
CLI reports auth_required (exit 3) mid-script
Cause: the stored session expired or was never established.
Fix: run clay login (or clay login --device on a headless machine) and retry.
Next steps
- Enrich the sourced list — see the Clay contact-waterfall-enrichment example
- Score the sourced accounts — see the Clay firmographic lead-scoring example
- Detect hiring signals for the sourced list — see the Clay hiring-signals outbound example
Verification
verification:
status: verified
tested_at: "2026-08-18"
cli_version: "0.7.0"
auth_method: "clay login --device"
command: "clay search filters-mode create --source-type companies --filters '{\"industries\":[\"Financial Services\"]}' && clay search filters-mode run <searchId> --limit 5"
expected_result: "searchId returned; 5 real companies (JPMorganChase, J.P. Morgan, Goldman Sachs, Nubank, Citi), hasMore=true"