Playbooks · Recipe
Two calls. enrich_company returns the facts, ai_enrich runs your scoring prompt over those facts and returns structured JSON. Both bill on a 2xx, including a 2xx where the model says it doesn't know, so the filter is only as honest as the enrichment feeding it.
Last updated September 22, 2026
Pattern: enrich_company → pass the returned fields into ai_enrich as context → get a structured verdict back → keep, drop, or route. Score before you spend anything on contact data.
Credit math: Scoring 1,000 accounts: enrich_company at 1 credit per call × 1,000 = 1,000 credits, plus ai_enrich at 2 credits per call × 1,000 = 2,000 credits. Total 3,000 to reduce 1,000 accounts to, say, 240. Running email_finder at 5 credits per call on all 1,000 instead would have cost more than the filter and produced a worse list.
ROI math: The filter pays when the drop rate is high. At a 25% pass rate you avoided 750 finder calls; at a 90% pass rate your ICP definition was never the bottleneck and you should skip this page. Measure the pass rate on 100 accounts before you run it on 10,000. Credit tiers at /pricing.
Owned internally by: Whoever owns the ICP definition. Usually RevOps, occasionally the founder, never the intern.
Best for: Teams whose ICP rule is real but not expressible as a filter: 'sells into regulated healthcare', 'has an in-house data team', 'runs a channel motion'.
# Call 1 — the facts. enrich_company takes a LinkedIn company page
# URL, not a domain. Bills on a 2xx, thin payload included.
curl -s https://api.richapi.ai/api/v1/enrich_company \
-H "x-api-key: $RICHAPI_KEY" \
-H "content-type: application/json" \
-d '{"url": "https://www.linkedin.com/company/acme/"}'
# Call 2 — the judgement. Feed the enrichment output in as context
# and demand structured output you can branch on.
curl -s https://api.richapi.ai/api/v1/ai_enrich \
-H "x-api-key: $RICHAPI_KEY" \
-H "content-type: application/json" \
-d '{
"provider": "",
"output_type": "json",
"temperature": 0,
"system_prompt": "You score B2B accounts. If the supplied facts do not support a judgement, return fit \"unknown\". Never infer from the company name alone.",
"prompt": "Company: {{name}}. Industry: {{industry}}. Headcount: {{headcount}}. Specialties: {{specialties}}. Description: {{description}}. Does this company sell software into regulated healthcare?",
"context": {
"name": "Acme Health",
"industry": "Hospital & Health Care",
"headcount": "210",
"specialties": "EHR integration, HL7, claims",
"description": "..."
},
"output_schema": {
"type": "object",
"properties": {
"fit": {"type": "string", "enum": ["yes", "no", "unknown"]},
"evidence": {"type": "string"},
"confidence": {"type": "number"}
}
}
}'
Write the ICP rule as a question with three possible answers: yes, no, unknown.
A rule that can only answer yes or no will answer yes when it has nothing.
Enrich first.
ai_enrich has no data of its own; it reasons over the context you hand it, and an empty context produces a confident guess.
Set temperature to 0 and output_type to json with an output_schema.
You are branching on this value in code; you do not want prose.
Force an unknown path in the system prompt and honour it downstream.
Unknown means 'a human looks at it', not 'treat as no'.
Calibrate on 100 accounts you already have an opinion about.
If the model disagrees with you on more than a handful, the prompt is wrong, not the accounts.
Only then run the finder chain on the survivors, in the order /use-cases/list-build-and-verify sets out.
Some ICP rules fit in a filter. Headcount between 50 and 500, in the UK, in software. `people_search` handles that and you don't need this page. The rules that matter usually don't fit. "Sells into regulated healthcare." "Has an in-house data team." "Runs a channel motion rather than direct." Those live in a company description, a specialties list and a careers page, and a human reading three tabs can answer them in ten seconds. `ai_enrich` is how you get that ten seconds applied to a thousand accounts.
**Call one: `enrich_company`**, 1 credit per call. It takes a LinkedIn company page URL, not a domain, which catches everybody once, and returns the facts: industry, headcount, specialties, description. **Call two: `ai_enrich`**, 2 credits per call. It takes a `prompt` with `{{placeholder}}` slots, a `context` object supplying those values, an optional `system_prompt`, a `temperature`, and `output_type` with an `output_schema` when you want JSON back. The important thing about the second call is what it doesn't have: any data. `ai_enrich` is a reasoning step over context you supply. It is not a lookup, it is not a search, and it does not know anything about the company except what you put in the request body. Call it without enrichment and you get a model's recollection of a brand name, dressed as a score. The `provider` field selects which model family runs the prompt. The accepted values are in the live OpenAPI spec. We don't publish a roster on a marketing page, for the same reason we don't publish the enrichment provider list: it changes.
You are going to branch on this answer in code, which means you need a value, not a paragraph. Set `output_type: "json"`, supply an `output_schema`, and set `temperature` to 0 so the same account scores the same way on Tuesday and Thursday. Three fields are enough: a verdict, the evidence it used, and a confidence number. The evidence field is the one people leave out and then miss, because when you're calibrating the prompt it tells you whether the model read the specialties list or invented something.
`enrich_company` returns something for a company with a sparse LinkedIn page: a name, an industry, no description, no specialties. It bills, because it's not a multi-provider waterfall endpoint and a 2xx is a 2xx. You pass that near-empty object into `ai_enrich`, which is obliged to produce an answer, and it produces one from a company name and an industry label. That row now looks identical to a properly-scored row in your table. It has a verdict and a confidence number and no indication that the model was reasoning over four words. Two guards. First, check the enrichment payload before the second call and skip `ai_enrich` when the fields you need are empty. The skip saves 2 credits per call and prevents a fake score. Second, make `unknown` a real output and make the system prompt insist on it when the evidence is missing. A filter that can say "I don't know" is worth more than one that's confidently wrong 8% of the time, because you can route unknowns to a human and you cannot route a wrong yes anywhere. And remember the billing: both calls charge on a 2xx. An `ai_enrich` response saying "unknown" costs the same as one saying "yes". The only genuinely free misses in the catalog are on `email_finder`, `email_verifier` and `phone_finder`.
This is a scoring step, not an intent product. It tells you whether an account matches a description you wrote. It says nothing about whether they're buying, and there is no intent data behind it. There's also no UI for this: no scoring screen, no model settings page, no place to see the prompt's outputs side by side. You write the prompt, you store the verdicts, you look at them in your own tooling.
**Which model is behind `ai_enrich`?** The `provider` field picks a family and the spec carries the accepted values. We don't name them on marketing pages, and you shouldn't build a hard dependency on one either. Pin `model` explicitly if you need reproducibility across time. **Can it look things up itself?** There's a `use_web_search` flag on the request, which changes the behaviour and the answer quality. Treat it as a different thing from enrichment: it's the model searching, not our retrieval, and it does not replace call one. **Why not just score from the domain?** Because then you're testing the model's memory of a brand, not the company. Every credible answer here comes from the facts in `context`. **Does a bad score cost me?** It costs the same as a good one. `ai_enrich` bills on a 2xx regardless of the verdict, which is why the calibration run on 100 accounts matters before the run on 10,000. **Do I need a card?** No. 25 free credits on signup will run this chain over roughly eight accounts, which is enough to see whether your prompt works.
[company enrichment](/api/company-enrichment) for the enrichment call, [use cases](/use-cases) for the rest of the plays, [list build and verify](/use-cases/list-build-and-verify) for what happens to the accounts that pass, [signal based prospecting](/use-cases/signal-based-prospecting) for building the input list from activity rather than a filter, and [enrichment backend for platforms](/use-cases/enrichment-backend-for-platforms) if the scoring lives inside your own product. Tiers on [pricing](/pricing). **25 free credits, no card.** Score eight accounts you already have an opinion about and see if the model agrees.