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

# Identify (Reverse Email Lookup)

> Resolve a bulk list of business emails (or profile URLs) to the people behind them as an async job — reverse email lookup with results delivered as a file.

**Use this when** you have a list of business emails and need to know *who* each
one belongs to — the person, their `crustdata_person_id`, and basic profile —
at bulk scale. Submit a job, then poll or receive a webhook when it finishes.
You pay only for the emails that resolve to a person.

<Note>
  **Identify vs Enrich.** Identify answers *"who is this email?"* — it returns
  the matched person's `crustdata_person_id` and `basic_profile` (name,
  headline, title). If you also need contact data, full employment history, or
  company IDs per role, use [Person Enrich](/person-docs/enrichment/introduction)
  (which also supports reverse lookup by business email).
</Note>

## How it works

Reverse identify is an **asynchronous, two-call flow** — you submit a job, then
fetch the results once it finishes:

<Steps>
  <Step title="Submit your emails">
    `POST /batch/person/identify` with your list of `business_emails` (or
    `professional_network_profile_urls`). You get a `batch_id` back
    immediately.
  </Step>

  <Step title="Poll, or wait for a webhook">
    `GET /batch/{batch_id}` to check the job status — or pass a `webhook_url`
    on submit and we call you when it finishes.
  </Step>

  <Step title="Download the results">
    Once `status` is `completed`, the status response includes a
    `download_url`: a gzipped JSONL file with one record per input, valid for
    5 days.
  </Step>
</Steps>

<Note>
  Emails already known to Crustdata resolve in seconds. Emails that require
  real-time retrieval take longer, which is why this endpoint is asynchronous.
</Note>

<Note>
  Replace `YOUR_API_KEY` in each example with your actual API key. All requests
  require the `x-api-version: 2025-11-01` header.
</Note>

<Callout icon="lock" color="#f59e0b">
  <strong>Pricing:</strong> 1 credit per email that resolves to a person —
  unmatched emails are free. See [Pricing](/general/pricing) for details.
  <strong> Limits:</strong> up to 300 identifiers per submission, and up to 5
  active batch jobs per user at a time.
</Callout>

***

## 1. Submit your emails

Send your emails in `business_emails`. The response returns a `batch_id`
immediately — the job runs asynchronously.

<CodeGroup>
  ```bash Request theme={"theme":"vitesse-black"}
  curl --request POST \
    --url https://api.crustdata.com/batch/person/identify \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'content-type: application/json' \
    --header 'x-api-version: 2025-11-01' \
    --data '{
      "business_emails": [
        "abhilash@crustdata.com",
        "ankit.harbhajanka@aequs.com"
      ]
    }'
  ```

  ```json Response theme={"theme":"vitesse-black"}
  {
      "batch_id": "61f537fc-e93d-4912-8d00-0ece6c7ecf9f",
      "status": "pending",
      "entity": "person",
      "action": "identify",
      "identifier_count": 2,
      "entities_requested": 2,
      "status_url": "/batch/61f537fc-e93d-4912-8d00-0ece6c7ecf9f"
  }
  ```
</CodeGroup>

<Note>
  You can submit `professional_network_profile_urls` instead of
  `business_emails` to resolve profile URLs to their `crustdata_person_id`.
  Submit exactly one identifier type per job. To be notified when the job
  finishes instead of polling, include a `webhook_url` in the request body.
</Note>

## 2. Get the results

Poll the `status_url` (or `GET /batch/{batch_id}`). While the job runs, `status`
is `pending` or `processing`. When it is `completed`, the response includes a
`download_url`.

<CodeGroup>
  ```bash Request theme={"theme":"vitesse-black"}
  curl --request GET \
    --url https://api.crustdata.com/batch/61f537fc-e93d-4912-8d00-0ece6c7ecf9f \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'x-api-version: 2025-11-01'
  ```

  ```json Response theme={"theme":"vitesse-black"}
  {
      "batch_id": "61f537fc-e93d-4912-8d00-0ece6c7ecf9f",
      "status": "completed",
      "entity": "person",
      "action": "identify",
      "identifier_count": 2,
      "result_count": 2,
      "entities_requested": 2,
      "entities_fulfilled": 2,
      "created_at": "2026-06-22T03:23:30Z",
      "completed_at": "2026-06-22T03:23:31Z",
      "download_url": "https://crustdata-batch-api-data.s3.amazonaws.com/...&X-Amz-Expires=432000"
  }
  ```
</CodeGroup>

The `download_url` points to gzipped JSONL (`.jsonl.gz`) with one record per
submitted identifier. The link is valid for 5 days.

## Result format

Each line is one record for an input identifier:

```json theme={"theme":"vitesse-black"}
{
  "matched_on": "abhilash@crustdata.com",
  "match_type": "business_email",
  "matches": [
    {
      "confidence_score": 1.0,
      "person_data": {
        "crustdata_person_id": 1068035,
        "basic_profile": {
          "name": "Abhilash Chowdhary",
          "headline": "Co-founder at Crustdata (YC F24) | Real-time B2B data for AI agents",
          "current_title": "Co-Founder & CEO",
          "summary": "Love building things...",
          "languages": ["English", "Hindi"],
          "last_updated": "2026-06-22T00:11:06Z",
          "location": null
        },
        "updated_at": "2026-06-22T00:11:06Z"
      }
    }
  ]
}
```

An email with no match returns an empty `matches` array (and is not billed):

```json theme={"theme":"vitesse-black"}
{ "matched_on": "nobody@unknown-domain.com", "match_type": "business_email", "matches": [] }
```

## Request parameters

| Parameter                           | Type      | Required          | Description                                                                 |
| ----------------------------------- | --------- | ----------------- | --------------------------------------------------------------------------- |
| `business_emails`                   | string\[] | One identifier of | Business emails to reverse-lookup. Max 300 per submission.                  |
| `professional_network_profile_urls` | string\[] | One identifier of | Profile URLs to resolve to a `crustdata_person_id`. Max 300 per submission. |
| `webhook_url`                       | string    | No                | URL to call when the job finishes, instead of polling.                      |

<Note>
  Submit exactly one identifier type per job — either `business_emails` or
  `professional_network_profile_urls`, not both.
</Note>

## Response fields

| Field                        | Description                                                                      |
| ---------------------------- | -------------------------------------------------------------------------------- |
| `matched_on`                 | The input value this record resolved (the email or profile URL you submitted).   |
| `match_type`                 | `business_email` or `professional_network_profile_url`.                          |
| `matches`                    | Array of matches. Empty when nothing resolved.                                   |
| `matches[].confidence_score` | Match confidence, `0`–`1`.                                                       |
| `matches[].person_data`      | `crustdata_person_id`, `basic_profile`, and `updated_at` for the matched person. |

## Job lifecycle

| Status       | Meaning                                     |
| ------------ | ------------------------------------------- |
| `pending`    | Job accepted, not yet started.              |
| `processing` | Job is running.                             |
| `completed`  | Job finished — `download_url` is available. |
| `failed`     | Job failed. Nothing was billed.             |

## Errors

| Status | Meaning                                                                          |
| ------ | -------------------------------------------------------------------------------- |
| `400`  | Invalid request — missing identifier, both identifier types, or too many values. |
| `401`  | Invalid or missing API key.                                                      |
| `403`  | Permission denied or insufficient credits.                                       |
| `429`  | Too many active batch jobs (max 5 per user).                                     |
| `500`  | Internal server error. Retry with exponential backoff.                           |

***

## API reference summary

| Detail       | Value                                                                                               |
| ------------ | --------------------------------------------------------------------------------------------------- |
| **Submit**   | `POST /batch/person/identify`                                                                       |
| **Poll**     | `GET /batch/{batch_id}`                                                                             |
| **Auth**     | Bearer token + `x-api-version: 2025-11-01`                                                          |
| **Request**  | One of `business_emails` or `professional_network_profile_urls` (max 300). Optional: `webhook_url`. |
| **Response** | Submit returns `batch_id` + `status`; poll returns `status` and a `download_url` when complete.     |
| **Output**   | Gzipped JSONL, one record per identifier, download link valid 5 days.                               |
| **Billing**  | 1 credit per matched person; unmatched identifiers are free.                                        |
| **Errors**   | `400`, `401`, `403`, `429`, `500`                                                                   |

For credit pricing, see [Pricing](/general/pricing). For throughput guidance, see
[Rate limits](/general/rate-limits).

***

## What to do next

* **Need contact data or full employment history?** Use [Person Enrich](/person-docs/enrichment/introduction) — it reverse-looks-up by business email and returns the full profile, including each role's `crustdata_company_id`.
* **Enrich contact info in bulk** — [Batch Contact Enrich](/person-docs/contact/batch) returns emails and phone numbers for a list of profile URLs.
* **Find people first** — use [Person Search](/person-docs/search/introduction) to build the list to identify.
