Skip to content

Endpoints // Contact

Find Phone

Find a professional phone number from a LinkedIn URL or full name and company domain, then receive the result by webhook.

POST/v2/contact/phone

Introduction

The Find Phone endpoint discovers professional phone numbers for a person. You can identify the person with a LinkedIn profile URL, or with their full name and company domain. Processing is asynchronous: the API acknowledges the request with a webhookId, then you retrieve the result by polling (recommended, no public endpoint required) or through a webhook callback (advanced, push delivery).

Use this endpoint when you need a phone number for outreach or CRM enrichment. For push delivery, configure a workspace webhook URL in Settings > Webhooks, or provide webhookUrl in the request.

Authorization

NameTypeRequiredDescription
apikeystringYesYour API key from the developer dashboard. Pass it in the Authorization: Bearer YOUR_API_KEY header.

Request body

Choose one lookup strategy. Use either a LinkedIn profile URL, or a full name with a company domain. The split firstName + lastName form is also accepted.

NameTypeRequiredDescription
urlstringConditionalPublic LinkedIn profile URL, such as https://www.linkedin.com/in/janedoe. Use this for the URL strategy.
fullNamestringConditionalPerson's full name, such as Jane Doe. Use this with companyDomain.
firstNamestringConditionalPerson's first name. Use this with lastName and companyDomain instead of fullName.
lastNamestringConditionalPerson's last name. Use this with firstName and companyDomain instead of fullName.
companyDomainstringConditionalCompany domain, such as acme.com. Required for the name-based strategies.
webhookUrlstringOptionalHTTPS URL that receives the callback. Omit it to retrieve the result by polling instead.

Response structure

This endpoint replies immediately with a webhookId. You then have two ways to retrieve the actual result:

  1. Polling (recommended). Call GET /v2/webhooks/:webhookId until the status is succeeded. No webhook URL needed. See the Polling guide.
  2. Webhook callback (advanced). If you provided a webhookUrl (or a workspace default is configured), the gateway POSTs the phone numbers to that URL once the lookup completes. See Webhook callback payload (advanced) below.
FieldTypeDescription
successbooleantrue if the job was created successfully
dataobject

Initial job acknowledgement. Save the webhookId to retrieve the result via polling (GET /v2/webhooks/:webhookId) or to correlate an upcoming webhook callback (null on error responses).

Show child attributes
FieldTypeDescription
statusstringJob status, always "created" for the initial response
webhookIdstringUnique identifier (UUID). Save it. Use it to poll the result at GET /v2/webhooks/:webhookId, or to correlate an incoming webhook callback.
pollUrlstringConvenience hint pointing to the polling endpoint for this job (e.g. /v2/webhooks/{webhookId}).
FieldTypeDescription
errornullAlways null on success
quotasobject

Credits and rate limit usage after this request

Show child attributes
FieldTypeDescription
creditsConsumednumberCredits consumed by this request
workspaceobject

Workspace-level limits

Show child attributes
FieldTypeDescription
idstringYour workspace identifier
hasUnlimitedCreditsbooleanWhether workspace credits are unlimited
allowDailyOvercostbooleanWhether the workspace may exceed its daily cap
creditsobject

Credit balance

Show child attributes
FieldTypeDescription
totalnumberTotal credits in your plan
usednumberCredits consumed so far
leftnumberRemaining credits
dailyLimitobject

Daily request limit (null if not configured)

Show child attributes
FieldTypeDescription
limitnumberMaximum requests per day
usednumberRequests made today
leftnumberRemaining requests today
nextResetstringWhen the daily window resets (ISO 8601)
minuteRateLimitobject

Per-minute rate limit

Show child attributes
FieldTypeDescription
limitnumberMaximum requests per minute
usednumberRequests made in the current minute
leftnumberRemaining requests in the current minute
nextResetstringWhen the minute window resets (ISO 8601)
keyobject

API key-level limits (null when request is from dashboard)

Show child attributes
FieldTypeDescription
idstringAPI key identifier
dailyLimitobject

Daily limit for this key (null if not configured)

Show child attributes
FieldTypeDescription
limitnumberMaximum requests per day
usednumberRequests made today
leftnumberRemaining requests today
nextResetstringWhen the daily window resets (ISO 8601)
minuteRateLimitobject

Minute rate limit for this key

Show child attributes
FieldTypeDescription
limitnumberMaximum requests per minute
usednumberRequests made in the current minute
leftnumberRemaining requests in the current minute
nextResetstringWhen the minute window resets (ISO 8601)
metadataobject

Request tracking information

Show child attributes
FieldTypeDescription
requestIdstringUnique identifier for this request
executionTimeMsnumberTotal execution time in milliseconds

Webhook callback payload (advanced)

When the lookup succeeds, ReverseContact sends a JSON POST request to your webhookUrl. The callback is not wrapped in the V2 response envelope. It always includes the webhookId from the initial acknowledgement and a data value.

Webhook callback (success)

Success payload

{
  "webhookId": "b8c9d0e1-f2a3-4b4c-5d6e-7f8091a2b3c4",
  "data": [
    {
      "value": "+33612345678",
      "type": "mobile"
    }
  ]
}
dataobject

One entry per phone number discovered for the person.

Show child attributes
FieldTypeDescription
valuestringThe discovered phone number, in the format reported by the provider (usually E.164)
typestring | nullPhone kind reported by the provider, such as mobile; null when the provider gives no kind

Webhook callback errors (advanced)

When the lookup cannot return a phone number, data is not an array. Instead, it contains an errorCode identifying the failure reason:

Webhook callback (error)

Error payload

{
  "webhookId": "b8c9d0e1-f2a3-4b4c-5d6e-7f8091a2b3c4",
  "data": {
    "errorCode": "phone-not-found"
  }
}

data.errorCode will be one of the following values:

CodeBilledDescription
phone-not-foundNoNo phone number was discovered for the person
person-not-foundNoNo matching person was found for the supplied identifiers
invalid-requestNoThe lookup input is malformed or does not match an accepted form
fetch-data-errorNoThe lookup failed while fetching data; safe to retry
webhook-url-invalidYesThe callback URL returned a 4xx response
webhook-url-erroredYesThe callback URL returned a 5xx response or a network error
webhook-url-timeoutYesThe callback URL did not respond in time
webhook-url-unreachableYesThe callback URL could not be reached

Code examples

Code Examples

const KEY = "YOUR_API_KEY";
const BASE = "https://api.reversecontact.com";

const trigger = await fetch("https://api.reversecontact.com/v2/contact/phone", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    url: "https://www.linkedin.com/in/janedoe"
  })
});
const { data: { webhookId } } = await trigger.json();

async function pollUntilDone(id) {
  while (true) {
    const res = await fetch(`${BASE}/v2/webhooks/${id}`, {
      headers: { "Authorization": `Bearer ${KEY}` }
    });
    const { data } = await res.json();
    if (data.status === "succeeded") return data.result;
    if (data.status === "errored")  throw new Error(data.errorCode ?? "Job failed");
    await new Promise(r => setTimeout(r, 2000));
  }
}

const result = await pollUntilDone(webhookId);
console.log(result);

Example response

Example Response

{
  "success": true,
  "data": {
    "status": "created",
    "webhookId": "b8c9d0e1-f2a3-4b4c-5d6e-7f8091a2b3c4",
    "pollUrl": "/v2/webhooks/b8c9d0e1-f2a3-4b4c-5d6e-7f8091a2b3c4"
  },
  "error": null,
  "metadata": {
    "requestId": "req_p1h2o3n4e5f6",
    "executionTimeMs": 95
  },
  "quotas": {
    "creditsConsumed": 20,
    "workspace": {
      "id": "ws_abc123",
      "credits": {
        "total": 10000,
        "used": 4539,
        "left": 5461
      },
      "dailyLimit": null,
      "minuteRateLimit": {
        "limit": 60,
        "used": 10,
        "left": 50,
        "nextReset": "2025-01-20T14:16:00.000Z"
      },
      "hasUnlimitedCredits": false,
      "allowDailyOvercost": false
    },
    "key": {
      "id": "key_abc123",
      "dailyLimit": null,
      "minuteRateLimit": {
        "limit": 60,
        "used": 10,
        "left": 50,
        "nextReset": "2025-01-20T14:16:00.000Z"
      }
    }
  }
}