> ## 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.

# Batch Contact Enrich

> Enrich a bulk list of profile URLs with contact data as an async job — no per-profile base fee, results delivered as a file.

**Use this when** you need contact data for hundreds of people at once — bulk lists, CRM backfills, or back-office pipelines. Submit a job, then poll or receive a webhook when it finishes. You pay only for the contact values that come back, with no per-profile base fee.

<Note>
  **Choose this for a higher fill rate.** Submit a bulk list and get results
  as a file, typically within 2–3 minutes. For a quick, synchronous response
  on a few people, use [Contact Enrich](/person-docs/contact/enrich) instead.
</Note>

## How it works

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

<Steps>
  <Step title="Submit your profile URLs">
    `POST /batch/person/contact/enrich` with your list of profile URLs and
    the contact `fields` you want. 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 URL, valid for
    5 days.
  </Step>
</Steps>

<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> no per-profile base fee — you are charged only for
  the contact values that are delivered. See [Pricing](/general/pricing) for
  per-field credit costs.
  <strong> Limits:</strong> up to 5 active batch jobs per user at a time.
</Callout>

***

## 1. Submit your profile URLs

Send your profile URLs in `professional_network_profile_urls` along with the
contact `fields` you want. 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/contact/enrich \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'content-type: application/json' \
    --header 'x-api-version: 2025-11-01' \
    --data '{
      "professional_network_profile_urls": [
        "https://www.linkedin.com/in/cassandrebay",
        "https://www.linkedin.com/in/ruchavora"
      ],
      "fields": ["business_email", "personal_contact_info"]
    }'
  ```

  ```json Response theme={"theme":"vitesse-black"}
  {
      "batch_id": "c97333e3-046f-4fd2-b888-a5b07793a0ac",
      "status": "pending",
      "entity": "person",
      "action": "contact_enrich",
      "identifier_count": 2,
      "entities_requested": 2,
      "status_url": "/batch/c97333e3-046f-4fd2-b888-a5b07793a0ac"
  }
  ```
</CodeGroup>

<Note>
  To be notified when the job finishes instead of polling, include a
  `webhook_url` in the request body. Crustdata sends a callback to that URL
  when the batch completes.
</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/c97333e3-046f-4fd2-b888-a5b07793a0ac \
    --header 'authorization: Bearer YOUR_API_KEY' \
    --header 'x-api-version: 2025-11-01'
  ```

  ```json Response theme={"theme":"vitesse-black"}
  {
      "batch_id": "c97333e3-046f-4fd2-b888-a5b07793a0ac",
      "status": "completed",
      "entity": "person",
      "action": "contact_enrich",
      "identifier_count": 2,
      "result_count": 2,
      "entities_requested": 2,
      "entities_fulfilled": 2,
      "created_at": "2026-05-28T10:00:00Z",
      "completed_at": "2026-05-28T10:06:00Z",
      "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 profile URL. The link is valid for 5 days.

***

## Fields

Request any combination of these contact fields. Only professional network profile URLs are
supported as identifiers for this endpoint.

| Field                                   | Returns                                |
| --------------------------------------- | -------------------------------------- |
| `business_email`                        | Verified business email addresses      |
| `personal_contact_info`                 | Both personal emails and phone numbers |
| `personal_contact_info.personal_emails` | Personal email addresses only          |
| `personal_contact_info.phone_numbers`   | Phone numbers only                     |

## Request parameters

| Parameter                           | Type      | Required | Description                                                     |
| ----------------------------------- | --------- | -------- | --------------------------------------------------------------- |
| `professional_network_profile_urls` | string\[] | Yes      | Profile URLs to enrich. Professional network profile URLs only. |
| `fields`                            | string\[] | Yes      | Which contact fields to enrich (see the table above).           |
| `webhook_url`                       | string    | No       | URL to call when the job finishes, instead of polling.          |

## Job lifecycle

| Status       | Meaning                                     |
| ------------ | ------------------------------------------- |
| `pending`    | Job accepted, not yet started.              |
| `processing` | Job is running.                             |
| `completed`  | Job finished — `download_url` is available. |
| `failed`     | Job failed. No contact values were billed.  |

## Errors

| Status | Meaning                                                          |
| ------ | ---------------------------------------------------------------- |
| `400`  | Invalid request — missing identifier, invalid field, or no URLs. |
| `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/contact/enrich`                                                             |
| **Poll**     | `GET /batch/{batch_id}`                                                                         |
| **Auth**     | Bearer token + `x-api-version: 2025-11-01`                                                      |
| **Request**  | `professional_network_profile_urls` (required), `fields` (required). Optional: `webhook_url`.   |
| **Response** | Submit returns `batch_id` + `status`; poll returns `status` and a `download_url` when complete. |
| **Output**   | Gzipped JSONL, one record per profile URL, download link valid 5 days.                          |
| **Errors**   | `400`, `401`, `403`, `429`, `500`                                                               |

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

See the [full API reference](/openapi-specs/2025-11-01/introduction) for the complete OpenAPI schema.

***

## What to do next

* **Enrich interactively** — [Contact Enrich](/person-docs/contact/enrich) returns contact data synchronously for up to 25 URLs per request.
* **Find people first** — use [Person Search](/person-docs/search/introduction) to build the list of profile URLs to enrich.
