Pearl Diver's REST API gives you access to your Pearl Diver data outside the web app, for integrations with CRMs, marketing automation platforms, analytics tools, reporting systems, and more.
✅ Prerequisites
- A valid Pearl Diver account, and OAuth client credentials (client ID and secret) for the API.
- A developer or development agency with experience building API integrations.
- Each audience you want to query connected to the REST API integration in your Pearl Diver account. An audience that isn't connected won't return data.
🔐 Authentication
The API uses OAuth 2.0, the standard protocol for letting a third-party application access user data without exposing credentials. The flow has four steps.
- Request authorization — Redirect the user to Pearl Diver's authorization endpoint with your requested scopes (
openid,profile,email,offline_access):GET https://auth.pearldiver.io/authorize?audience=pearldiverapi&response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=openid%20profile%20email%20offline_access&state=csrf_token - User authenticates — The user logs in and grants or denies access. On approval, they're redirected back to your redirect URI with an authorization code:
YOUR_REDIRECT_URI?code=AUTHORIZATION_CODE&state=csrf_token - Exchange the code for a token — Send the code, along with your client ID and secret, to the token endpoint:
POST https://auth.pearldiver.io/oauth/token?audience=pearldiverapi Content-Type: application/x-www-form-urlencoded grant_type=authorization_code code=AUTHORIZATION_CODE client_id=YOUR_CLIENT_ID client_secret=YOUR_CLIENT_SECRET redirect_uri=YOUR_REDIRECT_URI - Call the API — Include the access token in the
Authorizationheader of every request:GET https://api.pearldiver.io/v1/resource Authorization: Bearer ACCESS_TOKEN
Refreshing the access token
Access tokens expire. Use your refresh token to get a new one without asking the user to log in again:
POST https://auth.pearldiver.io/oauth/token?audience=pearldiverapi
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
refresh_token=REFRESH_TOKEN
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET
The response includes a new access token and a new refresh token. Store both securely; this is what lets your application keep working without the user having to sign in again.
Authorization and status codes
Authorization follows the user from the authentication step; they must have a valid Pearl Diver account. The API uses standard HTTP status codes, and error responses (400s, 500s) come back with no response body.
Using the REST API
The API has two endpoints. Every request needs these headers: Authorization: Bearer <access_token>, Content-Type: application/json, and Accept: application/json. The API only accepts and returns JSON.
1. List audiences
GET /v1/audience
Returns every audience in your account. Takes no parameters. A 200 OK returns an audiences array, where each item has a key (integer) and a name (string). A 400 Bad Request means the list couldn't be retrieved.
Example response:
{
"audiences": [
{ "key": 2, "name": "Hot leads" },
{ "key": 0, "name": "Pearls" }
]
}
Example request (Node.js with Axios):
const axios = require('axios');
const options = {
url: 'https://api.pearldiver.io/v1/audience',
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${access_token}`
}
};
axios(options)
.then((response) => {
if (response.status !== 200) {
throw new Error(`HTTP Error: ${response.status}`);
}
return response.data;
})
.then((results) => {
console.log(results);
return results;
})
.catch((error) => {
console.error(error);
});
2. Get an audience
GET /v1/audience/{audienceKey}
Returns a single audience, including its records. Call List Audiences first to get the exact audienceKey values your account can access; only those keys work here. A 400 usually means the key doesn't exist or isn't connected to the REST API for your account.
Path parameter: audienceKey (integer, required).
Query parameters:
- range (integer, optional) — period in days to retrieve, 1 to 90. Defaults to 90.
- since (datetime, optional) — ISO 8601 timestamp to retrieve data from. Can't be combined with
range, and can't go back further than 90 days. With neither set, you get the last 90 days. - pageToken (string, optional) — fetches the next page of records. Omit it for the first 1,000 records. If an audience has more, the response includes a
pageTokento pass on your next request.
A 200 OK returns an Audience object: key and name (required), an optional pageToken when more data is available, and a data array of records. A 400 Bad Request means the audience couldn't be retrieved; a 404 Not Found means the key doesn't exist.
Record fields
Only id is guaranteed on a record. Every other field is optional and appears when the data is available.
- Person — id (required), firstName, lastName, email, linkedIn.
- Job — jobTitle, seniorityLevel, department.
- Demographics — gender, ageRange, incomeRange, homeowner, married, children, netWorth.
- Email quality — emailValidationStatus, emailLastSeen.
- Activity — count, latestActivityDate, hotlistType.
- Nested collections — phones (array of Phone), addresses (array of Address), company (object), websites (array of string), sessions (array of Session).
Example request that follows pagination automatically until every record is collected:
const axios = require('axios'); // Make sure to install Axios if you haven't already.
const options = {
url: `https://api.pearldiver.io/v1/audience/${audienceKey}`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${access_token}`
},
params: {}
};
let results = {};
let nextPage = null; // Pagination token, starts empty.
async function fetchPage() {
if (nextPage !== null) {
options.params.pageToken = nextPage;
}
try {
const response = await axios(options);
if (response.status !== 200) {
throw new Error(`HTTP Error: ${response.status}`);
}
const data = response.data;
results.data = (results.data || []).concat(data.data || []);
nextPage = data.pageToken || null;
if (nextPage) {
await fetchPage();
}
} catch (error) {
console.error(error);
}
}
fetchPage().then(() => console.log(results));
Need help? Visit the Pearl Diver Help Centre or book a support session with the team.
