TL;DR: POST identity hints, get back enriched fields. Same waterfall, same credit model, programmatic. Most usage looks like { email: "..." } → { phone, social_handles, work_email, company }.
Endpoint
POST /enrichment
Headers:
Authorization: Bearer <UNSTUCK_API_KEY>
Content-Type: application/json
Body:
{
"email": "person@company.com",
"linkedin_url": "https://linkedin.com/in/...",
"company_domain": "company.com",
"channels": ["work_email", "personal_email", "phone", "social_handles"]
}
At least one identity hint required. channels is optional — defaults to all four contact channels.
Identity-only mode
Sometimes you have a name + company and want to discover an email:
POST /enrichment/discover
Body:
{
"first_name": "Chloe",
"last_name": "Walker",
"company_domain": "westmarkrobotics.com"
}
Returns the same response shape. Discovery is slower (the waterfall has to find the contact, not just confirm it) and costs more credits per success.
Response
{
"record_id": "lead_abc123",
"channels": {
"work_email": {
"value": "chloe.walker@westmarkrobotics.com",
"source": "Provider A",
"confidence": 0.94,
"enriched_at": "2026-05-26T14:30:00Z"
},
"phone": null,
"social_handles": {
"value": "https://linkedin.com/in/chloewalker",
"source": "Provider C",
"confidence": 0.88,
"enriched_at": "2026-05-26T14:30:00Z"
}
},
"credits_used": 5
}
null channels mean the waterfall ran but no provider returned a usable value. Per-channel metadata includes source, confidence, and timestamp.
Bulk enrichment
For higher-volume work:
POST /enrichment/bulk
Body:
{
"records": [
{ "email": "..." },
{ "linkedin_url": "..." },
...
],
"channels": ["work_email"]
}
Up to 100 records per request. Returns an array of per-record results. Credit cost is summed across all successful enrichments.
Idempotency
The single-record endpoint is idempotent on (identity, channels). Re-requesting the same record + channels returns cached values; no credits charged. Pass force: true to bypass the cache.