← all tools
Enrichment

BetterContact

Waterfall enrichment across providers, a hundred leads at a time.

Cost per call4.8 cr / result
Your own keyoptional
CategoryEnrichment

BetterContact queries multiple data vendors for each contact and returns the best result, in batches of up to a hundred. Emails are cheap. Phone numbers cost roughly ten times as much, so hyreflow leaves them switched off unless you ask for them.

Another waterfall option. It runs after the shortlist exists and before anything is validated.

things you can ask for

  • Enrich these 100 leads, emails only, no phone numbers
  • Take the longlist from TheirStack and resolve contact details for the decision makers
  • Get numbers for these six, I want to call them today
  • Validate everything that comes back through Enrichley before we send

works well with BetterContact

  • TheirStack

    start from companies with a live hiring signal

  • Enrichley

    the deliverability gate after the waterfall

  • FullEnrich

    the alternative waterfall, worth trying on a thin batch

  • Instantly

    send to the addresses that came back clean

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 →

What your agent reads before it touches BetterContact

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 BetterContact docs →
Show the raw playbookwritten for the agent

HOW in lib/bettercontact.py. Docs cached at reference/docs/bettercontact/raw/.

Auth & config

  • Base URL: https://app.bettercontact.rocks/api/v2 · Auth: header X-API-Key (env BETTERCONTACT_API_KEY; never hardcode).

Async flow

  1. start_enrichment(data=[{first_name,last_name,company,company_domain,linkedin_url,...}], enrich_email_address=True, enrich_phone_number=False, webhook=None)POST /async → returns {id}. Max 100 leads/request.
  2. get_enrichment(request_id)GET /async/{request_id} — poll until terminal (or use webhook).

Guardrails

  • enrich_phone_number=True raises the charge from 0.5 to 4.8 credits (billed once, on retrieval, when the result carries data) — default off, enable only when a phone number is actually needed. Pilot a small batch first.

Handoff

Waterfall enrichment layer (multi-provider email/phone). Take a shortlist → BetterContact → validate (Enrichley/email-validation) → ATS/sequencer.

Field notes (production experience)

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).

  • Async: start_enrichment returns a request id immediately -> fetch terminal data via get_enrichment(request_id).
  • Email status hierarchy: deliverable > catch_all_safe > catch_all_not_safe > undeliverable - only trust deliverable and catch_all_safe for outreach.
  • Batch up to 100 contacts per request.
  • Pricing: 0.5 credits for an email reveal, 4.8 for a phone reveal (email included), charged once when the retrieved result carries data -> only set enrich_phone_number: true when explicitly needed. get_enrichment returns credits_consumed.
  • Rate limit: 60 req/min per key (shared across endpoints).
  • Use it for: multi-provider waterfall email/phone when single-provider finders (LeadMagic/Prospeo) miss. Not for validation-only or company enrichment.

Callable surface — lib/bettercontact.py

Import: from lib.bettercontact import BetterContact → instantiate BetterContact() (reads key from env). Base: https://app.bettercontact.rocks/api/v2. Generic passthrough: request(method, path, *, params, json).

  • get_enrichment(request_id: str) -> dict — GET /async/{request_id} — poll the enrichment result.
  • start_enrichment(data: list[dict], *, enrich_email_address: bool = True, enrich_phone_number: bool = False, webhook: str | None = None, **opts) -> dict — POST /async — start waterfall enrichment for up to 100 leads. Returns {id}.