Fetch the full profile object by profileId
.
If your account owns the profile (purchased previously), the response can include contact data (emails/phones).
Base URL: https://api.salescaddy.ai/api
Endpoint
GET /profiles/{profileId}
Path parameters
Name | Type | Required | Description |
---|---|---|---|
profileId | string | Yes | Profile identifier (e.g. prof_001 ) |
Headers
Authorization: Bearer <token>
— required
Contact fields are returned only if your account has access (e.g., via Profiles — Purchase).
Example — Get details (purchased profile)
curl -sS "https://api.salescaddy.ai/api/profiles/prof_001" -H "Authorization: Bearer $TOKEN"
const res = await fetch("https://api.salescaddy.ai/api/profiles/prof_001", {
headers: { Authorization: `Bearer ${process.env.TOKEN}` }
});
console.log(await res.json());
import os, requests
r = requests.get("https://api.salescaddy.ai/api/profiles/prof_001",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"})
print(r.json())
using System.Net.Http.Headers;
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TOKEN);
var res = await http.GetAsync("https://api.salescaddy.ai/api/profiles/prof_001");
Console.WriteLine(await res.Content.ReadAsStringAsync());
Sample response (trimmed):
{
"id": "prof_001",
"fullName": "Alex Johnson",
"title": "VP Data Platform",
"seniority": "VP",
"function": "Data",
"companyName": "Hilton",
"companyDomain": "hilton.com",
"country": "US",
"city": "McLean",
"linkedinUrl": "https://www.linkedin.com/in/alexjohnson/",
"emails": [
{ "value": "[email protected]", "type": "work", "confidence": 0.95, "verified": true }
],
"phones": [
{ "value": "+1-555-123-4567", "type": "work", "confidence": 0.82 }
],
"lastUpdated": "2025-08-15T12:30:00Z"
}
Example — Not purchased yet
If your account hasn’t purchased this profile, the API may return 403 or a summary only (no contact fields), depending on your plan.
curl -sS "https://api.salescaddy.ai/api/profiles/prof_003" -H "Authorization: Bearer $TOKEN" -i
const res = await fetch("https://api.salescaddy.ai/api/profiles/prof_003", {
headers: { Authorization: `Bearer ${process.env.TOKEN}` }
});
console.log(res.status, await res.text());
r = requests.get("https://api.salescaddy.ai/api/profiles/prof_003",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"})
print(r.status_code, r.text)
var res2 = await http.GetAsync("https://api.salescaddy.ai/api/profiles/prof_003");
Console.WriteLine((int)res2.StatusCode + " " + await res2.Content.ReadAsStringAsync());
Possible 403 payload:
{ "status": 403, "error": "Forbidden", "message": "Purchase required for contact details" }
To unlock contact data, call Profiles — Purchase with the
profileId
. Then retry this endpoint.
Working with multiple profiles
Fetch details one by one (recommended for ownership checks and rate control).
If you need to hydrate many IDs, throttle requests and cache results by id
and lastUpdated
.
# bash example (loop)
for id in prof_001 prof_002 prof_003; do
curl -sS "https://api.salescaddy.ai/api/profiles/$id" -H "Authorization: Bearer $TOKEN" | jq -c .
done
// node: throttle with a simple concurrency pool
const ids = ["prof_001","prof_002","prof_003"];
const headers = { Authorization: `Bearer ${process.env.TOKEN}` };
const pmap = (xs, n, f) => {
const q = xs.slice(), active = new Set();
return new Promise((resolve, reject) => {
const out = [];
const run = () => {
if (!q.length && !active.size) return resolve(out);
while (active.size < n && q.length) {
const i = out.length;
const id = q.shift();
const p = fetch(`https://api.salescaddy.ai/api/profiles/${id}`, { headers }).then(r => r.json()).then(x => out[i]=x);
active.add(p);
p.finally(()=>{ active.delete(p); run(); });
}
};
run();
});
};
console.log(await pmap(ids, 3, id => id));
# python: simple rate limiting
import os, time, requests
ids = ["prof_001","prof_002","prof_003"]
for pid in ids:
r = requests.get(f"https://api.salescaddy.ai/api/profiles/{pid}",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"})
print(r.json())
time.sleep(0.25) # throttle
// csharp: sequential for clarity; use Polly for retry/backoff if needed
var ids = new[]{"prof_001","prof_002","prof_003"};
foreach (var id in ids) {
var res3 = await http.GetAsync($"https://api.salescaddy.ai/api/profiles/{id}");
Console.WriteLine(await res3.Content.ReadAsStringAsync());
await Task.Delay(250);
}
Field reference (common)
Field | Type | Notes |
---|---|---|
id | string | Profile identifier |
fullName | string | |
title | string | |
seniority | string | e.g., Manager , Director , VP , C-Level |
function | string | e.g., Data , Engineering , IT , Finance |
companyName | string | |
companyDomain | string | Join key with Company endpoints |
country | string | ISO‑2 |
city | string | |
linkedinUrl | string (url) | |
emails[] | array | Present only if owned; each has value , type , confidence , verified? |
phones[] | array | Present only if owned; each has value , type , confidence |
lastUpdated | string (ISO8601) | For caching/ETag semantics |
The exact schema can evolve; feature‑test field presence instead of hardcoding assumptions.
Security & compliance
- Store only what you need; avoid logging PII (emails/phones).
- Respect local laws (e.g., privacy & communications regulations).
- Implement access controls so only authorized users can view contact data.
- Consider encrypting stored PII at rest; rotate keys regularly.
Errors
Code | Meaning | How to fix |
---|---|---|
400 | Bad request | Validate profileId format. |
401 | Unauthorized | Provide/refresh Bearer token. |
403 | Forbidden | Purchase required or insufficient permissions. |
404 | Not found | Unknown profileId . |
429 | Rate limit exceeded | Retry with exponential backoff; respect Retry-After . |
500 | Internal server error | Retry later; contact support if persistent. |