Enrich
Tiered enrichment for a company, person, or topic - a cached brief instantly, first-party evidence on a miss, and the full fused brief on demand
POST /enrich/company / /enrich/person / /enrich/topic return intelligence on one subject fast by default: a fresh cached brief comes back instantly; on a cache miss you get your own first-party conversation evidence in a bounded read while the full web + LinkedIn + Crunchbase fusion rebuilds in the background (refresh_enqueued: true). Pass mode: "full" when you would rather block for the complete fused brief — including the market-vs-customers divergence map — inline.
Reach for it for call prep, outreach personalization, account research, topic scoping — any "tell me about X" where you want something grounded now and the deep brief soon.
| Subject | Operation | REST | MCP (enrich tool) | Scope |
|---|---|---|---|---|
| Company (by domain) | enrich.company | POST /enrich/company | action company | data:read (+ external_search:execute for the paid tiers) |
| Person (by LinkedIn URL or email) | enrich.person | POST /enrich/person | action person | same |
| Topic (by term) | enrich.topic | POST /enrich/topic | action topic | same |
The tier ladder
- Tier
cached— a brief you (or a background refresh) already paid for, served from the store. Company briefs stay fresh for ~7 days, person and topic briefs ~14; the response carriescaptured_atso you can judge staleness yourself, plus theartifact_idbacking it. - Tier
first_party— on a miss, a bounded read over your own corpus: who has talked to this account, what they said, what your customers say about this topic. It answers in seconds because it never leaves your tenant — and it is evidence generic enrichment tools do not have. - The background refresh — on that same miss, the full composite is enqueued behind the scenes (
refresh_enqueued: true), so a later call for the same subject lands on tiercached. First call seeds; second call feasts. mode: "full"— run the synchronous fused composite inline and return its brief (tier: "full"). This is the deep, slow call — use it when you are willing to wait.
The paid tiers (the background refresh and mode: "full") require the external_search:execute scope and degrade instead of failing: a key without it still gets cache + first-party evidence, with refresh_omitted: "missing_scope" telling you why no refresh was queued.
Company — by domain
curl -X POST "https://app.amdahl.co/api/platform/v1/enrich/company" \
-H "X-API-Key: $AMDAHL_KEY" \
-H "Content-Type: application/json" \
-d '{ "domain": "stripe.com", "name": "Stripe" }'Over MCP, the enrich tool's company action:
{ "action": "company", "domain": "stripe.com", "name": "Stripe" }domain is required (it is the cache key); name is optional and sharpens both the evidence read and the full fan-out.
Cache hit — the stored brief, instantly:
{
"success": true,
"tier": "cached",
"brief": { "summary": "…", "sections": { "positioning": "…", "recent_signals": "…" }, "citations": ["…"], "divergence_map": { "internal_only": ["…"], "market_only": ["…"] } },
"artifact_id": "a91f…",
"captured_at": "2026-07-18T02:11:40Z",
"refresh_enqueued": false
}Cache miss — your first-party evidence now, the rebuild queued:
{
"success": true,
"tier": "first_party",
"evidence": {
"matched_count": 23,
"utterances": [
{ "text": "we're consolidating vendors this quarter…", "speaker_type": "external", "interaction_id": "int_4812…", "relevance": 0.86 }
],
"narrative_facts": [],
"entity_lifts": [],
"call_fingerprints": [],
"aggregates": { "…": "…" }
},
"refresh_enqueued": true
}evidence is the bounded internal-evidence envelope — ranked utterances plus, when your corpus supports them, narrative_facts, entity_lifts, and per-call call_fingerprints. An account with no history returns the empty envelope (matched_count: 0), not an error.
refresh_enqueued: true means the full composite is rebuilding in the background — re-call the same subject later and you will land on tier: "cached". There is no promised completion time; treat it as "soon", and poll by simply re-calling.
Person — by LinkedIn URL or email
A bare name is refused (invalid_argument) — a name cannot be resolved to one person, and a name-keyed cache would poison lookups. Anchor on linkedin_url (preferred — it is the cache key) or email:
curl -X POST "https://app.amdahl.co/api/platform/v1/enrich/person" \
-H "X-API-Key: $AMDAHL_KEY" \
-H "Content-Type: application/json" \
-d '{ "linkedin_url": "https://www.linkedin.com/in/example-person/", "name": "Jordan Lee" }'{ "action": "person", "linkedin_url": "https://www.linkedin.com/in/example-person/", "name": "Jordan Lee" }An email-only call works, but skips the cache tier by construction (the person-brief cache keys on linkedin_url) — it goes straight to first-party evidence (your calls and threads that mention them), with the deep-profile refresh queued behind it.
Topic — by term
The topic brief keys on the verbatim term; the first-party tier reads what your customers say about it (external speakers by construction), so even the fast answer carries the internal half of the divergence story:
curl -X POST "https://app.amdahl.co/api/platform/v1/enrich/topic" \
-H "X-API-Key: $AMDAHL_KEY" \
-H "Content-Type: application/json" \
-d '{ "topic": "AI SDRs" }'{ "action": "topic", "topic": "AI SDRs" }mode: "full" on a topic runs the whole divergence-map synthesis inline — market story vs. your customers' story, with the disagreements called out — the long call worth making when the topic is the deliverable.
A prompt to hand an agent
Tiered enrichment, fast path first — use the enrich tool.
Enrich: {company {domain} | person {linkedin_url or email} | topic "{term}"}.
Start in fast mode. Tell me which tier answered (cached / first_party), and:
- if cached: summarize the brief and give me captured_at so I know how fresh it is;
- if first_party: give me the strongest first-party evidence verbatim, confirm
whether refresh_enqueued is true, and re-check the cache before we finish.
Only use mode "full" if I explicitly say I'm willing to wait for the deep brief.Variations
- Block for the deep brief:
mode: "full"returnstier: "full"with the complete fused brief inline. Requiresexternal_search:execute; without it the call degrades to the fast path withrefresh_omitted: "missing_scope"instead of erroring. - Warm the cache ahead of a meeting block: fast-enrich tomorrow's accounts this afternoon; each miss queues a refresh, so by meeting time the same calls land on
tier: "cached". - Read-only key: everything still works on
data:readalone — you get cache hits and first-party evidence;refresh_omitted: "missing_scope"just tells you no background rebuild was queued (so a cold subject stays on the first-party tier until a scoped caller warms it). - Batch politely: enriching a list (the expansion motion) is exactly what fast mode is for — N quick tiered calls now, the deep briefs backfilling behind you.
Tips
- Branch on
tier, render accordingly.cached→ a brief withcaptured_at;first_party→ verbatim evidence plus a "full brief refreshing" note;full→ the fused brief. Same envelope every time. refresh_enqueued: falseon a miss means look atrefresh_omitted.missing_scopeis the usual reason; it is a degradation, not a failure.- Anchor people on identifiers, not names.
linkedin_urlgets you the cache tier;emailgets first-party resolution; a bare name gets a typed refusal by design. - The first-party tier is not a consolation prize. "What this account said to us" is the half of the brief no external tool can produce — often it is the more useful half for a rep.
See also
- Lookalike — find which accounts to enrich (nearest neighbours to your best wins).
- Endpoints overview — the whole surface, prerequisites, and the expansion motion.
- Chat — when the brief needs judgment on top of retrieval.