Skip to navigation

Lead Enrichment Overview

Lead Enrichment (LE) is Dealsignal’s asynchronous bulk-enrichment product. You submit a list of contacts in a columnar format, Dealsignal matches each row against its verified B2B database, runs the enrichment pipeline, and returns paginated results.

A single LE job can process from a handful to tens of thousands of leads. The pipeline runs in the background — poll status or use a webhook.


Lifecycle

1

Create the job

POST /api/v1/lead_enrichments with your lead data. The response includes the job id.

2

Poll status (or wait for the webhook)

GET /api/v1/lead_enrichments/{id}. The job moves through Created → Launched → Running → Completion Running → Completed. It is finished when is_completed is true (completed_at is then set).

3

Fetch paginated results

GET /api/v1/lead_enrichments/{id}/final_result with page and page_size. Pages are zero-based; the default size is 100. Call it once is_completed is true — before that it returns a message instead of results.


Quickstart

1

Submit a job

curl -X POST "https://app.dealsignal.com/api/v1/lead_enrichments?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"lead_enrichments": {
"name": "YOUR_UNIQUE_JOB_NAME",
"source_type": "from_json",
"match_field": "linkedin_url",
"contact_profile_only": true,
"lead_data": {
"keys": ["first_name", "last_name", "company_name", "linkedin_url", "unique_identifier"],
"values": [
["Jane", "Smith", "Acme Corp", "https://www.linkedin.com/in/jane-smith-example", "1"],
["John", "Doe", "Globex Inc", "https://www.linkedin.com/in/john-doe-example", "2"]
]
}
}
}'
2

Poll until complete

curl -H "Accept: application/json" \
"https://app.dealsignal.com/api/v1/lead_enrichments/{id}?api_key=YOUR_API_KEY"
{
"lead_enrichment": {
"id": 652,
"name": "YOUR_UNIQUE_JOB_NAME",
"status": "Completed",
"is_completed": true,
"completed_at": "2024-06-01T11:30:00Z",
"type": "linkedin_url",
"profile_type": "Contact Profile",
"total_leads_to_enrich": 2,
"total_enriched_leads": 2
}
}

The job is wrapped in lead_enrichment. The response carries more keys than shown; see the API Reference for the documented ones.

3

Fetch results

curl -H "Accept: application/json" \
"https://app.dealsignal.com/api/v1/lead_enrichments/{id}/final_result?api_key=YOUR_API_KEY&page=0&page_size=100"

The response is { "lead_enrichment": {…}, "enriched_leads": { "total": 2, "leads": [ … ] } }. Each lead carries custom_columns — the row you submitted, including your unique_identifier — plus the enriched contact fields. total counts every lead in the job, matched or not.


Key request fields

FieldRequiredDescription
nameyesName for the job. Must be unique: a name that’s already taken returns 422, so include something distinctive such as a date or your own ID.
source_typeyesAlways from_json for API-submitted jobs.
match_fieldyesHow Dealsignal finds each row: name, email, or linkedin_url.
lead_datayes{ keys: string[], values: string[][] } — columnar input (see below).
contact_profile_onlynoEnrich the contact profile only — no email or phone enrichment. Don’t combine it with the two flags below.
is_full_prospect_profilenoAlso enrich phone numbers. Without it, direct_dial and contact_profile_only, the job enriches the contact profile and work email.
direct_dialnoAlso enrich phone numbers, including direct dials. Turns on is_full_prospect_profile. The job’s profile_type shows the resulting tier.
append_company_datanoAdd enriched company data alongside contact data.
contact_refresh_timenoFreshness threshold in days (1 or more). Contacts verified within this many days before the job are returned without a refresh; older ones are refreshed first. Default 30.
flag_if_lead_changed_companynoCompute changed_company: whether the contact’s primary employer changed within about the last month before the job (many position dates are only month-precise). It is not a comparison with the values you submit. false also covers leads that couldn’t be assessed, so it isn’t proof the contact stayed.
flag_if_lead_changed_titlenoSame, for the primary title (changed_title).
webhooknoURL to receive a POST when the job completes.

About lead_data

lead_data is columnar, not row-of-objects: keys defines the field names, each entry in values is one lead’s data in the same order.

{
"keys": ["first_name", "last_name", "email", "unique_identifier"],
"values": [
["Jane", "Smith", "jane@acme.example", "1"],
["John", "Doe", "john@globex.example", "2"]
]
}

Allowed keys: first_name, last_name, company_name, email, linkedin_url, title, city, state, country, unique_identifier.


Webhooks

Provide a webhook URL on job creation and Dealsignal will POST a notification when the job finishes. The body is the job object — the same fields as lead_enrichment in GET /api/v1/lead_enrichments/{id}, without the wrapper. It does not carry the leads; fetch them from final_result.

The notification is sent once, while the job is being finalized, so its payload shows status: "Completion Running" and is_completed: false — treat the webhook’s arrival as the completion signal. Acknowledge with any 2xx first, then fetch results; if final_result returns a message instead of enriched_leads, retry after a few seconds. If the job reads is_completed: true and final_result still returns a message, stop retrying and check page / page_size. If your endpoint was unavailable, poll GET /api/v1/lead_enrichments/{id} instead.


Endpoint reference

EndpointMethodPurpose
/api/v1/lead_enrichmentsPOSTCreate and launch a job.
/api/v1/lead_enrichmentsGETList all jobs with stats.
/api/v1/lead_enrichments/{id}GETSingle-job status.
/api/v1/lead_enrichments/{id}/final_resultGETPaginated enriched results.