Pay per use
A prepaid balance instead of a monthly plan. Each call takes what it cost off the balance, and every response says what that was. These are the /v2 routes.
First 100 people free, no card. Start free on the pay-per-person page. Accounts on a monthly plan keep using /v1 and are not affected; a plan account that calls /v2 gets 402 with a link to this page.
Rate card#
| What | Price | Charged |
|---|---|---|
| Search scan fee | $0.005 | per scan unit, at least 1 per search |
| Count scan fee | $0.002 | per scan unit, at least 1 per count |
| A person, with email and LinkedIn included | $0.0004 | per person returned |
| Fetch by id (minimum per call) | $0.001 | per call, or the people price if higher |
| Lookup by LinkedIn URL, email or phone | $0.001 | per person matched |
| Lookup where the key is not found | $0.0003 | per key |
| Phone number | $0.0015 | per person who has a phone, found |
Free, and never charged: /v2/meta, /v2/rates, /v2/balance, /v2/usage, /v2/openapi.json, /v2/people/estimate, and every error response. The current list is machine-readable at GET /v2/rates, with no key.
The scan fee#
Every search and count reads part of the database before it can answer, and that reading costs the same whether or not anyone matches. The scan fee covers it: a narrow search is one scan unit ($0.005), a very broad one is a few, and POST /v2/people/estimate tells you the number before you run it for free.
A search is charged scan_units x $0.005, a count scan_units x $0.002. A search that finds nobody is still charged its scan units. A search that would read too much of the database (over 6 GiB) is refused with 400 and costs nothing: add filters and try again.
Worked examples#
| What | Cost | How |
|---|---|---|
| 1,000 people with email and LinkedIn | from $0.405 | scan fee from $0.005, plus 1,000 x $0.0004 = $0.40 |
| One lookup by email or LinkedIn URL | $0.001 | a key not found costs $0.0003 |
| One count | from $0.002 | one scan unit, more for very broad filters |
| One phone number | $0.0015 | charged only for each number found |
About 17% of all records have a phone number, so at that overall rate 1,000 people would return around 170 numbers, about $0.26 at $0.0015. A search can differ from the average.
Endpoints#
All JSON. Send Authorization: Bearer YOUR_KEY. Base URL https://people-api.arihaan.ai/v2.
| Route | What it does |
|---|---|
POST /v2/people/search | Find people by filters. Up to 1,000 a call, cursor paging. |
POST /v2/people/count | Count matches, with the number that have an email, phone or LinkedIn. Optional group_by. |
POST /v2/people/lookup | Find a person by LinkedIn URL, email or phone. Up to 100 keys a call. |
POST /v2/people/batch | Get up to 1,000 people by id. |
POST /v2/people/phones | Phone numbers for up to 1,000 ids. Charged per number found. |
POST /v2/people/estimate | The scan units and scan fee of a search or count. Free. |
GET /v2/meta | Field values (departments, levels, industries, sizes, countries). Free. |
GET /v2/rates | The price list as data. Free, no key. |
GET /v2/balance | Your balance. Free. |
GET /v2/usage | Your usage. Free. |
Search
/v2/people/searchThe filters are the ones of the search API: country, state, city, department, level, title, title_exclude, company, industry, company_size, revenue, has_email, has_linkedin and the rest. Add limit (1 to 1000, default 25) and cursor from the last page.
curl -X POST https://people-api.arihaan.ai/v2/people/search \
-H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" \
-d '{"title": ["vp sales"], "country": ["US"], "has_email": true, "limit": 25}'{
"people": [ { "id": "p_8f3a91c2", "name": "Jordan Patel", "title": "VP of Sales", "...": "..." } ],
"next_cursor": "eyJpZCI6InBfOGYzYTkxYzIifQ",
"billing": {
"card": "payg",
"charge_usd": 0.0150,
"charge_micro": 15000,
"events": { "scan_unit": 1, "person": 25 },
"scan_units": 1,
"est_scan_usd": 0.0002
}
}Count
/v2/people/countSame filters. Returns count, with_email, with_phone, with_linkedin and billing. group_by is optional and returns the top 25 groups.
Lookup
/v2/people/lookupSend one key, {"linkedin_url" | "email" | "phone": "..."}, or up to 100 in a list: linkedin_urls, emails or phones. Keys are normalised before matching: LinkedIn lowercased with the trailing slash removed, email lowercased and trimmed, phone digits only with a leading 1 dropped from 11 digits. A key can match several people. A key with no match costs $0.0003.
{
"results": [
{ "key": "jordan.patel@northwindcloud.example", "matches": [ { "id": "p_8f3a91c2", "name": "Jordan Patel", "...": "..." } ] },
{ "key": "nobody@example.invalid", "matches": [] }
],
"billing": { "card": "payg", "charge_usd": 0.0013, "charge_micro": 1300, "events": { "lookup_hit": 1, "lookup_miss": 1 } }
}Batch and phones
/v2/people/batchSend {"ids": [...]}, up to 1,000, and get the people back. Charged at the people price, with a $0.001 minimum per call.
/v2/people/phonesSend {"ids": [...]}, up to 1,000. Returns [{id, phone, phone_type}] only for people who have a number, and you pay $0.0015 for each one returned. Phone numbers appear nowhere else.
Estimate
/v2/people/estimatefree: not countedSame body as a search or a count. Returns scan_units, est_usd, over_cap and charge_usd_for_scan. Free, and rate limited.
The person#
Phone is not part of this object. email is null when we have none.
{
"id": "p_8f3a91c2",
"name": "Jordan Patel",
"title": "VP of Sales",
"department": "Sales",
"level": "VP",
"company": {
"name": "Northwind Cloud",
"website": "northwindcloud.example",
"industry": "Software Development",
"size": "250-499",
"revenue": "$10-50M"
},
"company_location": { "city": "Austin", "state": "TX", "country": "US" },
"email": "jordan.patel@northwindcloud.example",
"linkedin_url": "http://www.linkedin.com/in/jordan-patel-example"
}country, state and city filters work on it. No email is marked verified: the API returns no verified flag.What a response tells you#
| Where | Meaning |
|---|---|
billing | The card, charge_usd and charge_micro (1 micro = $0.000001), the events charged and the scan_units. charge_usd is always present on a success, 0 when free. |
X-Cost-USD | What this call cost, in dollars |
X-Balance-USD | What is left on your balance after it |
GET /v2/balance returns your balance and is free, like /v2/usage and /v2/meta.
When the balance runs out#
If your balance is below the estimated charge of a call, the API answers 402 before doing any work and charges nothing.
{ "error": { "code": "insufficient_balance",
"message": "Your balance is below the estimated charge for this call. Add funds: https://people.arihaan.ai/app/wallet" } }Errors#
| Status | Meaning |
|---|---|
400 | Invalid request, or a search too broad to run. Nothing is charged. |
401 | Missing or wrong key. |
402 | insufficient_balance, or a plan account calling a pay-per-use route. |
429 | Too many requests. Try again shortly. |
Three honest notes#
- Location is the company headquarters. City, state and country describe where the person’s company is based, not where the person lives. Amazon’s 302,679 people are all in Seattle. The response calls it company_location, and the country, state and city filters work on it.
- No email is marked verified. Emails come from our data sources and are not checked by us. The API does not return a verified flag, and we do not call any email verified.
- A search that finds nobody still pays the scan fee. The database is read either way. An empty result costs the scan fee and nothing for people. Errors, refused requests and the free routes cost nothing.
Also available on#
Apify and treg. Prices on a marketplace are set there and can differ from this page.