Skip to content
heyenrich
Last updated 2026-10-21

API reference

Base URL https://api.heyenrich.io. Bearer auth. JSON in, JSON out. A miss is HTTP 200 with match: false and credits_charged: 0.

Authentication and limits

ItemValue
HeaderAuthorization: Bearer he_live_… (or he_test_… for the sandbox)
Content typeapplication/json
Rate limits60 rpm Starter, 300 Growth, Custom sets its own; shared across sub-keys; bulk jobs not counted
Limit headersX-RateLimit-Limit, X-RateLimit-Remaining, Retry-After on 429
IdempotencyIdempotency-Key header on POST /v1/bulk
Sandboxhe_test_ keys return the three sample people and never charge

POST /v1/lookup

One person. Send one identifier set and the fields you want. Name, title, company and LinkedIn URL come free with any match.

Request
{
  // one of:
  "linkedin_url": "https://linkedin.com/in/priya-raman-example",
  "first_name": "Priya", "last_name": "Raman", "domain": "northwind-traders.example",
  "first_name": "Priya", "last_name": "Raman", "location": "Austin, TX",
  "work_email": "p.raman@northwind-traders.example",

  "fields": ["work_email", "personal_email", "mobile"]   // optional; default ["work_email"]
}

Response

200 OK
{
  "match": true,
  "name": "Priya Raman",
  "title": "Head of Growth",
  "linkedin_url": "https://linkedin.com/in/priya-raman-example",
  "company": { "name": "Northwind Traders", "domain": "northwind-traders.example",
               "headcount_band": "51-200", "industry": "Logistics", "hq_country": "US" },
  "work_email":     { "value": "p.raman@northwind-traders.example", "state": "verified", "checked_at": "2026-10-18" },
  "personal_email": { "value": null, "state": "notfound", "checked_at": null },
  "mobile":         { "value": "+15125550141", "line_type": "mobile", "state": "verified", "checked_at": "2026-10-02" },
  "credits_charged": 6,
  "latency_ms": 171
}

// no match:
{ "match": false, "credits_charged": 0, "latency_ms": 92 }

Field states

StateMeaningCharged
verifiedResolved at lookup time (mailbox accepted, or carrier and line-type check passed)Yes
riskyDomain is catch-all; address follows the company pattern but can't be confirmedYes
notfoundNothing on fileNo

POST /v1/bulk

Up to 100,000 rows as JSON, or multipart CSV with a column mapping. Returns a job id. Poll GET /v1/bulk/{job_id} or pass webhook_url.

Request and status
POST /v1/bulk
Idempotency-Key: 7f3c…
{
  "rows": [ { "linkedin_url": "https://linkedin.com/in/…" }, { "first_name": "…", "last_name": "…", "domain": "…" } ],
  "fields": ["work_email", "mobile"],
  "webhook_url": "https://example.com/hooks/heyenrich"
}
→ { "job_id": "job_01J…", "rows": 2, "estimated_credits_max": 12 }

GET /v1/bulk/job_01J…
→ { "status": "done", "rows": 2, "filled": { "work_email": 2, "mobile": 1 },
    "credits_charged": 7, "download_url": "https://…/job_01J….csv" }

GET /v1/company/{domain}

Email pattern with share, catch-all status, mail provider and firmographics. Free with any person match in the same session; 1 credit standalone.

Response
{
  "domain": "northwind-traders.example",
  "patterns": [ { "pattern": "first.last", "share": 0.78 }, { "pattern": "flast", "share": 0.12 } ],
  "sample_size": 1240,
  "catch_all": false,
  "mx_provider": "google",
  "headcount_band": "51-200", "industry": "Logistics", "hq_country": "US",
  "credits_charged": 1
}

POST /v1/verify

Check an address you already have. 0.5 credit.

Request and response
{ "email": "p.raman@northwind-traders.example" }
→ { "state": "verified", "checked_at": "2026-10-21", "catch_all": false, "credits_charged": 0.5 }

GET /v1/credits

Response
{ "balance": 742, "used_this_period": 258,
  "rollover": [ { "credits": 120, "expires": "2027-01-01" } ] }

Errors

HTTPMeaningWhat to do
400Bad input; message says which fieldFix the request
401Bad or missing keyCheck the Authorization header
402No credits leftTop up or wait for the period to reset
429Rate limitedHonour Retry-After
5xxOur faultRetry with backoff; status.heyenrich.io shows incidents

Webhooks

bulk.completed and person.suppressed, signed with HMAC-SHA256 in X-HeyEnrich-Signature. Verify the signature before acting.

person.suppressed
POST https://example.com/hooks/heyenrich
X-HeyEnrich-Signature: sha256=…
{
  "event": "person.suppressed",
  "person_hash": "sha256:…",
  "fields": ["work_email", "mobile"],
  "at": "2026-10-21T09:12:00Z"
}
// Delete every copy of the record you hold. Required under the terms.

Changelog

Behaviour changes to the API are listed on /changelog with dates. Breaking changes get a new version prefix and at least 90 days of overlap.