Skip to content

Find contact details

Find work email addresses and direct phone numbers using an identifiable professional profile.

For a known person, supply a professional profile URL where possible. Otherwise include their name, company and domain so research can resolve the identity before attempting a contact lookup. Request output: {"type":"email"} or output: {"type":"phone"} in enrichment.

Use enrichment_start in MCP or POST /api/v1/operations/enrichment.start through HTTP. One request accepts 1–100 independent items, so you can research email addresses or phones for many contacts at once. For both details per person, send two items with distinct IDs and the corresponding output types: up to 50 people with both fields per batch. See the executable bulk contact example.

Leadbase handles the identity research and contact lookup within the same workflow. In HTTP integrations, direct catalog operations are also available when you already know the exact operation and its required identifiers. MCP clients use the research tools above.

Example question

“Find the work email for the person identified by this professional profile. Do not substitute a general company inbox.” Include the profile in input and select email as the output. For a direct phone number, explicitly ask for the person rather than a switchboard.

Research a direct phone through HTTP

This example starts one phone question without creating a Sheet. Configure LEADBASE_API_KEY for the intended workspace; see API authentication. Replace the profile placeholder with a person you intend to research and choose a stable key for this exact request. Running the start request can consume credits. The Claude Code and Codex phone guide shows the same workflow through MCP.

1. Start the phone question

bash
curl --fail-with-body https://www.leadbase.io/api/v1/operations/enrichment.start \  -H "x-api-key: $LEADBASE_API_KEY" \  -H 'Content-Type: application/json' \  --data-binary @- <<'JSON'{  "idempotencyKey": "contact-phone-pilot-001",  "items": [    {      "id": "contact-1-phone",      "input": {        "profileUrl": "https://www.linkedin.com/in/CONTACT_ONE"      },      "question": "Find this person's direct business phone number. Do not substitute a company switchboard or invent a missing number.",      "output": { "type": "phone" }    }  ]}JSON

Keep the returned batchId and the mapping between jobs[].itemId and jobs[].jobId. The response confirms acceptance; a queued or running job has not returned a final answer. The input object accepts task-relevant scalar facts such as name, company, domain and country in addition to the profile URL.

2. Retrieve the same batch

bash
curl --fail-with-body https://www.leadbase.io/api/v1/operations/enrichment.get \  -H "x-api-key: $LEADBASE_API_KEY" \  -H 'Content-Type: application/json' \  -d '{"batchId":"BATCH_ID_FROM_START"}'

Replace BATCH_ID_FROM_START with the actual returned UUID. In MCP, use enrichment_get with that same argument. Read at a reasonable interval with backoff while jobs remain queued or running. Do not repeat enrichment.start to poll.

The following is a fictional excerpt from a completed response; other job fields are omitted. PHONE_VALUE_FROM_RESULT is a placeholder for the returned phone string, not a callable number. The excerpt demonstrates structure, not a measured research result or a promise of free research.

json
{  "batchId": "11111111-1111-4111-8111-111111111111",  "jobs": [    {      "itemId": "contact-1-phone",      "status": "completed",      "result": {        "type": "phone",        "value": ["PHONE_VALUE_FROM_RESULT"],        "confidence": 80,        "summary": "Illustrative phone result. Review the actual explanation and evidence before use.",        "sources": []      },      "errorCode": null,      "billingStatus": "pending",      "credits": null    }  ]}

The real response includes jobId, batchId, instruction, createdAt and updatedAt for each job. Preserve these identifiers and the actual sources. A confidence value is not proof of current ownership or permission to call; empty sources provide no citation. The public phone result is an array of strings, not an object that guarantees number-type or verification metadata.

3. Handle missing numbers, errors and billing

ObservationMeaningHandling
status: "completed", phone result.value: ["…"]A phone value was returnedRead the explanation and sources; check identity and number type
status: "completed", phone result.value: []No usable phone returnedKeep the empty result and explanation; do not fill it with a guess
status: "queued" or "running"No final outcome yetContinue reading this batch
status: "failed" or "cancelled"Execution did not finish successfullyRetain errorCode and status; do not classify it as a completed search without a number
billingStatus: "pending" or "reconciliation_pending"Accounting remains unresolvedReport observed costs separately and check settlement again
billingStatus: "settled"Recorded billing is finalUse the returned credits; null usage is never an assumed zero

For a completed phone result without a number, the result fragment is:

json
{  "type": "phone",  "value": [],  "confidence": 0,  "summary": "Illustrative completed search without a usable phone number.",  "sources": []}

A source supporting the person's identity does not automatically support a phone number. If the returned string has no observed type, leave mobile versus direct line unknown. A phone number also does not establish permission to call it.

If the start response is lost, recover with the identical payload and the same idempotencyKey. A changed question, input or intentionally new batch requires a new key. Do not create a fresh key to recover an uncertain paid submission. Keep job completion and credit settlement separate; research can incur costs even without a returned contact. See Activity and Credits.

Enrich contacts already in a sheet

Use sheets_enrich for an existing email or phone column, or create one as part of the request. For example, pass the following arguments for all existing rows only when that is the requested scope. Replace the sheet UUID and choose your own stable retry key before executing paid research:

json
{  "idempotencyKey": "sheet-email-pilot-001",  "sheetId": "SHEET_UUID",  "column": {    "name": "Work email",    "question": "Find this person's work email using their existing profile and company context.",    "type": "email"  }}

Use column: {"columnId":"COLUMN_UUID"} for a configured column. Supply rowIds to restrict a subset; omission covers all existing rows, up to 10,000. Populated cells and active cells are skipped. Use a separate request and retry key for a phone column. Read sheets_get_enrichment_status, then sheets_query for saved values and evidence. The HTTP equivalent is sheets.enrich.

Interpret missing results

A no-result outcome means no usable answer was returned. It is different from an execution failure. An identity source can be present even when the requested phone or email was not found; that source does not itself prove a contact detail.

The result uses arrays for email and phone values. Keep the returned values and check the job status and explanation before using them. Do not treat an empty array as a delivered contact.

Understand cost

Research that identifies the person and the contact lookup can be separate cost components. “No contact found” does not necessarily mean the whole research task was free. Review settled credits in Activity and the current catalog estimate instead of assuming one fixed price for every workflow. See Credits.