> Reverse Contact API documentation. This is the Markdown copy of https://docs.reversecontact.com/use-cases/find-a-person
> Every page is listed at https://docs.reversecontact.com/llms.txt, every endpoint with its credit cost and status at https://docs.reversecontact.com/catalog.json

# Find a person from an email, a name or a profile URL

> Find a person from an email, a name and company, or a Social profile URL with the API. Compare cached and live profiles, code examples and credits.

- Last verified: 2026-11-04

Find a professional profile from an email address, a full name with a company, or a Social profile URL. Enrich and cached Fetch return the result in the response. Use Live to fetch fresh data in the background.

## Which endpoint

| Input you have | Endpoint | Cost | Mode |
| --- | --- | --- | --- |
| Email, or name with a company | [Enrich profile](https://docs.reversecontact.com/endpoints/enrich-person) | 2 credits when found. A 404 is free | Synchronous |
| Social profile URL or person id | [Person profile](https://docs.reversecontact.com/endpoints/fetch-profile) | 1 credit when found in the cache. A 404 is free | Synchronous |
| Social profile URL or person id, with a stale or missing cache | [Person profile live](https://docs.reversecontact.com/endpoints/fetch-profile-live) | 2 credits when the job is created | Asynchronous |

## How it works

Set `RC_API_KEY` to your [API key](https://docs.reversecontact.com/authentication). Install the [TypeScript SDK](https://docs.reversecontact.com/sdk/javascript), [Python SDK](https://docs.reversecontact.com/sdk/python) or [CLI](https://docs.reversecontact.com/guides/cli) for your chosen example. The cURL live example also uses `jq`. Choose either the email lookup or the URL fetch, depending on your input.

### Find the person behind an email

Send the email to Enrich profile and read `data.person`. If no person matches, you get HTTP `404`, or `null` / `None` in the SDKs.

To search by name, replace `email` with `firstName: "Jane"`, `lastName: "Doe"` and `companyDomain: "acme.com"`. In Python, use `first_name`, `last_name`, `company_domain`. In the CLI, use `--first-name Jane --last-name Doe --company-domain acme.com`.

**Code Examples**

```bash [cURL]
curl --fail-with-body -sS -X POST https://api.reversecontact.com/v2/enrich/persons \
  -H "Authorization: Bearer $RC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "jane.doe@acme.com"}'
```
```typescript [TypeScript SDK]
import ReverseContact from "@reverse-contact/sdk";

const client = new ReverseContact({ apiKey: process.env.RC_API_KEY });

const result = await client.enrich.person({ email: "jane.doe@acme.com" });
if (result === null) {
  console.log("No confident match: nothing was charged");
} else {
  const { person } = result.data;
  console.log(person?.firstName, person?.lastName, person?.currentCompanyName);
}
```
```python [Python SDK]
import os

from reversecontact import ReverseContact

with ReverseContact(api_key=os.environ["RC_API_KEY"]) as client:
    result = client.enrich.person(email="jane.doe@acme.com")
    if result is None:
        print("No confident match: nothing was charged")
    elif result.data is not None and result.data.person is not None:
        person = result.data.person
        print(person.first_name, person.last_name, person.current_company_name)
```
```bash [CLI]
rc enrich person --email jane.doe@acme.com
```

### Use the profile URL when you have one

If you already have the Social profile URL, call Person profile and read the profile directly from `data`, including `firstName`, `lastName` and `currentPosition`. You can also send the `id` from a previous response instead of `url`.

**Code Examples**

```bash [cURL]
curl --fail-with-body -sS -X POST https://api.reversecontact.com/v2/fetch/persons \
  -H "Authorization: Bearer $RC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.social.com/in/janedoe"}'
```
```typescript [TypeScript SDK]
import ReverseContact from "@reverse-contact/sdk";

const client = new ReverseContact({ apiKey: process.env.RC_API_KEY });

const result = await client.fetch.person({ url: "https://www.social.com/in/janedoe" });
if (result === null) {
  console.log("Profile not found: nothing was charged");
} else {
  console.log(result.data.firstName, result.data.lastName);
}
```
```python [Python SDK]
import os

from reversecontact import ReverseContact

with ReverseContact(api_key=os.environ["RC_API_KEY"]) as client:
    result = client.fetch.person(url="https://www.social.com/in/janedoe")
    if result is None:
        print("Profile not found: nothing was charged")
    elif result.data is not None:
        print(result.data.first_name, result.data.last_name)
```
```bash [CLI]
rc fetch person --url https://www.social.com/in/janedoe
```

### Refresh a stale or missing profile

You can use Live when the cached profile is too old or a cached fetch returns `404`. To decide based on the profile's age, [check profile freshness](https://docs.reversecontact.com/use-cases/keep-profiles-fresh) first. Save the job id, then poll until the job succeeds or fails. A successful job returns the profile in `data.result`.

**Code Examples**

```bash [cURL]
curl --fail-with-body -sS -X POST https://api.reversecontact.com/v2/fetch/persons/live \
  -H "Authorization: Bearer $RC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.social.com/in/janedoe"}' > live-job.json
WEBHOOK_ID=$(jq -er .data.webhookId live-job.json)
printf 'Save this job id: %s\n' "$WEBHOOK_ID"

while :; do
  result=$(curl --fail-with-body -sS --max-time 30 \
    "https://api.reversecontact.com/v2/webhooks/$WEBHOOK_ID?wait=20" \
    -H "Authorization: Bearer $RC_API_KEY") || break
  case "$(printf '%s' "$result" | jq -r '.data.status')" in
    succeeded) printf '%s' "$result" | jq '.data.result'; break ;;
    errored) printf '%s' "$result" | jq '.data | {errorCode, creditsConsumed}'; break ;;
    created|in_progress) sleep 2 ;;
    *) printf '%s\n' "$result"; break ;;
  esac
done
```
```typescript [TypeScript SDK]
import ReverseContact, { JobFailedError } from "@reverse-contact/sdk";

const client = new ReverseContact({ apiKey: process.env.RC_API_KEY });

const job = await client.fetch.personLive({ url: "https://www.social.com/in/janedoe" });
console.log("Save this job id:", job.id); // resume after a restart with client.jobs.wait(id)

try {
  // Long polls until the job ends, 30 minutes at most by default.
  const done = await job.wait();
  console.log(done.data.result?.firstName, done.data.result?.lastName);
} catch (error) {
  if (error instanceof JobFailedError) console.log("Job failed:", error.errorCode, "credits:", error.creditsConsumed);
  else throw error;
}
```
```python [Python SDK]
import os

from reversecontact import JobFailedError, ReverseContact

with ReverseContact(api_key=os.environ["RC_API_KEY"]) as client:
    job = client.fetch.person_live(url="https://www.social.com/in/janedoe")
    print("Save this job id:", job.id)  # resume after a restart with client.jobs.wait(id)

    try:
        # Long polls until the job ends, 30 minutes at most by default.
        done = job.wait()
        person = done.data.result if done.data else None
        if person is not None:
            print(person.first_name, person.last_name)
    except JobFailedError as error:
        print("Job failed:", error.error_code)
```
```bash [CLI]
rc fetch person --url https://www.social.com/in/janedoe --live --wait --timeout 300
```

## What it costs

Enrich profile costs **2 credits when a person is found**, with the full profile included. Person profile costs **1 credit when the profile is found in the cache**. A `404` from either synchronous lookup costs nothing.

Person profile live consumes **2 credits per request when the job is created**. A `person-not-found` failure remains billed. Failures with `invalid-data` or `fetch-data-error` are refunded. Check the [live failure rules](https://docs.reversecontact.com/endpoints/fetch-profile-live#webhook-callback-errors-advanced) before retrying. Polling is free.

> [!NOTE]
> For 1,000 email lookups that match 600 people, Enrich costs 600 × 2 = **1,200 credits**. The 400 unmatched requests cost nothing. Fetching 600 known URLs from the cache instead costs 600 × 1 = **600 credits**. Starting 100 live jobs consumes **200 credits** at creation.

## Good to know

Add a company domain or company name to a name-based lookup to reduce ambiguous matches. Review `data.alternativePersons` before choosing a candidate.

Enrich usually returns the full profile. If you get `data.isFullProfile: false`, Enrich returned a light profile instead. A separate cached fetch can complete that result for 1 additional credit when found.

Live results can take tens of minutes. [Polling](https://docs.reversecontact.com/guides/polling) is recommended. Send `webhookUrl` only if you want [webhook delivery](https://docs.reversecontact.com/guides/webhooks). If an SDK wait times out, resume with `client.jobs.wait(jobId)` rather than starting another job. In the CLI, use `rc task` with the saved id.

Handle [missing and empty profile fields](https://docs.reversecontact.com/guides/missing-and-empty-fields), and follow [current position ordering](https://docs.reversecontact.com/guides/current-position-resolution) when selecting a job. Profile enrichment does not replace [Find Email or Find Phone](https://docs.reversecontact.com/use-cases/get-a-work-email-or-phone).

## FAQ

### How do I find a person from an email address with the API?

Send `email` to `POST /v2/enrich/persons`. Enrich profile returns the matched profile in `data.person` and costs 2 credits when a person is found. An unmatched lookup costs nothing.

### How do I find a person by name and company?

Send `firstName`, `lastName` and `companyDomain` or `companyName` to Enrich profile. Company information narrows the match. Review `data.alternativePersons` when several people match.

### Which endpoint should I use when I already have a Social profile URL?

Use `POST /v2/fetch/persons` for the cached profile at 1 credit when found. Use Person profile live when the cached profile is stale or missing, at 2 credits consumed when the job is created.

### Does a live profile lookup cost credits when no person is found?

Person profile live consumes 2 credits at job creation, and a `person-not-found` failure remains billed. The live endpoint documents which failures receive a refund.

### Why does Enrich profile return fewer fields than expected?

Enrich profile sets `data.isFullProfile` to `false` when only the light profile could be returned in time. A separate Person profile request with the returned person id can retrieve the cached full profile for 1 additional credit when found.
