> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pubrio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# People Contact Lookup

> Reverse-lookup a person from an email, phone, or first/last name + company — no people_search_id required. 1 credit per billable match.

The People Contact Lookup API answers the question **"who does this email/phone/name belong to?"** Hand it an identifier, get back a `people_search_id` and the matched person's profile — without having to run a search first.

```bash theme={null}
curl -X POST https://api.pubrio.com/redeem/people/contact/lookup \
  -H "pubrio-api-key: $PUBRIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email": "king.lai@pubrio.com" }'
```

## When to use Contact Lookup

Use Contact Lookup when **you have an identifier and want to find the person**:

* An email landed in your inbox — who sent it, what company, what title?
* A phone number rang on your sales line — match it to a known contact
* A CSV of leads with names and companies but no Pubrio IDs — resolve them all to `people_search_id`s
* Form submission with `email + name` — enrich into a full contact record

If instead you have a `people_search_id` (or LinkedIn URL) and want the **email + phone for that person**, use [People Redeem](/en/developer-guides/people-redeem) — it's the forward direction.

## Two flavors

| Endpoint                                   | Use when                                                                                     |
| ------------------------------------------ | -------------------------------------------------------------------------------------------- |
| `POST /redeem/people/contact/lookup`       | Single lookup — one identifier per request.                                                  |
| `POST /redeem/people/contact/lookup/batch` | Batch lookup — up to your subscription's bulk size limit per request, processed in parallel. |

Both endpoints return the same `match` metadata per record (see [Match metadata](#match-metadata) below).

## Quick start

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.pubrio.com/redeem/people/contact/lookup \
    -H "pubrio-api-key: $PUBRIO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "email": "king.lai@pubrio.com" }'
  ```

  ```js JavaScript theme={null}
  const res = await fetch("https://api.pubrio.com/redeem/people/contact/lookup", {
    method: "POST",
    headers: {
      "pubrio-api-key": process.env.PUBRIO_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ email: "king.lai@pubrio.com" }),
  });
  const { data } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.post(
      "https://api.pubrio.com/redeem/people/contact/lookup",
      headers={"pubrio-api-key": os.environ["PUBRIO_API_KEY"]},
      json={"email": "king.lai@pubrio.com"},
  )
  data = res.json()["data"]
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "data": {
    "profile": {
      "credit": 450375,
      "topup_credit": 235236,
      "total_credit_cost": 1
    },
    "peoples": [
      {
        "people_search_id": "e37ccf38-ea8f-422e-9874-cb23b15e8fe4",
        "first_name": "King",
        "last_name": "Lai",
        "people_name": "King Lai",
        "company_name": "Pubrio",
        "domain": "pubrio.com",
        "match": {
          "confidence": "exact",
          "input": { "value": "king.lai@pubrio.com", "type": "email-work" },
          "is_duplicate_input": false
        }
      }
    ]
  }
}
```

## Lookup modes

You can match a person in two ways:

### Exact match — by email or phone

The default. Pass `email` or `phone`; Pubrio matches on the normalized contact value. This always returns `match.confidence: "exact"` when it hits.

```json theme={null}
{ "email": "king.lai@pubrio.com" }
```

```json theme={null}
{ "phone": "+15551234567" }
```

### Similarity match — by name + domain or company

If you don't have a deterministic identifier, you can fall back to similarity matching. Pass `first_name`, `last_name`, plus either `domain` or `company`, and set `is_enable_similarity_search: true`.

```json theme={null}
{
  "first_name": "King",
  "last_name": "Lai",
  "domain": "pubrio.com",
  "is_enable_similarity_search": true
}
```

Pubrio first tries to find an exact email/phone hit; if none exists and similarity is enabled, it ranks candidates by name proximity within the company domain (or, if `domain` is omitted, the company match). Returned matches carry `match.confidence: "similarity_domain"` or `"similarity_company"` so you can filter by certainty.

You can combine both: pass an email **and** a name + domain. The exact email match wins; the name fields become a fallback only if the email doesn't resolve.

## Match metadata

Every returned record includes a `match` object describing how the hit was made:

| Field                      | Values               | Meaning                                                                                                                          |
| -------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `match.confidence`         | `exact`              | Direct email/phone match. Highest confidence.                                                                                    |
|                            | `similarity_domain`  | Name-based match anchored to a known company domain.                                                                             |
|                            | `similarity_company` | Name-based match anchored to a company name (no domain).                                                                         |
| `match.input`              | `{ value, type }`    | Echoes the identifier that produced the hit, so you can show "matched on `king.lai@pubrio.com`" in your UI.                      |
| `match.is_duplicate_input` | boolean              | `true` when the same identifier appeared earlier in a batch — the lookup is performed only once and the duplicate isn't charged. |

Use `match.confidence` to gate downstream actions: e.g., auto-enroll only `exact` matches into a sequence; route `similarity_*` matches to manual review.

## Batch lookup

Submit up to your subscription's bulk size limit in one request. Each entry takes the same identifiers as the single-lookup body.

```bash theme={null}
curl -X POST https://api.pubrio.com/redeem/people/contact/lookup/batch \
  -H "pubrio-api-key: $PUBRIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "peoples": [
      { "email": "king.lai@pubrio.com" },
      { "first_name": "John", "last_name": "Smith", "domain": "example.com" }
    ],
    "is_enable_similarity_search": true
  }'
```

The batch is synchronous — the response contains all resolved records in the same order as the input. Unmatched inputs are dropped from the response (they don't appear at all and aren't charged).

## Credit cost

**1 credit per billable match.** Specifically:

* A successful match (exact or similarity) → 1 credit
* No match → 0 credits
* Duplicate input within a batch → 0 credits (resolved once, charged once)

This makes Contact Lookup an order of magnitude cheaper than [Redeem](/en/developer-guides/people-redeem) — you're paying to **identify** a person, not to **unlock** their contacts. If after looking up you also need their email/phone, redeem the returned `people_search_id`.

## Common patterns

<CardGroup cols={2}>
  <Card title="Inbound email enrichment" icon="envelope-open">
    On every inbound email, look up the sender. Surface their company, title, and `people_search_id` in your CRM or helpdesk view.
  </Card>

  <Card title="CSV-to-CRM resolution" icon="file-csv">
    Resolve a CSV of `name + company` rows to canonical `people_search_id`s. Ones that don't match exact get a similarity attempt automatically.
  </Card>

  <Card title="Form submission enrichment" icon="form">
    Hand off `{ email }` from your marketing form. Get back the company, title, and a Pubrio ID you can route through scoring rules.
  </Card>

  <Card title="Lookup → redeem pipeline" icon="arrow-right-arrow-left">
    Two-step flow: cheap lookup (1 credit) to identify the person, then full redeem (5–10 credits) only for matches above a confidence threshold.
  </Card>
</CardGroup>

## FAQ

<AccordionGroup>
  <Accordion title="Does Contact Lookup return verified email and phone?">
    No — Contact Lookup returns the person's profile (`people_search_id`, name, company, domain, title, etc.) plus match metadata. To get the verified contacts themselves, pass the returned `people_search_id` to [Redeem](/en/developer-guides/people-redeem).
  </Accordion>

  <Accordion title="What's the difference between similarity_domain and similarity_company?">
    `similarity_domain` means we anchored the name match to a known company domain — strongest of the similarity tiers. `similarity_company` means we anchored to a company name with no canonical domain — slightly less reliable, since multiple unrelated companies can share a name.
  </Accordion>

  <Accordion title="Will I be charged for unmatched inputs?">
    No. Unmatched inputs are silently dropped from the response and not billed.
  </Accordion>

  <Accordion title="What if I send the same email twice in a batch?">
    The duplicate is detected server-side, the lookup runs once, and you're charged once. The duplicate entry is flagged with `match.is_duplicate_input: true` in the response.
  </Accordion>

  <Accordion title="What's the batch size limit?">
    The cap is set on your subscription as `people_contact_enrichment_bulk_size`. Most plans allow 100+ per call; reach out if you need a higher ceiling.
  </Accordion>

  <Accordion title="Can I look up by LinkedIn URL?">
    Not on Contact Lookup. Use [Redeem](/en/developer-guides/people-redeem) with `linkedin_url` if you have a LinkedIn profile and want both the resolution and the contacts in one call.
  </Accordion>

  <Accordion title="What happens with international phone numbers?">
    Phone is matched on a normalized form. International (E.164) is the most reliable input. Domestic-format numbers may match if the country can be inferred, but E.164 (`+15551234567`) avoids ambiguity.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="People Redeem" icon="key" href="/en/developer-guides/people-redeem">
    Forward direction: spend credits to unlock email + phone for a known `people_search_id` or LinkedIn URL.
  </Card>

  <Card title="People Search" icon="users" href="/en/api-reference/endpoint/people/search">
    Find people who match a job/company/location filter.
  </Card>

  <Card title="People Lookup" icon="user" href="/en/api-reference/endpoint/people/lookup">
    Resolve a single person's full profile from a known identifier.
  </Card>

  <Card title="Pricing" icon="coins" href="/en/get-started/pricing">
    Credit costs across all endpoints, by plan tier.
  </Card>
</CardGroup>
