Skip to main content
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.
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 (which also supports reverse lookup by business email).

How it works

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

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.
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 input, valid for 5 days.
Emails already known to Crustdata resolve in seconds. Emails that require real-time retrieval take longer, which is why this endpoint is asynchronous.
Replace YOUR_API_KEY in each example with your actual API key. All requests require the x-api-version: 2025-11-01 header.
Pricing: 1 credit per email that resolves to a person — unmatched emails are free. See Pricing for details. Limits: up to 300 identifiers per submission, and up to 5 active batch jobs per user at a time.

1. Submit your emails

Send your emails in business_emails. The response returns a batch_id immediately — the job runs asynchronously.
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"
    ]
  }'
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.

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.
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'
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:
{
  "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):
{ "matched_on": "nobody@unknown-domain.com", "match_type": "business_email", "matches": [] }

Request parameters

ParameterTypeRequiredDescription
business_emailsstring[]One identifier ofBusiness emails to reverse-lookup. Max 300 per submission.
professional_network_profile_urlsstring[]One identifier ofProfile URLs to resolve to a crustdata_person_id. Max 300 per submission.
webhook_urlstringNoURL to call when the job finishes, instead of polling.
Submit exactly one identifier type per job — either business_emails or professional_network_profile_urls, not both.

Response fields

FieldDescription
matched_onThe input value this record resolved (the email or profile URL you submitted).
match_typebusiness_email or professional_network_profile_url.
matchesArray of matches. Empty when nothing resolved.
matches[].confidence_scoreMatch confidence, 01.
matches[].person_datacrustdata_person_id, basic_profile, and updated_at for the matched person.

Job lifecycle

StatusMeaning
pendingJob accepted, not yet started.
processingJob is running.
completedJob finished — download_url is available.
failedJob failed. Nothing was billed.

Errors

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

API reference summary

DetailValue
SubmitPOST /batch/person/identify
PollGET /batch/{batch_id}
AuthBearer token + x-api-version: 2025-11-01
RequestOne of business_emails or professional_network_profile_urls (max 300). Optional: webhook_url.
ResponseSubmit returns batch_id + status; poll returns status and a download_url when complete.
OutputGzipped JSONL, one record per identifier, download link valid 5 days.
Billing1 credit per matched person; unmatched identifiers are free.
Errors400, 401, 403, 429, 500
For credit pricing, see Pricing. For throughput guidance, see Rate limits.

What to do next

  • Need contact data or full employment history? Use Person Enrich — it reverse-looks-up by business email and returns the full profile, including each role’s crustdata_company_id.
  • Enrich contact info in bulkBatch Contact Enrich returns emails and phone numbers for a list of profile URLs.
  • Find people first — use Person Search to build the list to identify.