curl --request GET \
--url https://client-api.salesfinity.co/v1/api/enrichment/phone/{id} \
--header 'x-api-key: <api-key>'import requests
url = "https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"_id": "507f1f77bcf86cd799439011",
"status": "pending",
"linkedin": "https://www.linkedin.com/in/username",
"linkedin_username": "username",
"enrichment_type": "contact",
"phone_numbers": [
{
"number": "+14155550123",
"country_code": "US",
"type": "mobile",
"extension": "",
"source": "prospeo",
"validation": {
"phone_number": "+14155550123",
"is_valid": true,
"carrier": "AT&T",
"line_type": "mobile",
"likely_to_answer": "P1",
"score": 92,
"status": "pending"
}
}
],
"createdAt": "2026-08-27T10:15:04.221Z",
"updatedAt": "2026-08-27T10:16:38.904Z"
}{
"message": "Forbidden resource",
"error": "Forbidden",
"statusCode": 403
}{
"message": "Cannot GET /v1/unknown-route",
"error": "Not Found",
"statusCode": 404
}{
"message": "Too many requests",
"error": "Too Many Requests",
"statusCode": 429
}{
"message": "Internal server error",
"error": "Internal Server Error",
"statusCode": 500
}Poll a Phone Enrichment
Returns the current state of a phone enrichment request. While the waterfall is running status is pending or processing. When finished status is completed (with the numbers in phone_numbers) or not-found (every eligible provider was exhausted without a number that passed validation). phone_numbers is populated only on a completed request and is an empty array otherwise. Polling is a fallback for the callback and is safe to call repeatedly — a request is never charged twice.
curl --request GET \
--url https://client-api.salesfinity.co/v1/api/enrichment/phone/{id} \
--header 'x-api-key: <api-key>'import requests
url = "https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.salesfinity.co/v1/api/enrichment/phone/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"_id": "507f1f77bcf86cd799439011",
"status": "pending",
"linkedin": "https://www.linkedin.com/in/username",
"linkedin_username": "username",
"enrichment_type": "contact",
"phone_numbers": [
{
"number": "+14155550123",
"country_code": "US",
"type": "mobile",
"extension": "",
"source": "prospeo",
"validation": {
"phone_number": "+14155550123",
"is_valid": true,
"carrier": "AT&T",
"line_type": "mobile",
"likely_to_answer": "P1",
"score": 92,
"status": "pending"
}
}
],
"createdAt": "2026-08-27T10:15:04.221Z",
"updatedAt": "2026-08-27T10:16:38.904Z"
}{
"message": "Forbidden resource",
"error": "Forbidden",
"statusCode": 403
}{
"message": "Cannot GET /v1/unknown-route",
"error": "Not Found",
"statusCode": 404
}{
"message": "Too many requests",
"error": "Too Many Requests",
"statusCode": 429
}{
"message": "Internal server error",
"error": "Internal Server Error",
"statusCode": 500
}callback_url webhook — it is safe to call repeatedly, and a request is never charged twice regardless of how often you poll.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The enrichment request _id returned when the request was created. |
Status lifecycle
| Status | Meaning |
|---|---|
pending | Accepted, not yet started. |
processing | The provider waterfall is running. |
completed | The lookup finished — see phone_numbers. (1 credit charged, unless the list came back empty.) |
not-found | Every eligible provider was exhausted without a number that passed validation. No credit charged. |
phone_numbers is returned only on a completed request. Until then the field is an empty array, even if we already hold numbers for that profile from an earlier lookup.Response (200) — completed
{
"_id": "507f1f77bcf86cd799439011",
"linkedin": "https://www.linkedin.com/in/janedoe",
"linkedin_username": "janedoe",
"status": "completed",
"enrichment_type": "contact",
"phone_numbers": [
{
"number": "+14155550123",
"country_code": "US",
"type": "mobile",
"extension": "",
"source": "prospeo",
"validation": {
"phone_number": "+14155550123",
"is_valid": true,
"carrier": "AT&T",
"line_type": "mobile",
"likely_to_answer": "P1",
"score": 92,
"status": "completed"
}
}
],
"createdAt": "2026-08-27T10:15:04.221Z",
"updatedAt": "2026-08-27T10:16:38.904Z"
}
phone_numbers is everything we hold for that LinkedIn profile, not only what this request discovered — a profile enriched twice returns the accumulated list both times.
Phone number object
| Field | Type | Description |
|---|---|---|
number | string | The number in E.164 format. |
country_code | string | ISO 3166-1 alpha-2 country of the number (US, GB, …) — not a dialing prefix. |
type | string | mobile, direct, or office. |
extension | string | Dial extension, empty when there is none. |
source | string | The data provider the number came from. |
validation | object | Result of the phone validation pass — see below. |
Validation object
| Field | Type | Description |
|---|---|---|
phone_number | string | The number that was validated. |
is_valid | boolean | Whether the number passed validation. Numbers that fail are never stored. |
carrier | string | Carrier reported by the validator. |
line_type | string | Line classification, e.g. mobile or landline. |
likely_to_answer | string | Answer-likelihood tier — P1 (best) through P3. |
score | number | Validator confidence score. |
status | string | completed once validation resolved; pending while it is still running. |
landline, and is not tier P3; anything else sends the waterfall on to the next provider. Numbers that were rejected on the way may still appear in the array from earlier passes, so filter on validation rather than assuming every entry is dial-worthy.
Response (200) — still running
{
"_id": "507f1f77bcf86cd799439011",
"linkedin": "https://www.linkedin.com/in/janedoe",
"linkedin_username": "janedoe",
"status": "processing",
"enrichment_type": "contact",
"phone_numbers": [],
"createdAt": "2026-08-27T10:15:04.221Z",
"updatedAt": "2026-08-27T10:15:09.117Z"
}
Errors
| Status | Description |
|---|---|
| 404 | No enrichment request found for the given id |
Authorizations
Team-scoped API key generated in the Salesfinity dashboard under Settings -> Connections & API. A missing or invalid key returns HTTP 403.
Path Parameters
The enrichment request _id returned by POST /v1/api/enrichment/phone.
Response
Current state of the enrichment request.
Enrichment request ID. Use this to poll GET /v1/api/enrichment/phone/{id}, and to match the request_id in the callback.
"507f1f77bcf86cd799439011"
Current state of the request. completed means the waterfall finished; not-found means no number passed validation. Phone enrichment never resolves to failed.
pending, processing, completed, not-found The LinkedIn profile URL the request was created with.
"https://www.linkedin.com/in/username"
The username extracted from the LinkedIn URL.
"username"
Always contact for phone enrichment.
contact Every number held for the profile, not only the ones this request discovered. Populated only when status is completed; an empty array otherwise. Absent from the response to POST /v1/api/enrichment/phone.
Show child attributes
Show child attributes
"2026-08-27T10:15:04.221Z"
"2026-08-27T10:16:38.904Z"