Icypeas runs email searches and verifications as background jobs, so a long list does not hold anything up. You hand it the list, it works through it, hyreflow collects the results when they land.
Icypeas is the volume option. Reach for it when the list is long enough that throughput matters more than per-row cleverness.
Ask for the outcome and your agent composes the run itself. Or start from a skill, a whole pipeline it already knows end to end.
browse all skills →Every tool ships with a written playbook, and the agent loads it before the first call. Auth, rate limits, what each call costs, which actions need your approval, and the mistakes worth avoiding. It is the difference between an agent that knows the tool and one that guesses at it.
Read the Icypeas docs →HOW in lib/icypeas.py. Docs cached at reference/docs/icypeas/raw/.
https://app.icypeas.com/api · Auth: header Authorization: <API_KEY> (env ICYPEAS_API_KEY; never hardcode). Rate limit ~30 req/min.email_search / email_verification / domain_search launch a job (return an id) → poll read_results (POST /bulk-single-searchs/read) or use a webhook.
Email-finding/verification layer. Launch searches for a shortlist → poll → validate → ATS/sequencer.
Field-shape note: these are vendor-native operational notes. The client returns the raw vendor JSON and uses the method names in this file — read field shapes accordingly (no normalized-wrapper /
result.data.prefix).
SCHEDULED + an _id -> poll read_results by _id for the final email.NOT_FOUND and DEBITED_NOT_FOUND as non-deliverable.lib/icypeas.pyImport: from lib.icypeas import Icypeas → instantiate Icypeas() (reads key from env). Base: https://app.icypeas.com/api. Generic passthrough: request(method, path, *, params, json).
domain_search(payload: dict) -> dict — POST /domain-search — find emails for a domain (async).email_search(payload: dict) -> dict — POST /email-search — launch an email-finder search (async). Returns a job id.email_verification(payload: dict) -> dict — POST /email-verification — verify an email (async).read_results(payload: dict) -> dict — POST /bulk-single-searchs/read — poll results for launched searches (by id/filters).