Match Prospects
curl --request POST \
--url https://api.explorium.ai/v1/prospects/match \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"prospects_to_match": [
{
"business_id": null,
"full_name": null,
"company_name": null,
"email": null,
"phone_number": null,
"linkedin": null
}
],
"request_context": null
}
'import requests
url = "https://api.explorium.ai/v1/prospects/match"
payload = {
"prospects_to_match": [
{
"business_id": None,
"full_name": None,
"company_name": None,
"email": None,
"phone_number": None,
"linkedin": None
}
],
"request_context": None
}
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prospects_to_match: [
{
business_id: null,
full_name: null,
company_name: null,
email: null,
phone_number: null,
linkedin: null
}
],
request_context: null
})
};
fetch('https://api.explorium.ai/v1/prospects/match', 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://api.explorium.ai/v1/prospects/match",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prospects_to_match' => [
[
'business_id' => null,
'full_name' => null,
'company_name' => null,
'email' => null,
'phone_number' => null,
'linkedin' => null
]
],
'request_context' => null
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.explorium.ai/v1/prospects/match"
payload := strings.NewReader("{\n \"prospects_to_match\": [\n {\n \"business_id\": null,\n \"full_name\": null,\n \"company_name\": null,\n \"email\": null,\n \"phone_number\": null,\n \"linkedin\": null\n }\n ],\n \"request_context\": null\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("api_key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.explorium.ai/v1/prospects/match")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"prospects_to_match\": [\n {\n \"business_id\": null,\n \"full_name\": null,\n \"company_name\": null,\n \"email\": null,\n \"phone_number\": null,\n \"linkedin\": null\n }\n ],\n \"request_context\": null\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.explorium.ai/v1/prospects/match")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prospects_to_match\": [\n {\n \"business_id\": null,\n \"full_name\": null,\n \"company_name\": null,\n \"email\": null,\n \"phone_number\": null,\n \"linkedin\": null\n }\n ],\n \"request_context\": null\n}"
response = http.request(request)
puts response.read_body{
"response_context": {
"correlation_id": "<string>",
"request_status": "success",
"time_took_in_seconds": 123
},
"total_results": 123,
"total_matches": 1,
"matched_prospects": [
{
"input": {
"business_id": null,
"full_name": null,
"company_name": null,
"email": null,
"phone_number": null,
"linkedin": null
},
"error": "<string>",
"error_type": "<string>",
"prospect_id": "<string>"
}
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Prospects
Match prospects
Match a list of prospect attributes to Prospect IDs. Returns a list of the same length and order as the input list, with the matched IDs.
POST
/
v1
/
prospects
/
match
Match Prospects
curl --request POST \
--url https://api.explorium.ai/v1/prospects/match \
--header 'Content-Type: application/json' \
--header 'api_key: <api-key>' \
--data '
{
"prospects_to_match": [
{
"business_id": null,
"full_name": null,
"company_name": null,
"email": null,
"phone_number": null,
"linkedin": null
}
],
"request_context": null
}
'import requests
url = "https://api.explorium.ai/v1/prospects/match"
payload = {
"prospects_to_match": [
{
"business_id": None,
"full_name": None,
"company_name": None,
"email": None,
"phone_number": None,
"linkedin": None
}
],
"request_context": None
}
headers = {
"api_key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {api_key: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prospects_to_match: [
{
business_id: null,
full_name: null,
company_name: null,
email: null,
phone_number: null,
linkedin: null
}
],
request_context: null
})
};
fetch('https://api.explorium.ai/v1/prospects/match', 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://api.explorium.ai/v1/prospects/match",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prospects_to_match' => [
[
'business_id' => null,
'full_name' => null,
'company_name' => null,
'email' => null,
'phone_number' => null,
'linkedin' => null
]
],
'request_context' => null
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.explorium.ai/v1/prospects/match"
payload := strings.NewReader("{\n \"prospects_to_match\": [\n {\n \"business_id\": null,\n \"full_name\": null,\n \"company_name\": null,\n \"email\": null,\n \"phone_number\": null,\n \"linkedin\": null\n }\n ],\n \"request_context\": null\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("api_key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.explorium.ai/v1/prospects/match")
.header("api_key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"prospects_to_match\": [\n {\n \"business_id\": null,\n \"full_name\": null,\n \"company_name\": null,\n \"email\": null,\n \"phone_number\": null,\n \"linkedin\": null\n }\n ],\n \"request_context\": null\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.explorium.ai/v1/prospects/match")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["api_key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prospects_to_match\": [\n {\n \"business_id\": null,\n \"full_name\": null,\n \"company_name\": null,\n \"email\": null,\n \"phone_number\": null,\n \"linkedin\": null\n }\n ],\n \"request_context\": null\n}"
response = http.request(request)
puts response.read_body{
"response_context": {
"correlation_id": "<string>",
"request_status": "success",
"time_took_in_seconds": 123
},
"total_results": 123,
"total_matches": 1,
"matched_prospects": [
{
"input": {
"business_id": null,
"full_name": null,
"company_name": null,
"email": null,
"phone_number": null,
"linkedin": null
},
"error": "<string>",
"error_type": "<string>",
"prospect_id": "<string>"
}
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Introduction
The Match Prospects endpoint allows users to accurately match individual prospects to unique Prospect IDs using multiple fetchers, such as email, phone number, LinkedIn profile, or name and company combination. This ensures accurate lead identification and enhances sales and marketing workflows. Key Benefits:- Match and validate lead data across multiple fetchers.
- Enhance B2B prospecting by linking leads to business profiles.
- Improve lead scoring and segmentation with high-quality matches.
- Reduce data duplication and inconsistencies.
Endpoint: POST /v1/prospects/match
How Matching Works: The Waterfall
Matching is not a single lookup — each record you send runs through a sequential matching waterfall. Identifiers are attempted in a fixed priority order, from the most reliable to the least. As soon as a record matches at a step, it is resolved and removed from the waterfall; later steps only apply to records that are still unmatched.| Priority | Match step | Fields passed (in order) | Notes |
|---|---|---|---|
| 1 | business_id → linkedin | Highest-confidence identifier — always attempted first | |
| 2 | business_id → email | ||
| 3 | Phone | business_id → phone_number | |
| 4 | Name + company | business_id → company_name → full_name | Requires bothfull_name and company_name |
| 5 | Name + business ID | business_id → full_name | Runs only when business_id is provided in the record |
business_id is supplementary context, not a required identifier. When provided, it is applied at every waterfall step to scope the match to a specific company, which improves precision. It is never used to match a prospect on its own.What is never matched:
full_nameon its own — full name is only matched together withcompany_name(step 4) orbusiness_id(step 5). A record containing onlyfull_namealways returnsprospect_id: null.company_nameon its own — company name is only used in combination withfull_name.business_idon its own — it scopes a match to a company but cannot identify a prospect by itself.
- If a record contains multiple identifiers (e.g., both
linkedinandemail), it is matched at the highest-priority step that succeeds — in this example, LinkedIn is attempted first, and email is only tried if the LinkedIn match fails. - Each record is matched at most once. Once matched, it does not continue to lower-priority steps.
- Adding
business_idnever hurts — it refines every step it participates in.
How It Works
How It Works
- Input: Provide a list of prospects with at least one fetcher (e.g., email, phone number, LinkedIn URL, or name & company).
- Processing: Each record runs through the matching waterfall described above — identifiers are attempted in priority order (LinkedIn → email → phone → name & company → name & business ID), and a record exits the waterfall as soon as it matches.
- Output: A structured response with matched Prospect IDs, maintaining the same order as the input list. Records that cannot be matched return
prospect_id: null.
Request Schema
Request Schema
| Field | Type | Description |
|---|---|---|
| prospects_to_match: | Array | A list of prospect fetchers to match |
linkedin | String | LinkedIn profile URL — the highest-priority identifier in the matching waterfall |
email | String | The prospect’s email address |
phone_number | String | The prospect’s phone number |
full_name | String | The prospect’s full name — must be accompanied by company_name or business_id; never matched on its own |
company_name | String | The prospect’s company name — only used in combination with full_name |
business_id (optional) | String | Scopes the match to a specific company at every waterfall step; supplementary context, not a standalone identifier |
Example Request (cURL)
Example Request (cURL)
Bash
curl -X POST "https://api.explorium.ai/v1/prospects/match" \
-H "API_KEY: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"request_context": {},
"prospects_to_match": [
{
"business_id": "19fbe842a2e51db95d4f92333f2cc63a",
"linkedin": "https://www.linkedin.com/in/russell-lumpkin-07585b128"
},
{
"full_name": "Richard Branson",
"company_name": "Virgin"
},
{
"email": "satyan@microsoft.com"
},
{
"full_name": "John Smith"
}
]
}'
Example Response
Example Response
Note the fourth record: it contains only
full_name, so it never enters any waterfall step and returns prospect_id: null.JSON
{
"response_context": {
"correlation_id": "68d2e054ffa149dab8d09c59f1092091",
"request_status": "success",
"time_took_in_seconds": 0
},
"total_results": 4,
"total_matches": 3,
"matched_prospects": [
{
"input": {
"business_id": "19fbe842a2e51db95d4f92333f2cc63a",
"full_name": null,
"company_name": null,
"email": null,
"phone_number": null,
"linkedin": "https://www.linkedin.com/in/russell-lumpkin-07585b128"
},
"prospect_id": "6ffd52c681452e2da8aac7ec3efb174f4604734c"
},
{
"input": {
"business_id": null,
"full_name": "Richard Branson",
"company_name": "Virgin",
"email": null,
"phone_number": null,
"linkedin": null
},
"prospect_id": "46ab818ec439a76489024b5727abdf194dfa3329"
},
{
"input": {
"business_id": null,
"full_name": null,
"company_name": null,
"email": "satyan@microsoft.com",
"phone_number": null,
"linkedin": null
},
"prospect_id": "f80a80fb6b3d55dfefd269bb35c2049e050876ae"
},
{
"input": {
"business_id": null,
"full_name": "John Smith",
"company_name": null,
"email": null,
"phone_number": null,
"linkedin": null
},
"prospect_id": null
}
]
}
Best Practices
Best Practices
- Provide the strongest identifier you have. LinkedIn URLs match with the highest confidence, followed by email and phone. Name-based matching is the last resort in the waterfall.
- Use multiple fetchers whenever possible — the waterfall automatically uses the highest-priority one that succeeds.
- Combine with
business_idto refine matches to a specific company — it improves precision at every step, and it is required for matching onfull_namewithout acompany_name. - Never send
full_namealone — it will always returnnull. Pair it withcompany_nameorbusiness_id. - Ensure accurate and up-to-date data for improved results.
- Handle
nullvalues in responses where no match is found. - Use the input field when sending multiple queries to match your queries with the results.
Rate limits are counted per query, not per request. Each prospect in the
prospects_to_match array counts as a separate query toward your rate limit. A single request that matches 50 prospects consumes 50 queries from your 200-queries-per-minute limit — not 1. Batching reduces HTTP/network overhead, but it does not reduce the number of queries counted against your rate limit. Size your batches accordingly.Authorizations
APIKeyHeaderAPIKeyHeader
Body
application/json
Response
Successful Response
This is base response model for all responses in partner service.
Show child attributes
Show child attributes
The total_results number matched prospects
The total number of matches.
Required range:
x >= 0A list of matched prospects ids represented by MD5 hashes. May contain None for unmatched items.
- ProspectMatchOutputWithError
- ProspectMatchOutput
Show child attributes
Show child attributes
Was this page helpful?