Blog/Sales & enrichment
11 min read

RocketReach Pricing or Per-Contact Lookups: Where the Charge Lands

We paid the base charge for one executive and got an id, a country and a null title. A second provider returned the right job title and zero contacts.

RocketReach Pricing or Per-Contact Lookups: Where the Charge Lands

Copy this line to your agent to look up one contact and see what it costs.

set up https://monid.ai/SKILL.md and use apollo /people/match without the reveal flags first

On 2026-09-17 we looked up one executive, a person whose job title is a matter of public record, through two contact providers in the same minute. The first returned thirty-five fields in which the title was null, the email was null, the email status said unavailable, and the charge still landed. The second returned the correct job title and every contact array empty, along with a set of counters telling us exactly what it had consumed. Neither of those is a malfunction, and both explain more about contact pricing than any published table. This guide runs through Monid, the OpenRouter for agent tools.

What are you actually buying when you buy a contact?

Not a contact. A lookup, and then separately the right to see each class of thing the lookup found.

The three layers

The match. Does this person exist in the index, and can the provider tie your name and company to a record. This is the layer that gets charged first and the one people forget is a product.

The reveal, by class. A work email, a personal email and a mobile number are three different purchases on most providers, priced differently, because they cost the provider different amounts to hold and carry different risk.

The profile. Title, seniority, employer, history. Often bundled with the match, sometimes the only thing you get.

A seat-and-credit product like RocketReach wraps all three in a monthly allowance, which is why a pricing page shows you a number of lookups rather than a price per field. We do not resell RocketReach and nothing here measures it. What the API layer does is make the three separate again, and once they are separate you can see which one you are paying for.

Why that matters for a pricing question

Because the honest answer to "what does a contact cost" is a conditional. It depends on whether the match succeeded, on which class of contact you asked to see, and on whether the thing you asked for actually came back. The two runs below are that conditional, measured.

📖 See also People Data Labs, Apollo, ZoomInfo: Which Should You Actually Buy?

What does the base charge get you?

On our run: an identifier, an employer identifier, a country, and eleven nulls.

The call

apollo/people/match with a first name, a last name and a company domain, no reveal flags set, 7.2 seconds:

{
  "id": "6aac55f4…",
  "first_name": "Ryan",
  "last_name": "Gellert",
  "organization_id": "54a1273b…",
  "country": "United States",
  "title": null,
  "email": null,
  "email_status": "unavailable",
  "linkedin_url": null,
  "seniority": null,
  "departments": [],
  "city": null
}

Thirty-five keys in the object. The ones that would make it useful were null. And this is documented behaviour rather than a fault: the endpoint's own pricing note says it bills the base credit when it can attach the name to a known company, even with no email or title. That is precisely what happened, and it is the single most important sentence on any contact provider's pricing page, whether or not it appears there.

The same person, the other provider

contactout/v1/people/enrich/work-email with a full name and a company array, 2.4 seconds:

{ "status_code": 200,
  "profile": {
    "full_name": "…", "headline": "Chief Executive Officer at Patagonia",
    "industry": "Retail", "url": "https://www.linkedin.com/in/…",
    "company": { "name": "Patagonia", "domain": "patagonia.com",
                 "linkedin_company_id": 665858 },
    "email": [], "work_email": [], "personal_email": [],
    "phone": [], "github": [], "twitter": [] },
  "work_email_units": …, "phone_units": …, "search_units": … }

The title the first provider left null came back correct here. Every contact array came back empty. And three counters at the top level report consumption by class: work email units, phone units, search units.

What the pair tells you

One provider charged for a match and could not describe the person. The other described the person correctly and held back every contact. Same person, same minute, two different halves of the job, and each billed for the half it did.

The meter in the body is the useful feature. A response that tells you what it just consumed, split by contact class, is a response you can build a budget on. The same pattern appeared on the availability flags measured in the prospecting guide: providers are usually honest about what they have, in a field, if you read the field.

How do you control per-contact cost on one key?

Four steps, and the first one is the one most pipelines skip.

For agents

Grab an API key at app.monid.ai, then paste this to your agent and hand it the key:

set up https://monid.ai/SKILL.md

It learns the whole discover, inspect, run workflow itself. More in the agent quickstart.

For humans

npm install -g @monid-ai/cli
monid keys add -k <your-api-key> -l main

Step 1. Read the tier structure before the first call

monid inspect -p apollo -e /people/match

The pricing block spells out the base, each conditional tier, the flag that triggers it and whether the flag alone charges. On this endpoint it also says a no-match consumes nothing, which changes how aggressively you can try.

Step 2. Match without reveal flags first

What it does. Establishes whether the person is in the index at all, at the base rate, before you buy anything.

The endpoints. apollo/people/match, tiered, takes first_name, last_name, domain and other identifiers as query params.

monid run -p apollo -e /people/match \
  --query '{"first_name":"…","last_name":"…","domain":"example.com"}'

What comes back. The person object, and crucially email_status. On our run it read unavailable, which is the endpoint saying do not bother spending on a reveal here.

Step 3. Reveal only the class you need

Set reveal_personal_emails when you will actually send a personal email. Set reveal_phone_number only where a call is the plan, because that tier is the expensive one and the next section is about why.

Step 4. Read the meter

contactout/v1/people/enrich/work-email returns work_email_units, phone_units and search_units in the body. Log them. A per-class consumption count on every response is a better cost model than any estimate you can build from a pricing page.

Give this to your agent

$Set up https://monid.ai/SKILL.md, and then use Monid to match these 200 people without any reveal flags, drop everyone whose email_status is unavailable, then reveal work emails only for the remaining ones and tell me the total units consumed.

📖 See also Wire Up ICP Prospect Search with People Data Labs

Why is a phone number the expensive field?

Because on one provider it costs eight times what a personal email costs, in credits, and the provider is explicit about when that charge applies.

The structure

From the endpoint's own pricing block: the base is charged always. Personal emails add one credit when the reveal flag is set. A mobile phone adds eight credits, and only when a mobile number is actually returned. The flag alone never charges.

Three things follow from that

The ratio is the design constraint. One phone reveal is eight personal email reveals. A pipeline that sets the phone flag by default on every row has multiplied its bill by a factor it never chose.

Pay on delivery is the good version. Charging only when a number actually comes back is the fair form of this, and it means setting the flag speculatively on a list where coverage is thin costs nothing on the misses. In the prospecting guide, a free search told us seven rows in a hundred had a phone at all, which is exactly the number that should decide whether you set that flag.

A no-match is free, a partial match is not. This is the asymmetry to design around. If the provider cannot find the person, you pay nothing. If it finds a record and the record is thin, you pay the base for an id and a country. The failure mode that costs money is the near miss, not the miss.

What it means for comparing vendors

A seat product quotes you lookups per month and hides this structure inside the word "lookup". A per-call product exposes it and lets you spend nothing on the classes you will not use. Neither is cheaper in the abstract. The one that is cheaper for you depends on the ratio of matches to reveals in your own list, and you can measure that ratio for the price of the base tier before committing to either.

Which endpoint should I use for which job?

EndpointWhat it doesInputOutputBest forBilling
apollo/people/matchMatch a person, optionally revealfirst_name, last_name, domain, reveal flagsPerson object, email_statusTesting existence cheaply firstTiered, base plus per-class reveal
contactout/v1/people/enrich/work-emailProfile plus work emailfull_name, company arrayProfile, contact arrays, unit countersReading the meter per classTiered, base always
contactout/v1/people/enrich/personal-emailSame, personal address classIdentifier mixProfile, contact arraysWhen personal is the channelTiered, base always
ploid/enrichRefresh a known LinkedIn identityLinkedIn identityFresh profileKeeping an existing record currentTiered, varies
hunterio/multi-domain-searchPopulation with existence flagsDepartment, seniority, sizeRedacted rows with flagsSizing before spending anythingFree

Every row was verified with monid inspect on 2026-09-17. The table gives billing shape rather than figures, because shape drives design and current numbers live on monid.ai/tools.

The last row is in the table because it is the cheapest way to answer the question that decides all the others: how many of these people have the thing you are about to pay to reveal.

When is a seat cheaper than per-call?

Four cases, and they are ordinary.

Your team browses. Reps who open a tool, search, look at a person and decide are using an interface, and a seat with a monthly allowance is the right shape for that. An API does not make a person faster at reading a profile.

Your volume is steady and high. A fixed monthly allowance beats variable per-call spend once you reliably consume most of it. The crossover is arithmetic, and the honest way to find it is to run a month of real lookups on a per-call route and compare, which costs you the base tier and nothing else.

You need the exports and the interface features. Saved searches, list building, browser extensions, CRM sync. Those are seat products and per-call endpoints do not carry them.

You cannot tolerate variance. A finance team that needs one number per month will prefer a seat even at a worse unit rate. That is a legitimate reason and not a technical one.

And the disclosure: this is Monid's blog and we resell every endpoint measured here. The central finding is that we charged for a lookup that returned a null title and a null email, which is not flattering, and the recommendation that follows is to match without reveal flags and buy fewer reveals, which is a recommendation to spend less with us.

Conclusion

A contact does not have a price. A match has a price, and then each class of contact has its own, and the gap between them is wide: eight to one between a mobile number and a personal email on one provider. On 2026-09-17 we paid a base charge for an executive and received an identifier, an employer identifier, a country and eleven nulls, exactly as that endpoint's own pricing note says it will when a name attaches to a known company without an email or a title. A second provider returned the correct job title, every contact array empty, and a set of counters reporting what it had just consumed.

What matters more than the vendor is the order and the flags. Match first without reveals, read email_status before spending, set the phone flag only where a call is genuinely the plan, and log the unit counters that come back in the body. Those four habits change the bill more than any choice between providers does.

Free next step: run monid inspect -p apollo -e /people/match and read the pricing block, including the sentence about what happens on a partial match. It is the clearest statement of contact pricing we have found anywhere, and it costs nothing to read. Start at monid.ai.

FAQ

Are credits or per-call billing better for contact lookups?

They are the same model wearing different clothes, and the difference that matters is visibility. A credit allowance hides the per-class structure inside one monthly number, so a pipeline that reveals mobile numbers by default burns the allowance eight times faster than one that reveals personal emails, and nothing in the interface says so until the allowance is gone. Per-call billing exposes the tiers and lets you spend zero on classes you never use. If your usage is steady and you consume most of an allowance, credits are simpler. If it is bursty or heavily weighted to one contact class, per-call is both cheaper and easier to reason about.

Should you have to pay for a partial match?

You will, on most providers, and the rule is usually documented if you look. The endpoint measured here charges the base when it can attach your name to a known company, even when it returns no email and no title, and charges nothing at all when it cannot match the person. That asymmetry means the expensive failure is the near miss, not the miss. Design for it by matching in bulk without reveal flags, treating email_status of unavailable as a stop signal, and never letting a partial record flow into a reveal call.

Why do mobile phone numbers cost more than emails?

Because they are harder to source, they decay differently, and they carry more regulatory risk for the provider that supplies them. On the endpoint measured here a mobile reveal is eight credits against one for a personal email, an eight to one ratio, and it is charged only when a number is actually returned rather than when the flag is set. That last detail is the useful one: setting the flag on a list with thin phone coverage costs nothing on the rows that come back empty, so the ratio only bites on success. Check coverage on a free population search before you decide phone is your channel.

How do you estimate contact spend before committing?

Run the cheap layers first. A free population search tells you how many of your targets exist and which contact classes they have at all. A base-tier match on a sample of a few hundred tells you your real match rate and how many come back with an unavailable email status. Multiply out from those two numbers rather than from a vendor's per-lookup figure, because the vendor number assumes every lookup succeeds and yours will not. Then log the unit counters that providers return in the response body, and after one week you have a cost model built from your own list instead of someone's pricing page.

Last updated September 2026.

rocketreach pricingrocketreachcontact lookup apipeople enrichment pricingcredits