CSV Contact Enrichment - Fill Contact Data in Any Columns
Pricing
from $3.00 / 1,000 contact enricheds
CSV Contact Enrichment - Fill Contact Data in Any Columns
Enrich a CSV or list of rows with work emails, phones, job title and company. Any column names: map them once, every original column comes back unchanged with new columns added. Pay per enriched contact, misses free. Free plan: 100 rows per run. Does not verify mailboxes. No login or cookies.
Pricing
from $3.00 / 1,000 contact enricheds
Rating
0.0
(0)
Developer
Open Enrich
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Features
Share
CSV contact enrichment for any spreadsheet: give rows with any columns, name the ones that hold a LinkedIn URL, email, handle or name plus company domain, and get every row back unchanged with work email, phone, job title and company added. No login, no cookies, no start fee. You pay only for the contacts you receive.
Any column names | Your columns kept as they are | Email, phone, title, company per row | Up to 1,000 rows per run | Misses are free | JSON/CSV export
Not an email verifier. Each email comes with a status (
valid,catch_all,unknown), andunknownis common because no mailbox check is run. Check the list yourself before a campaign.
Pricing and plans
Three events, each charged only for a value you receive. Prices per 1,000 (set on the Pricing tab):
| Event | When it is charged | Free plan | Gold plan |
|---|---|---|---|
contact | A row resolves to a person and is delivered with at least one field you asked for | $3.963 | $2.996 |
email-found | A work email on your company domain is found and added | $0.963 | $0.696 |
phone-found | A phone number is delivered in the row | $39.963 | $29.963 |
Bronze and Silver prices are on the Pricing tab. Higher Apify plans only lower the price. Empty runs, rows that are not found, failed lookups, unreadable rows and notices are free, and there is no start fee. You choose with fields what is looked up, so you are never charged for a phone you did not ask for.
Plan-credit math. The free plan's $5 monthly credit covers about 1,260 contact events, or about 5,190 email-found events, or about 125 phone-found events, all at the Free price.
The free plan
Free Apify accounts get up to 100 rows looked up per run, and as many runs as their Apify credit covers. Nothing is stored on our side. When a list is longer, the first 100 are looked up and one free notice row (reason: "free_plan_limit") says how many rows were not looked up; they are not charged. Run again with the rest, or use a paid Apify plan for no per-run limit.
Keep a run small while you test
limit caps the rows looked up. The default is 25, the maximum is 1,000, and 0 means all rows up to 1,000. Try 2 to 3 rows first, read the output, then scale up.
Quick start: enrich a CSV with email and phone
Turn your CSV into a list of row objects (any CSV-to-JSON tool does it; the header row becomes the keys) and pass it as items.
1. Two rows, auto-detected columns
{"items": [{ "ID": 1, "Name": "Patrick Collison", "Company Website": "stripe.com", "Notes": "met at a conference" },{ "ID": 2, "LinkedIn URL": "https://www.linkedin.com/in/satyanadella", "Company Website": "microsoft.com" }]}
2. Odd column names, with a column map
{"items": [{ "Contact": "Patrick Collison", "Corporate Site": "stripe.com", "Owner": "Sam" }],"columnMap": { "Contact": "fullName", "Corporate Site": "domain" },"fields": ["email", "jobTitle", "company"]}
Bulk contact enrichment: inputs
| Key | Type | Default | What it does |
|---|---|---|---|
items | array of objects | required | One object per CSV row, any column names. Each row needs one strong key: a LinkedIn profile URL, an email, a GitHub, Twitter/X or Facebook handle, or a full name plus a company domain. Rows without one are listed in MISSES. |
columnMap | object | auto-detect only | { "your column": "field" }. Fields: linkedin, email, github, twitter, facebook, fullName, firstName, lastName, domain. Obvious headers (LinkedIn, Email, Name, First Name, Last Name, Domain, Website) are found without it. |
fields | array | ["email", "phone"] | What to add: email, phone, jobTitle, company. Only the picked fields are looked up and charged. |
limit | integer | 25 | Rows looked up. 0 = all rows, up to 1,000. A higher number stops the run with a message before any charge. |
includeAudit | boolean | false | Adds an audit object to each row. |
Any other field stops the run before a lookup with remove unsupported fields: .... An unknown columnMap field or fields value does the same. Nothing is charged.
Which key wins. When a row has several, the order is LinkedIn URL, email, GitHub, Twitter/X, Facebook, then name plus domain. Emails are looked up from the person's name and the company domain in the row, so add a domain column (Website, Domain, Company Domain) when you want email. A row that already has an email keeps it and is not charged for one.
Enrich CSV with emails and phones: output
One row per resolved contact, in input order. Your original columns come first, unchanged. Values we add:
| Key | Type | Meaning, and when it is missing |
|---|---|---|
| (your columns) | any | Every column you sent, same names, same order, same values |
profileUrl | string | Professional profile link of the matched person |
fullName | string | Matched name. Skipped when your row already holds the same name |
email | string | Work email on your domain, lower case. Missing when none was found or no domain was given |
emailStatus | string | valid, catch_all or unknown. Rows with a known-invalid address get no email |
confidence | number | 0-1 from the status: valid 0.95, catch_all 0.6, unknown 0.5 |
phone | string | First phone on file, international format when the source gives one. Missing when none is on file |
jobTitle, company | string | Current role and employer on the profile. Missing when not on file |
audit | object | Only with includeAudit |
If a column already exists. An empty cell with the same header (case and spaces ignored) is filled, so an empty Email column gets the email. A non-empty cell is never overwritten: our value goes to a new <name>Enriched column (for example jobTitleEnriched), and an identical value is not repeated.
{"ID": 2,"Full Name": "Patrick Collison","Company Website": "stripe.com","Notes": "met at a conference","profileUrl": "https://www.linkedin.com/in/patrickcollison","jobTitle": "Cofounder","company": "Arc Institute","email": "patrick.collison@stripe.com","emailStatus": "unknown","confidence": 0.5}
A real row from a test run with fields set to email, phone, jobTitle and company. No phone was on file for this person, so there is no phone and no phone-found charge. The job title and employer come from the profile and can differ from the domain you gave.
Other records in the run
MISSES(key-value store):[{row, input, reason}]for every row that produced no result.rowis the 1-based position in your list. Reasons:no_strong_key,not_found,invalid,nothing_found(resolved, but none of the fields you asked for was found),Upstream HTTP <code>.errors-contact-enrich-csv: lookups that failed for a technical reason, so you can run only those rows again.RUN_SUMMARY: counts, requested fields, stop reason, free-plan status.- Notice rows (
type: "notice") are free:free_plan_limit(list longer than 100 on a free plan),charge_limit_reached(the run's charge limit was hit),invalid-input.
What is NOT returned
- Personal email addresses
- Several alternative addresses per person
- A live mailbox check of the address
- Matches by phone number, street address or company name alone
Reliable results
Our data promise. We work to keep every contact current, and we stand behind it. If a record is outdated, an email bounces or a person has moved on, open the Issues tab with your run link. We review every report and sort it out with you, case by case.
- Misses are free and visible. Every row without a result is in
MISSESwith its row number and a reason. - Your data stays yours. Original columns are returned as they came in; nothing is dropped, renamed or reordered.
- Only addresses on your domain. An email on another domain is never returned as the result.
- Each row is saved as it is delivered. A run that stops keeps what it already produced.
- Typos fail early. An unsupported input field or a limit above 1,000 stops the run before any charge, with one free notice row.
- Check before you send.
emailStatusandconfidenceare signals, not a guarantee.
Use with AI agents (MCP)
This actor runs through the Apify MCP server. Prompt to copy:
"Use b2bdata/contact-enrich-csv with items=[{"Name":"Patrick Collison","Company Website":"stripe.com"}], fields=["email","jobTitle"] and limit=1. Return email, emailStatus and jobTitle."
When to use it. You hold rows with a name, a LinkedIn URL, an email or a handle, and want email, phone, title or company added without losing your columns.
When not to. You hold only company domains (use a domain actor), or you only need to verify emails you already have.
Input contract. items array of row objects; optional columnMap, fields, limit 0-1,000, includeAudit.
Output contract. One row per resolved contact: your columns, then profileUrl, fullName, and the fields you asked for. Deterministic and schema-stable, rows keep input order. Unresolved rows are absent from the dataset and listed in MISSES.
Smoke test. limit: 1 on a well-known person returns one row.
Integrations
- API.
GET /v2/datasets/{datasetId}/items?format=csvreturns the enriched rows as a CSV, your columns first. - Webhook on run success to push rows to your own endpoint.
- n8n, Make, Zapier. Use the native Apify nodes: run the actor, then read the dataset.
- Google Sheets, Airtable, HubSpot, Salesforce. Map
email,phoneandemailStatusback to your fields.
Related actors
b2bdata/email-finder: you only need a work email from a name and a company domain. Openb2bdata/bulk-linkedin-profile-enrichment: you hold LinkedIn URLs and want the full profile row. Openb2bdata/phone-number-finder: you hold LinkedIn URLs and want only people who have a phone. Openb2bdata/email-phone-finder: you have an email and need a phone. Open
FAQ
How do I enrich my CSV with email and phone?
Convert the CSV to a list of row objects, pass it as items, and leave fields at its default (email and phone). Each resolved row comes back with your columns plus the new ones.
Can I enrich a CRM export with work emails if my column names are unusual?
Yes. Add a columnMap such as {"Contact": "fullName", "Corporate Site": "domain"}. Obvious headers are detected without it.
Is this a spreadsheet email finder for any columns? Yes. Any number of extra columns is allowed and all of them come back unchanged.
Can I enrich a lead list with names and company?
Yes, with a full name and a company domain per row. A single name with no domain cannot be matched and is listed in MISSES for free.
Can I use it as a CSV enrichment API for AI agents?
Yes. Call it through the Apify API or MCP with limit: 1. The output is stable and one row per resolved contact.
What do I pay when nobody is found? Nothing. There is no start fee, and misses, failed lookups and notices are free. A row that resolves but has none of the fields you asked for is also free.
Support
Use the Issues tab on this actor's Apify page for bugs, questions and feature requests. We answer within 48 hours on working days. Please include the run ID and a row that shows the problem. Published on Apify by b2bdata as proprietary software. Not affiliated with, endorsed by, or sponsored by any company or person named in the examples above.