Playbooks / Recipe

Turn a list of emails into enriched LinkedIn profiles

Resolve each email to a LinkedIn profile URL with find_linkedin_url_by_email, then enrich that URL with enrich_profile. Two calls, two charges. Neither one is a waterfall endpoint, so both bill on any 2xx — including a lookup that resolves nothing.

Pattern: find_linkedin_url_by_email → enrich_profile

In short: A two-call RichAPI recipe. POST https://api.richapi.ai/api/v1/find_linkedin_url_by_email takes an email address and returns a LinkedIn profile URL. The URL is returned under the literal JSON key "LinkedIn Profile URL" — with spaces and capital letters — inside the data object, not a snake_case key. POST /enrich_profile then takes that URL in the url field and returns the full profile. Neither endpoint is a waterfall endpoint: both bill their flat per-call cost on any 2xx response, including a lookup that resolves nothing. Only email_finder, email_verifier and phone_finder return billed:false on a soft miss. Non-2xx responses never bill. Authentication is the x-api-key header. enrich_profile accepts a LinkedIn URL and does not accept a domain. New accounts get 100 free credits and require no credit card.

Last updated November 4, 2026

Credit math

Worked example at stated counts: 500 emails. find_linkedin_url_by_email 500 calls at 4 = 2,000 credits, charged on all 500 even though only 300 resolve. enrich_profile on those 300 at 1 = 300 credits. Total 2,300 credits for 300 enriched profiles. 4 credits per find_linkedin_url_by_email call, 1 credit per enrich_profile call

ROI math

About 7.7 credits per enriched profile at a 60% resolve rate, and the resolve rate is what moves that number — at 40% the same 500 emails cost 2,200 credits for 200 profiles, about 11 each. Clean the list before you spend. Convert credits at your tier rate on /pricing.

Owned internally by

Whoever owns the CRM backfill — usually RevOps, sometimes a data engineer with a deadline

Best for

Backfilling signup lists, webinar registrations and old CRM records that have an email and nothing else

  1. 01

    Sign up at app.richapi.ai and copy your key.

    100 free credits, no card.

  2. 02

    Strip the obvious dead weight from the list first — role addresses, test accounts, free-mail domains you do not care about. Every one you leave in is a full-price call.

  3. 03

    Call find_linkedin_url_by_email per email and read the result at the key "LinkedIn Profile URL", with the spaces and capitals.

  4. 04

    Call enrich_profile with that URL.

    It takes a LinkedIn URL, never a domain and never an email.

  5. 05

    Write both raw responses to storage before you transform them, so a parsing bug does not cost you the whole run again.

Take these 40 signup emails, resolve each one to a LinkedIn profile,
and enrich the ones that resolve. Tell me the current title and company
for each, and list the emails that did not resolve so I know what I
paid for and got nothing back.

The response key that will eat your afternoon

find_linkedin_url_by_email returns the URL under the literal key "LinkedIn Profile URL". Spaces. Capital letters. Inside data.

Every client library, every ORM habit, every autocomplete in your editor will push you toward linkedin_profile_url, and that lookup returns undefined in JavaScript and raises nothing at all if you used .get() in Python. The call succeeded. You were billed. Your row is empty. Then you spend an hour looking for the bug in your retry logic.

# wrong — no error, no data, full charge
url = resp["data"].get("linkedin_profile_url")   # None, every time

# right
url = resp["data"]["LinkedIn Profile URL"]
// wrong
const url = resp.data.linkedin_profile_url;      // undefined

// right
const url = resp.data["LinkedIn Profile URL"];

Normalise it once, at the edge of your code, and never touch the raw key again. If you are writing an assertion anywhere in this pipeline, make it this one.

Get 100 free credits — no card

Both calls bill, both times

There is no free miss in this chain. find_linkedin_url_by_email and enrich_profile are flat per-call endpoints and they bill on any 2xx, including a response that resolves nothing. The free-miss behaviour belongs to the three waterfall endpoints endpoints — email_finder, email_verifier and phone_finder — and none of them is in this recipe.

On a 500-row run that difference is 800 credits spent on emails that resolved to nobody. It is not a defect, it is the pricing model, and the honest way to work with it is to shrink the input list rather than hope the resolve rate carries you.

What reverse email lookup costs, at stated counts

500 emails in, 300 resolving to a profile.

Step Count Rate Bills on an empty result? Credits
find_linkedin_url_by_email 500 calls, 300 resolve 4 / call Yes 2,000
enrich_profile 300 calls 1 / call Yes 300

Rates used above: 4 credits per find_linkedin_url_by_email call, 1 credit per enrich_profile call.

2,300 credits, 300 profiles, roughly 7.7 credits each. Drop the resolve rate to 40% and the same list costs 2,200 for 200 profiles. The lookup step is four times the price of the enrichment, so every junk row you delete before the run saves four credits and every one you leave in costs four. Per-credit rates vary by tier, so convert on the pricing page.

Where reverse email lookup goes wrong

Role addresses. info@, sales@, support@, careers@. Nobody's LinkedIn profile is attached to a shared inbox, and each one is a full-price call that resolves to nothing. Filter them with a regex before the run, not after.

Personal free-mail addresses. A gmail address resolves far less often than a corporate one. Worth a separate, deliberate batch so you can measure its resolve rate and decide whether it earns its credits, rather than burying it in an average.

Feeding a domain to enrich_profile. It takes a LinkedIn profile URL. A domain, a company page URL or an email will not do, and the failure is not always loud.

Re-running the whole list on retry. A bad deploy that dropped the results does not entitle you to a refund on the second run. Persist the raw response for every call as it lands.

When to run reverse email lookup instead

Going the other direction — you have a profile and need the address — is waterfall email then verify, where the misses are free. If your input is a company rather than a person, bulk enrich without seats covers the volume shape. To wire this into a research agent instead of a batch job, see agent-driven account research. The endpoint pages for email to LinkedIn and person enrichment carry field-level detail, and the Proxycurl comparison covers the migration if that is where your list currently lives. The rest sit on the use-case index.

Reverse email lookup FAQ

Why is the key formatted like that?
It comes back from the source that way and we pass it through rather than silently reshaping a payload. Pin it in one adapter function and move on.

What happens when the email does not resolve?
You get a 2xx with no URL and you are charged for the call. Only email_finder, email_verifier and phone_finder return billed: false on a soft miss. Non-2xx responses never bill, on any endpoint.

Can I batch this?
enrich_profiles_bulk takes up to 50 LinkedIn URNs per call and bills per result. The lookup step has no bulk form today, so it stays one call per email.

How fresh is the enriched profile?
It is fetched live at call time rather than read from a stored index. A profile edited this morning reflects that; a profile nobody has touched since 2021 is 2021 data, and that is the profile's problem rather than ours.

Do I need a credit card?
No. 100 free credits on signup.

Try reverse email lookup: 100 free credits, no card

Run twenty emails through both calls and look at your resolve rate before you commit a list of five thousand. Get 100 free credits

FAQ

Frequently asked

It comes back from the source that way and we pass it through rather than silently reshaping a payload. Pin it in one adapter function and move on.
You get a 2xx with no URL and you are charged for the call. Only `email_finder`, `email_verifier` and `phone_finder` return `billed: false` on a soft miss. Non-2xx responses never bill, on any endpoint.
`enrich_profiles_bulk` takes up to 50 LinkedIn URNs per call and bills per result. The lookup step has no bulk form today, so it stays one call per email.
It is fetched live at call time rather than read from a stored index. A profile edited this morning reflects that; a profile nobody has touched since 2021 is 2021 data, and that is the profile's problem rather than ours.
No. 100 free credits on signup.

More playbooks

Related playbooks

Signal-Based Prospecting: Build an Account List From Jobs, Ads and PostsStart from something a company did this month (a job post, a running ad, a LinkedIn post) and turn it into an account list, then find and verify contacts on it. The signal endpoints bill per result on any 2xx; only the email_finder and email_verifier legs at the end are miss-free.Qualify domains on traffic before you spend on contactsRun similarweb_scraper_sync over a domain list, cut the ones too small or too far off-category to be worth working, then spend finder and verifier credits only on what survives. At 2 credits per result it is the most expensive per-result call in this chain, and it bills on any 2xx including a domain it knows nothing about.Qualify accounts by what they run, then find the peopleDetect a domain's public web technologies with one flat-rate call, drop the accounts that fail the test, and only then spend per-result search credits on finding people. A stack detection is a fit signal, not intent — we sell no intent feed. web_tech_stack bills on any 2xx, including one that finds nothing.Verify before the push, and know exactly which verifications you paid forA gate between enrichment and your sequencer: no row reaches a sending tool without a verification verdict attached. email_verifier is a waterfall endpoint, so the free case is narrow and specific — sources ran and reached no verdict at all. A verdict of invalid, or a verdict of catch-all, is a result and it bills. We do not send email; the gate hands rows to whatever does.