Profiles - Details

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

NameTypeRequiredDescription
profileIdstringYesProfile 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)

FieldTypeNotes
idstringProfile identifier
fullNamestring
titlestring
senioritystringe.g., Manager, Director, VP, C-Level
functionstringe.g., Data, Engineering, IT, Finance
companyNamestring
companyDomainstringJoin key with Company endpoints
countrystringISO‑2
citystring
linkedinUrlstring (url)
emails[]arrayPresent only if owned; each has value, type, confidence, verified?
phones[]arrayPresent only if owned; each has value, type, confidence
lastUpdatedstring (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

CodeMeaningHow to fix
400Bad requestValidate profileId format.
401UnauthorizedProvide/refresh Bearer token.
403ForbiddenPurchase required or insufficient permissions.
404Not foundUnknown profileId.
429Rate limit exceededRetry with exponential backoff; respect Retry-After.
500Internal server errorRetry later; contact support if persistent.