Contact Endpoints
All three contact operations are part of All tools. A start needs the
relevant scope and enough credits, and the tool must be available in
/v1/health. Free credits also follow the
free limits. Accepted starts return 202 Accepted.
All contact endpoints are preview. Preview means the contract may still evolve before stable release; returned data is live contact data, not sample output.
Contact operations do not accept operation callback fields, dry_run,
offset, artifact controls, or raw provider options. Unknown request fields
are rejected.
All three contact operations are also available to verified free accounts and guest trial API credentials while free use is available. Free credits are one-off grants and do not refresh monthly.
See Contact Pricing for fixed prices, plan access, no-result settlement, and no-cost failure behavior.
POST/v1/contacts/domain-search
Finds public contacts associated with a company domain.
Required Access
- Access: Paid plans that include this family, or free credits (guest trial or verified account) within the free limits.
- Operation family: Contacts
- Scope:
api:contact:write - Credits: 80 credits reserved on acceptance
- Idempotency:
Idempotency-Keyheader required
Request
{
"domain": "example.com",
"limit": 10,
"departments": ["sales"],
"seniorities": ["director", "manager"],
"include_generic": false
}
Fields:
domain: required hostname only, such asexample.com. Chab lowercases the hostname and removes one trailing dot. URLs, paths, query strings, and schemes are rejected.limit: optional integer from 1 to 25; defaults to 10.departments: optional array of up to 5 unique values. Supported values areexecutive,sales,marketing,engineering,support,finance,hr,legal,operations,other, andunknown.seniorities: optional array of up to 5 unique values. Supported values areowner,founder,c_level,vp,director,manager,individual, andunknown.include_generic: optional boolean; defaults totrue. Setfalseto exclude role or shared addresses such assales@orinfo@.
Chab matches related filters through coarse groups. For seniority,
owner, founder, and c_level share one executive group, while vp,
director, and manager share one senior group. For departments, operations
spans management and operations roles, while marketing spans marketing and
communication roles. If a selection includes other or unknown, Chab avoids
a provider-side filter that would exclude those values and enforces the complete
selection after results are normalized. The requested limit is applied after
normalization, filtering, and deduplication, so an earlier nonmatching or
duplicate candidate does not consume a returned-result slot.
Example
curl -X POST https://www.chab.ai/v1/contacts/domain-search \
-H "Authorization: Bearer CHAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: contacts-domain-search-001" \
-d '{"domain":"example.com","limit":10,"departments":["sales","marketing"],"seniorities":["manager","director"],"include_generic":false}'
Async Response
{
"operation": {
"id": "op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
"status": "queued",
"operation_key": "contacts.domain_search",
"family": "contacts",
"status_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
"result_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/result",
"estimated_credits": 8,
"result_available": false,
"warnings": []
},
"meta": {
"request_id": "req_123",
"credits": {
"estimated": 8,
"reserved": 8,
"currency": "credit"
}
}
}
Credit estimates and reservations are reported on the operation envelope and
response metadata. After the operation becomes terminal,
operation.settlement.final_credits is the authoritative final charge. Result
payloads do not include a separate usage or credit object.
Result
{
"data": {
"result": {
"domain": "example.com",
"contacts": [
{
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Doe",
"full_name": "Jane Doe",
"title": "Sales Director",
"department": "sales",
"seniority": "director",
"organization": {
"name": "Example Inc.",
"domain": "example.com"
},
"confidence": 0.92,
"source_category": "website",
"is_role_address": false,
"is_generic_address": false,
"verification": {
"status": "valid",
"mx_records_found": true,
"smtp_check": true,
"accepts_all": false,
"disposable": false,
"blocked_domain": false
},
"evidence": {
"matched_pattern": true,
"public_profile_seen": false,
"domain_match": true,
"verification_observed": true
},
"warnings": []
}
],
"summary": {
"requested_limit": 10,
"returned": 1,
"deduplicated": 0,
"no_result": false
}
},
"artifacts": [],
"warnings": [],
"result_expires_at": "2026-07-17T09:30:05+00:00"
},
"meta": {
"request_id": "req_123"
}
}
If no matching contacts are found, the operation still succeeds and charges the
fixed price because provider work started. The result contains an empty
contacts array and summary.no_result: true.
When the lookup returns company-wide organization or email-pattern facts, Chab
uses those facts while normalizing each contact. Organization values can remain
populated when an individual contact record does not repeat them. Pattern
evidence is evaluated against each normalized address, so
evidence.matched_pattern is true only when that address follows the known
company pattern.
POST/v1/contacts/email-finder
Finds a likely work email address for one person at a company.
Required Access
- Access: Paid plans that include this family, or free credits (guest trial or verified account) within the free limits.
- Operation family: Contacts
- Scope:
api:contact:write - Credits: 8 credits reserved on acceptance
- Idempotency:
Idempotency-Keyheader required
Request
Lookup by full name:
{
"full_name": "Jane Doe",
"domain": "example.com"
}
Lookup by split name and company:
{
"first_name": "Jane",
"last_name": "Doe",
"company": "Example Inc."
}
Fields:
- Provide either
full_nameor bothfirst_nameandlast_name. - Do not send
full_nametogether withfirst_nameorlast_name. full_namecan be up to 160 characters.first_nameandlast_namecan each be up to 80 characters.- Chab trims name and company values and collapses repeated whitespace. Whitespace-only values are rejected.
- Split names remain a split-name lookup; Chab also derives the normalized
full_nameshown in the operation summary and result lookup. - Provide at least one company selector:
domainorcompany. domainmust be a hostname only. URLs, paths, query strings, and schemes are rejected.companyis optional whendomainis present and can help when a hostname is not known. It can be up to 160 characters.
Example
curl -X POST https://www.chab.ai/v1/contacts/email-finder \
-H "Authorization: Bearer CHAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: contacts-email-finder-001" \
-d '{"full_name":"Ada Lovelace","domain":"example.com"}'
Async Response
The create response has the same operation envelope shape as domain search,
with operation_key: "contacts.email_finder" and an 8 credit
estimate/reservation.
Result
{
"data": {
"result": {
"lookup": {
"full_name": "Jane Doe",
"first_name": null,
"last_name": null,
"domain": "example.com",
"company": null
},
"contact": {
"email": "[email protected]",
"first_name": "Jane",
"last_name": "Doe",
"full_name": "Jane Doe",
"title": "Sales Director",
"department": "sales",
"seniority": "director",
"organization": {
"name": "Example Inc.",
"domain": "example.com"
},
"confidence": 0.9,
"source_category": "company_pattern",
"is_role_address": false,
"is_generic_address": false,
"verification": {
"status": "valid",
"mx_records_found": true,
"smtp_check": true,
"accepts_all": false,
"disposable": false,
"blocked_domain": false
},
"evidence": {
"matched_pattern": true,
"public_profile_seen": false,
"domain_match": true,
"verification_observed": true
},
"warnings": []
},
"summary": {
"no_result": false
}
},
"artifacts": [],
"warnings": [],
"result_expires_at": "2026-07-17T09:30:05+00:00"
},
"meta": {
"request_id": "req_123"
}
}
If no likely email is found, the operation succeeds, contact is null, and
summary.no_result is true.
POST/v1/contacts/email-verify
Checks one email address, or a list of up to 100, and returns normalized verification facts for each address.
Required Access
- Plan: Pro or Scale. Verified free accounts and guest trial API credentials
can start
contacts.email_verifywith free credits while free use is available. - Operation family: Contacts
- Scope:
api:contact:write - Credits: 2 credits per address, reserved on acceptance (200 credits for 100 addresses). Addresses that could not be checked are not charged. Free credits are one-off grants and do not refresh monthly.
- Idempotency:
Idempotency-Keyheader required
Request
{
"email": "[email protected]"
}
Or a list:
{
"emails": ["[email protected]", "[email protected]", "[email protected]"]
}
Fields (send exactly one of the two):
email: an RFC email address, up to 254 characters. Chab trims and lowercases the address before verification.emails: 1 to 100 RFC email addresses, no duplicates. Chab trims and lowercases each one. To check a long list, such as a CSV of 400 leads, send it in requests of 100.
Example
curl -X POST https://www.chab.ai/v1/contacts/email-verify \
-H "Authorization: Bearer CHAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: contacts-email-verify-001" \
-d '{"email":"[email protected]"}'
Async Response
The create response has the same operation envelope shape as domain search,
with operation_key: "contacts.email_verify" and an estimate and
reservation of 2 credits per address.
Result
{
"data": {
"result": {
"email": "[email protected]",
"verification": {
"status": "valid",
"mx_records_found": true,
"smtp_check": true,
"accepts_all": false,
"disposable": false,
"blocked_domain": false
},
"confidence": 0.95,
"source_category": "verification_check",
"evidence": {
"matched_pattern": false,
"public_profile_seen": false,
"domain_match": true,
"verification_observed": true
},
"warnings": [],
"summary": {
"no_result": false
}
},
"artifacts": [],
"warnings": [],
"result_expires_at": "2026-07-17T09:30:05+00:00"
},
"meta": {
"request_id": "req_123"
}
}
A request with emails returns one row per address, in the order sent, and
a count per verdict:
{
"data": {
"result": {
"results": [
{
"email": "[email protected]",
"checked": true,
"verification": {
"status": "valid",
"mx_records_found": true,
"smtp_check": true,
"accepts_all": false,
"disposable": false,
"blocked_domain": null
}
},
{
"email": "[email protected]",
"checked": true,
"verification": {
"status": "invalid",
"mx_records_found": null,
"smtp_check": false,
"accepts_all": false,
"disposable": false,
"blocked_domain": null
}
}
],
"summary": {
"total": 2,
"valid": 1,
"invalid": 1,
"risky": 0,
"unverifiable": 0,
"not_checked": 0,
"no_result": false
},
"source_category": "verification_check",
"warnings": []
}
}
}
Chab checks a batch several addresses at a time and stops after about 45
seconds. Addresses it could not check come back with checked: false and
status unverifiable, are not charged, and a warning names how many there
were. Send those again.
Before the mailbox check, Chab looks up the domain in DNS. When the domain
does not exist or has no mail server (no MX, A or AAAA record), or it
publishes a "null MX" record that says it accepts no email, the address is
invalid right away. Its verification then has mx_records_found: false and
a reason of no_mail_server or domain_accepts_no_mail. These addresses
are charged like any checked address. When the DNS lookup itself fails, Chab
runs the mailbox check as usual.
Verification status values are:
valid: the address appears deliverable.invalid: the address appears undeliverable.risky: the address may deliver but has risk signals such as accept-all behavior.unknown: Chab could not determine a stronger status.unverifiable: verification could not be completed for the address.
Email verification always returns one of these statuses, including
unverifiable, so it does not have a no-result outcome.
When a verification response contains both a detailed status and a legacy coarse result, Chab uses the detailed status.
blocked_domain: true means the remote SMTP server prevented the verification
check. It does not by itself mean the address is invalid; the normalized
verification status remains authoritative.
unverifiable, low-confidence, missing-field, and duplicate-candidate
conditions are returned as structured warnings. Warnings are advisory and do not
change the operation's terminal success status.
Contact Result Fields
Contact records use these normalized enum values:
department:executive,sales,marketing,engineering,support,finance,hr,legal,operations,other, orunknown.seniority:owner,founder,c_level,vp,director,manager,individual, orunknown.source_category:website,public_profile,company_pattern,verification_check, orunknown.evidence.matched_pattern: true only when the normalized address matches a known company email pattern; the presence of a company pattern alone does not make this true.
Boolean flags distinguish shared and role addresses:
is_role_address: true for addresses whose local part is a role or mailbox name, such assupport@.is_generic_address: true for addresses that are generic, shared, or not clearly tied to one person.
Sparse fields are returned as null rather than omitted. When missing data is
important to interpretation, Chab includes a structured field_unavailable
warning.
Domain-search candidates are deduplicated by normalized email address, or by
full name plus organization domain when no email is available. Chab keeps the
highest-ranked candidate, fills only missing fields from duplicates, and emits
one duplicate_candidate warning for each conflicting field whose
higher-ranked value was retained.
Billing and No-Result Behavior
Validation failures, authentication failures, missing scope, missing paid-plan access, insufficient credits, and readiness failures before work starts are not charged. A contact operation that ends in a provider error instead of a result also releases its full hold. Once provider work returns a successful result, the operation settles at the fixed price even when no contact is found.
Idempotent retries with the same Idempotency-Key and byte-identical request
body return the original operation and do not create a second hold.
Errors
Common errors include:
validation_failed: the JSON body is malformed, missing required fields, or contains unsupported fields.api_scope_missing: the key does not includeapi:contact:write.paid_plan_requiredoroperation_family_not_included: the team plan cannot call contact endpoints.insufficient_credits: the team or token budget cannot cover the fixed estimate.provider_unavailable: contact lookup is temporarily unavailable.provider_temporarily_rate_limited: retry after the indicated delay.provider_errororprovider_response_invalid: the operation could not safely produce a normalized result. For email verification, Chab rejects an provider result that omits the verified address or names a different one; it never presents that result as verification of your requested address.
Temporary provider rate caps use provider_temporarily_rate_limited. Provider
usage or readiness exhaustion uses provider_unavailable and is not treated as
an immediately retryable rate cap.
See Errors, Rate Limits, and Pagination for the shared error envelope and retry guidance.