Playbooks · Playbook
Batch enrichment is a machine job. It runs from one service account, on a schedule, with nobody logged in — so paying per seat prices the wrong thing entirely. enrich_profiles_bulk and enrich_companies_bulk bill per record in the list, on any 2xx.
Last updated September 22, 2026
Pattern: one key, one batch endpoint, credits drawn per record — no per-user licensing
Credit math: Worked example at stated counts: 5,000 LinkedIn profile URLs through enrich_profiles_bulk at 1 credit per record = 5,000 credits. The same 5,000 one at a time through enrich_profile is also 1 credit per call, so the saving is in request count and code, not in rate. 800 company URLs through enrich_companies_bulk = 800 credits. 1 credit per result on enrich_profiles_bulk and enrich_companies_bulk, 1 credit per call on enrich_profile and enrich_company
ROI math: Seat pricing charges for people who are not doing the work. Credit pricing charges for records. A quarterly 5,000-record refresh costs 5,000 credits whether one person or nine people touch the pipeline, and nothing is due in the months you do not run it.
Owned internally by: One service account, owned by data engineering or RevOps
Best for: Teams refreshing a CRM on a cadence, platforms enriching on a nightly job, agencies running many clients' data through one pipeline
curl -X POST https://api.richapi.ai/api/v1/enrich_profiles_bulk \
-H "x-api-key: $RICHAPI_KEY" \
-H "Content-Type: application/json" \
-d '{"profiles": [
"https://www.linkedin.com/in/example-one/",
"https://www.linkedin.com/in/example-two/"
]}'
Take the LinkedIn URLs in contacts.csv, send them through the bulk profile
enrichment endpoint in batches, and write the results back to the CSV with a
column recording how many credits the run consumed.
A nightly enrichment job has no users. It has a cron entry, a service account and a queue. Charging per seat for that is charging for a login screen nobody opens. The awkward version of the same problem is that seat pricing punishes you for adding the analyst who reads the output. The pipeline did not get bigger, your bill did. Meanwhile the quarter you skip the refresh entirely, the seats renew anyway. Credits invert that. You pay for records processed. Nine people can watch the job; the job costs the same. Run it twice this quarter and once next and the bill tracks reality. **[Get 25 free credits — no card](https://app.richapi.ai)**
`enrich_profiles_bulk` takes a list of LinkedIn profile URLs. `enrich_companies_bulk` takes a list of LinkedIn company URLs. Both bill per record in the list rather than per request, so batching changes your HTTP overhead and your code, not your rate. Two things worth reading twice. **They take LinkedIn URLs, not domains.** Same as their single-record siblings, [enrich_profile](/api/person-enrichment) and [enrich_company](/api/company-enrichment). If your source data is a domain list, resolving domains to company pages is a step you own, upstream, before the batch starts. We would rather say that plainly than let you discover it on a 5,000-row run. **Neither is a multi-provider waterfall endpoint.** They bill on any 2xx. The miss-free guarantee — a 2xx with `success: false` and `billed: false` costing zero — applies to `email_finder`, `email_verifier` and `phone_finder`, and nowhere else. Reconcile the billed count against the credits drawn on your first real run.
| Run | Count | Rate | Credits | |---|---|---|---| | `enrich_profiles_bulk` | 5,000 profile URLs | 1 / record | 5,000 | | `enrich_companies_bulk` | 800 company URLs | 1 / record | 800 | | `enrich_profile`, one at a time | 5,000 calls | 1 / call | 5,000 | Rates used above: 1 credit per result on `enrich_profiles_bulk` and `enrich_companies_bulk`, 1 credit per call on `enrich_profile` and `enrich_company`. Bulk is not a discount. It is fewer requests, less retry logic and one place to handle failure. Pick it for the engineering, not for a rate that does not change. Convert credits to currency at your tier rate on [the pricing page](/pricing), which varies by package.
An agency running nine clients through one pipeline usually wants nine keys. You can have them. A team can hold multiple named API keys, each revocable on its own, with usage attributed per key and exportable. What that gives you is attribution. You can see which key consumed what, put it on an invoice, and cut off one client's key without touching the rest. What it does not give you is a budget. **There are no per-key credit budgets and no billed sub-accounts.** Credits are pooled at the team. If one key runs away with a bad loop, it spends the pool, and no ceiling on the key stops it. If you need that ceiling, enforce it in your own scheduler — that is the honest answer and it is the one you should plan against.
**Re-enriching what has not changed.** The commonest way to double a bill. Store an `enriched_at` per record and skip anything inside your refresh window. A job that re-processes the full table nightly is paying for stability. **No idempotency on retries.** A batch that fails halfway and gets re-run from the top pays for the first half twice. Checkpoint the batch. **Storing three fields and discarding the response.** Next quarter you want a field you threw away and the only way back is to pay again. Keep the raw payload. **Assuming empty rows are free.** They are not, on these endpoints. See what these endpoints charge, above, and reconcile on your first run.
If you are enriching inside your own product rather than your own CRM, [enrichment backend for platforms](/use-cases/enrichment-backend-for-platforms) is the shape you want. [ICP filter with AI enrich](/use-cases/icp-filter-with-ai-enrich) covers scoring the enriched records afterwards, and [list build and verify](/use-cases/list-build-and-verify) covers building the list that feeds this. For teams migrating off a per-lookup vendor, [the Proxycurl alternative page](/alternatives/proxycurl) has the mapping, and [the use-case index](/use-cases) has the other patterns.
**Do I need a seat per person on my team?** No. Teams hold pooled credits and multiple named keys. Nothing about adding a colleague changes what a record costs. **Can I set a credit limit per client key?** No. Named keys give per-key usage attribution and independent revocation, not budgets or billing isolation. Enforce limits in your own job scheduler. **Does the bulk endpoint cost less per record than the single one?** No. Both are one credit per record at current pricing. Bulk saves requests and code, not credits. `1 credit` **Can I send domains instead of LinkedIn URLs?** Not to these. Both take LinkedIn URLs. There is no public domain-in company enrichment endpoint exposed today. **What happens if a record returns nothing?** It is a 2xx and these endpoints bill on 2xx. Whether an empty record counts toward the billed list count is worth checking on your first run. **Do I need a credit card?** No. 25 free credits on signup.
Push twenty rows through the bulk endpoint and reconcile the credits against the count before you schedule anything. **[Get 25 free credits](https://app.richapi.ai)**