Skip to main content
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 per contact type returned for each matched person — never per candidate record.
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 instead.
Availability: requires contact-enrich access (enterprise or higher-tier plans). Limits: up to 300 profile URLs per submission.
Contact endpoint rate limits are grouped with the live endpoints, not with in-database, so they do not move with the limits on search and enrich. See Rate limits.

Pricing

Billed per contact type returned, per matched person, at the same prices as Person Contact Enrich. The maximum is 5 per person, or 5.5 with verified: true. Counted per type, not per record — a person with four business-email candidates bills once. Persons with no contact data found are not billed for any type. Result rows contain only the contact types you requested; a requested type with no data appears as an empty list. See Pricing for all endpoints. Set verified: true and each matched person who receives at least one verified business email costs 0.5 more, the same add-on as the synchronous endpoint. Business emails alone then cost 1.5 per matched person, and all three types cost 5.5. You pay nothing for the add-on on a person whose verified list comes back empty.

How it works

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

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

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

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.
Replace YOUR_API_KEY in each example with your actual API key. All requests require the x-api-version: 2025-11-01 header.
Pricing: no per-profile base fee — you are charged only for the contact values that are delivered. See Pricing for per-field credit costs. Limits: active jobs are capped per account across the live endpoints (5 on default limits) - see Rate limits.

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

Verified business emails only

Add "verified": true to keep only business emails that pass a deliverability check. Crustdata re-checks cached addresses marked deliverable or unknown before it writes the results file and drops any address that fails. Each row’s business_email list then holds only deliverable and catch_all entries. Personal emails and phone numbers do not change.
Poll and download exactly as in the unverified flow. In the results file, a row with no surviving address gets an empty business_email list and business_email_message set to no verified emails found. The second record above is illustrative.
verified only changes business_email. It has no effect unless you request business_email, and it adds 0.5 credits per matched person who receives at least one verified business email. You pay nothing for business emails on a row whose list is empty.

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.
fill_counts is how many profiles came back with at least one value for each field you requested. Use it to measure fill rate. It is only present once status is completed, and it breaks personal_contact_info out into personal_emails and phone_numbers so each is counted separately. Do not use entities_fulfilled for this. It counts rows in the results file, one per distinct profile URL you submitted, whether or not any contact was found for it. The download_url points to gzipped JSONL (.jsonl.gz) with one record per submitted profile URL. The link is valid for 5 days. Unzip it and each line looks like this:
One record from the results file
Join back to your input list on professional_network_url, which echoes the profile URL you submitted. Only the fields you asked for in fields are present.

Fields

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

Request parameters

Job lifecycle

Errors


API reference summary

For credit pricing, see Pricing. For throughput guidance, see Rate limits. See the full API reference for the complete OpenAPI schema.

What to do next

  • Enrich interactively — Contact Enrich returns contact data synchronously for up to 25 URLs per request.
  • Find people first — use Person Search to build the list of profile URLs to enrich.