Skip to main content
The Person Enrich API takes an identifier you already have — a LinkedIn URL or a business email — and returns a rich professional profile. This page walks you through the API step by step, starting with the simplest possible request and building up to advanced patterns. Every request goes to the same endpoint:
POST https://api.crustdata.com/person/enrich
Replace YOUR_API_KEY in each example with your actual API key. All requests require the x-api-version: 2025-11-01 header.

Your first enrichment: look up a LinkedIn profile

The simplest enrichment takes a single LinkedIn URL and returns the person’s professional profile. Pass the URL in the professional_network_profile_urls array.
curl --request POST \
  --url https://api.crustdata.com/person/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/abhilashchowdhary/"
    ]
  }'
Response trimmed for clarity.

Understanding the response

The Enrich API returns an array — one entry per identifier you submitted. Each entry has three fields:
  • matched_on — the identifier you submitted (the LinkedIn URL or email).
  • match_type — either professional_network_profile_url or business_email, telling you which identifier type was used.
  • matches — an array of candidate profiles. Each match includes a confidence_score (0 to 1) and the full person_data object.
For LinkedIn URL lookups, you will typically get exactly one match with a confidence_score of 1.0, because the URL is a direct identifier.

What is inside person_data?

The person_data object contains several sections:
SectionKey fieldsDescription
basic_profilename, headline, current_title, summary, location, languagesCore identity and role information
professional_networkconnections, followers, joined_date, verifications, open_to_cards, profile_picture_permalinkLinkedIn-specific metadata and network stats
social_handlesprofessional_network_identifier.profile_url, professional_network_identifier.member_idCanonical LinkedIn identifiers for deduplication
experienceemployment_details.current, employment_details.pastFull work history (when available)
educationschools, all_schools, all_degreesEducation background (when available)
skillsprofessional_network_skillsListed professional skills (when available)
contactemails, phone_numbers, websitesAvailable contact information (when available)
certificationsname, issuing_organization, issue_dateProfessional certifications (when available)

Reverse lookup: find a person from a business email

You do not always have a LinkedIn URL. If you have a business email, use business_emails to reverse-lookup the person behind the address.
curl --request POST \
  --url https://api.crustdata.com/person/enrich \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --header 'x-api-version: 2025-11-01' \
  --data '{
    "business_emails": ["abhilash@crustdata.com"],
    "min_similarity_score": 0.8
  }'
Response trimmed for clarity.

How email reverse lookup works

When you submit a business email, the API resolves it to a LinkedIn profile. The response structure is identical to a LinkedIn URL lookup, but match_type is business_email and matched_on shows the email you submitted. The min_similarity_score parameter controls how strict the matching is. A value of 0.8 means the API only returns matches where it is at least 80% confident the email belongs to the person. Higher values give fewer but more reliable results.
min_similarity_scoreWhen to use
0.91.0High-confidence workflows (CRM enrichment, automated pipelines)
0.70.8Balanced accuracy for most use cases
0.50.6Exploratory lookups where you will manually verify
Not setReturns all matches regardless of confidence

Handle no-match results

Not every identifier will resolve to a person. When there is no match, the matches array is empty.
curl --request POST \
  --url https://api.crustdata.com/person/enrich \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --header 'x-api-version: 2025-11-01' \
  --data '{
    "business_emails": ["nonexistent@unknowndomain.com"],
    "min_similarity_score": 0.8
  }'
You still get a response entry for the identifier — matched_on tells you which input had no match. This makes it easy to track which lookups succeeded and which need a different approach (for example, trying Person Search with the person’s name instead).

Batch enrichment: look up multiple people at once

You can enrich up to 25 identifiers in a single request. The response returns one entry per identifier, in the same order you submitted them.
curl --request POST \
  --url https://api.crustdata.com/person/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/dvdhsu/",
      "https://www.linkedin.com/in/abhilashchowdhary/"
    ]
  }'
Response trimmed for clarity.

Batch enrichment tips

  • The maximum batch size is 25 identifiers per request.
  • You must use one identifier type per request — either all LinkedIn URLs or all emails, not a mix.
  • Each entry in the response corresponds to the input at the same position, so you can match results back to your input list by index.
  • If some identifiers fail to match, their matches array will be empty, but the request still succeeds for the others.

Get fresh data with real-time enrichment

By default, the API returns cached data. If you need the latest information (for example, to detect a recent job change), enable real-time enrichment.
curl --request POST \
  --url https://api.crustdata.com/person/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/dvdhsu/"
    ],
    "enrich_realtime": true,
    "force_fetch": true
  }'
Response trimmed for clarity.
Current platform behavior: The enrich_realtime and force_fetch flags are accepted by the API and documented in the internal PersonEnrichParsedRequest schema. They are not part of the public PersonEnrichRequest schema.

The two real-time flags

FlagWhat it does
enrich_realtime: trueFetches fresh data if the cached version is stale. If the cache is recent enough, it may still return cached data.
force_fetch: trueAlways fetches fresh data, regardless of cache age. Must be used with enrich_realtime: true.
When to use each combination:
CombinationUse case
Neither flag (default)Standard enrichment. Fastest response, lowest cost. Good for most workflows.
enrich_realtime: trueCRM data cleaning. Fetches fresh data only when the cached version is old.
enrich_realtime: true + force_fetch: trueVerifying a recent job change, pre-meeting research. Always gets the latest data.
Real-time enrichment takes longer and may cost more credits than cached lookups. Use it when data freshness matters, not for every request.

Request specific fields

By default, the API returns all available data. If you only need specific information, use the fields parameter to request just what you need.
curl --request POST \
  --url https://api.crustdata.com/person/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/dvdhsu/"
    ],
    "fields": ["professional_network.joined_date", "professional_network.verifications"]
  }'
Response trimmed for clarity.

Available fields

Field pathWhat it returns
professional_network.joined_dateWhen the person first created their LinkedIn account
professional_network.verificationsLinkedIn verification badges (e.g., work email verified)
certificationsProfessional certifications listed on the profile
This is useful for workflows that need specific metadata — for example, checking how long a prospect has been on LinkedIn, or verifying their identity through work email verification badges.

Preview mode

Use preview: true to get lightweight results before committing credits. This is useful for validating that your identifiers will resolve before running a full enrichment.
curl --request POST \
  --url https://api.crustdata.com/person/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/dvdhsu/"
    ],
    "preview": true
  }'
Preview responses have the same structure but may return fewer fields per profile.

Choosing between LinkedIn URL and email enrichment

Both paths return the same person_data shape, but they work differently.
LinkedIn URLBusiness email
Identifierprofessional_network_profile_urlsbusiness_emails
Match typeDirect lookup — the URL uniquely identifies a profileReverse lookup — the API infers which profile owns the email
ConfidenceAlways 1.0 (exact match)Varies. Use min_similarity_score to control the threshold
Best forWhen you have the LinkedIn URL (from search results, CRM data, business cards)When you only have an email (inbound leads, event attendees, badge scans)
Batch limitUp to 25 URLs per requestUp to 25 emails per request

Common workflow: Search then Enrich

The most powerful pattern combines Person Search with Person Enrich. Search finds people matching your criteria; Enrich gets the full profile for each match. Step 1: Search for decision-makers at a target company.
curl --request POST \
  --url https://api.crustdata.com/person/search \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --header 'x-api-version: 2025-11-01' \
  --data '{
    "filters": {
      "op": "and",
      "conditions": [
        {
          "field": "experience.employment_details.current.company_name",
          "type": "in",
          "value": ["Retool"]
        },
        {
          "field": "experience.employment_details.current.title",
          "type": "(.)",
          "value": "VP|Director|Head of"
        }
      ]
    },
    "limit": 5
  }'
Step 2: Take the LinkedIn URLs from the search results and enrich them for full profiles.
curl --request POST \
  --url https://api.crustdata.com/person/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/dvdhsu/",
      "https://www.linkedin.com/in/abhilashchowdhary/"
    ]
  }'
This two-step pattern is the foundation for most sales, recruiting, and research workflows. Search narrows the universe; Enrich fills in the details.

Request parameter reference

ParameterTypeRequiredDefaultDescription
professional_network_profile_urlsstring[]One of professional_network_profile_urls or business_emailsLinkedIn profile URLs to enrich. Max 25.
business_emailsstring[]One of professional_network_profile_urls or business_emailsBusiness emails for reverse lookup. Max 25.
fieldsstring[]NoAll fieldsSpecific field paths to return (e.g., professional_network.joined_date).
min_similarity_scorenumber (0–1)NoNoneMinimum confidence threshold for email reverse lookup matches.
Current platform behavior (not in public PersonEnrichRequest schema): The following parameters are accepted by the API but are documented in the internal PersonEnrichParsedRequest schema only.
| enrich_realtime | boolean | No | false | Fetch fresh data if cached version is stale. | | force_fetch | boolean | No | false | Always fetch fresh data. Requires enrich_realtime: true. | | preview | boolean | No | false | Return lightweight preview results. |

Response fields reference

Each item in the response array contains:
FieldTypeDescription
matched_onstringThe input identifier (LinkedIn URL or email)
match_typestringprofessional_network_profile_url or business_email
matchesarrayArray of candidate matches (may be empty for no-match)
matches[].confidence_scorenumber0 to 1. How confident the match is. 1.0 = exact match.
matches[].person_dataobjectFull enriched profile (see table below)

Person data sections

SectionKey fieldsDescription
basic_profilename, pronoun, headline, current_title, summary, location, languages, last_updatedCore identity and role
professional_networkprofile_picture_permalink, connections, followers, joined_date, verifications, open_to_cardsLinkedIn-specific metadata
social_handlesprofessional_network_identifier.profile_url, professional_network_identifier.member_id, twitter_identifier.slugCanonical social identifiers
experienceemployment_details.current[], employment_details.past[]Full employment history
educationschools[], all_schools[], all_degrees[]Education background
skillsprofessional_network_skills[]Professional skills
contactemails[], phone_numbers[], websites[]Contact information
certificationsname, issuing_organization, issue_date, credential_urlProfessional certifications
metadatalast_scraped_source, updated_atData freshness timestamps

What to do next

  • Search first, then enrich — use Person Search to find people by name, title, company, or location, then enrich the results.
  • See more examples — browse person examples for ready-to-copy patterns.
  • Read the overview — see Person Overview for a high-level guide to choosing between search and enrich.
  • Check the API reference — see Enrich person API reference for the full schema.