Dedup
curl --request POST \
--url https://api.opennous.cloud/v2/dedup \
--header 'Content-Type: application/json' \
--data '
{
"emails": [
"<string>"
],
"linkedin_urls": [
"<string>"
]
}
'import requests
url = "https://api.opennous.cloud/v2/dedup"
payload = {
"emails": ["<string>"],
"linkedin_urls": ["<string>"]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({emails: ['<string>'], linkedin_urls: ['<string>']})
};
fetch('https://api.opennous.cloud/v2/dedup', 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.opennous.cloud/v2/dedup",
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([
'emails' => [
'<string>'
],
'linkedin_urls' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$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.opennous.cloud/v2/dedup"
payload := strings.NewReader("{\n \"emails\": [\n \"<string>\"\n ],\n \"linkedin_urls\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
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.opennous.cloud/v2/dedup")
.header("Content-Type", "application/json")
.body("{\n \"emails\": [\n \"<string>\"\n ],\n \"linkedin_urls\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.opennous.cloud/v2/dedup")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"emails\": [\n \"<string>\"\n ],\n \"linkedin_urls\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodySearch
Dedup
Cross-list cold-outbound dedup. Classify identifiers as net_new / engaged / bounced / unsubscribed BEFORE you spend.
POST
/
v2
/
dedup
Dedup
curl --request POST \
--url https://api.opennous.cloud/v2/dedup \
--header 'Content-Type: application/json' \
--data '
{
"emails": [
"<string>"
],
"linkedin_urls": [
"<string>"
]
}
'import requests
url = "https://api.opennous.cloud/v2/dedup"
payload = {
"emails": ["<string>"],
"linkedin_urls": ["<string>"]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({emails: ['<string>'], linkedin_urls: ['<string>']})
};
fetch('https://api.opennous.cloud/v2/dedup', 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.opennous.cloud/v2/dedup",
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([
'emails' => [
'<string>'
],
'linkedin_urls' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$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.opennous.cloud/v2/dedup"
payload := strings.NewReader("{\n \"emails\": [\n \"<string>\"\n ],\n \"linkedin_urls\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
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.opennous.cloud/v2/dedup")
.header("Content-Type", "application/json")
.body("{\n \"emails\": [\n \"<string>\"\n ],\n \"linkedin_urls\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.opennous.cloud/v2/dedup")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"emails\": [\n \"<string>\"\n ],\n \"linkedin_urls\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodyThe “pre-flight before you pay” check. You’re about to scrape 10k leads on Apollo for $300 — paste in the LinkedIn URLs (visible for free in Apollo’s preview), get back which ones you already have. Buy only the difference.
You can also pass
At least one of the two is required. The API chunks internally, so there’s no URL-length cap to worry about.
Request
curl -X POST https://api.opennous.cloud/v2/dedup \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"linkedin_urls": [
"https://linkedin.com/in/sarah-chen-vp",
"https://linkedin.com/in/jamie-doe"
]
}'
emails, or both:
{
"emails": ["sarah@acme.com", "jamie@beta.com"],
"linkedin_urls": ["https://linkedin.com/in/sarah-chen-vp"]
}
Body
string[]
Up to 50,000 emails per call.
string[]
Up to 50,000 LinkedIn URLs per call.
Response
{
"results": [
{
"kind": "linkedin_url",
"value": "https://linkedin.com/in/sarah-chen-vp",
"status": "engaged",
"entity_id": "a1b2c3d4-...",
"reason": "In active conversation — last touch 4 days ago"
},
{
"kind": "linkedin_url",
"value": "https://linkedin.com/in/jamie-doe",
"status": "net_new"
}
],
"summary": {
"net_new": 1,
"engaged": 1,
"recent": 0,
"bounced": 0,
"unsubscribed": 0,
"suppressed": 0,
"total": 2
}
}
Status values
| Status | Meaning | What to do |
|---|---|---|
net_new | No prior record. | Safe to send / safe to buy. |
engaged | In an active conversation. | Don’t cold-send. |
recent | Contacted in the last 30 days. | Defer. |
bounced | Last delivery bounced (email-only). | Skip. |
unsubscribed | Opted out or marked do-not-contact. | Skip. |
suppressed | Workspace-level suppression policy. | Skip. |
Authentication note
Unlike the other v2 endpoints,/v2/dedup also accepts the workspace JWT — so the in-app Lists page can call it without going through the API key. External integrations use the API key as normal.
When to call it
- Before paying Apollo for a list reveal — classify the LinkedIn URLs first
- As a CSV pre-flight in your own workflow — drop a 5k-row list, send only the
net_newrows - In a workspace audit — how much of last quarter’s $X list spend was already in our pipeline?