Retrieve detected technologies and product installs for a company.
Fetch a company’s installed technology stack in three formats (choose what fits your integration):
- CSV export (file).
- JSONL stream.
- Paged JSON.
Use Products‑in‑Use to verify specific product IDs with confidence.
Base URL: https://api.salescaddy.ai/api
Endpoints overview
- CSV —
GET /companies/{companyDomain}/products?export=true
→text/csv
(binary) Requires header:X-On-Behalf-Of-User: <email>
- JSONL —
GET /companies/{companyDomain}/products/json?export=false
→application/jsonl
- Paged JSON —
GET /companies/{companyDomain}/products/paged?page=0&size=20
→application/json
- Verify (deterministic) —
POST /companies/{companyDomain}/products-in-use
(body:{ "productIds": [...] }
)
Path parameter
companyDomain
— e.g.,hilton.com
Common query parameters
page
(int, default0
) — only for paged JSONsize
(int, default20
, max ~200
) — only for paged JSONexport
(bool) —true
for CSV;false
for JSONL (explicit)
CSV — full export (file)
Example CSV Export
curl -sS "https://api.salescaddy.ai/api/companies/hilton.com/products?export=true" -H "Authorization: Bearer $TOKEN" -H "X-On-Behalf-Of-User: [email protected]" --output hilton-products.csv
import fs from "fs";
const url = "https://api.salescaddy.ai/api/companies/hilton.com/products?export=true";
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.TOKEN}`, "X-On-Behalf-Of-User":"[email protected]" }
});
const file = fs.createWriteStream("hilton-products.csv");
await new Promise((resolve, reject) => {
res.body.pipe(file);
res.body.on("error", reject);
file.on("finish", resolve);
});
import os, requests
with requests.get("https://api.salescaddy.ai/api/companies/hilton.com/products",
params={"export":"true"},
headers={"Authorization": f"Bearer {os.environ['TOKEN']}",
"X-On-Behalf-Of-User":"[email protected]"},
stream=True) as r:
r.raise_for_status()
with open("hilton-products.csv","wb") as f:
for chunk in r.iter_content(8192):
if chunk: f.write(chunk)
using System.Net.Http.Headers;
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TOKEN);
http.DefaultRequestHeaders.Add("X-On-Behalf-Of-User","[email protected]");
var bytes = await http.GetByteArrayAsync("https://api.salescaddy.ai/api/companies/hilton.com/products?export=true");
System.IO.File.WriteAllBytes("hilton-products.csv", bytes);
CSV snippet (sample):
companyDomain,productId,productName,vendorDomain,category,categoryId,intensity
hilton.com,prod_office365,Microsoft 365,microsoft.com,Productivity,cat_productivity,0.78
hilton.com,prod_slack,Slack,salesforce.com,Collaboration,cat_collab,0.55
CSV is ideal for bulk analytics and offline processing. Exports are attributed to the user in
X-On-Behalf-Of-User
.
JSONL — stream (line‑delimited JSON)
Example JSONL
curl -sS "https://api.salescaddy.ai/api/companies/hilton.com/products/json?export=false" -H "Authorization: Bearer $TOKEN"
const url = "https://api.salescaddy.ai/api/companies/hilton.com/products/json?export=false";
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.TOKEN}` } });
console.log((await res.text()).split("\n").slice(0,3)); // first 3 lines
import os, requests
r = requests.get("https://api.salescaddy.ai/api/companies/hilton.com/products/json",
params={"export":"false"},
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"})
print("\n".join(r.text.splitlines()[:3]))
var res = await http.GetAsync("https://api.salescaddy.ai/api/companies/hilton.com/products/json?export=false");
var text = await res.Content.ReadAsStringAsync();
Console.WriteLine(text.Split('\n')[0]); // first line
JSONL snippet (sample):
{"companyDomain":"hilton.com","productId":"prod_office365","productName":"Microsoft 365","vendorDomain":"microsoft.com","intensity":0.78}
{"companyDomain":"hilton.com","productId":"prod_slack","productName":"Slack","vendorDomain":"salesforce.com","intensity":0.55}
JSONL is great for streaming pipelines and incremental ingestion.
Paged JSON — standard API
Example Paged JSON
curl -sS "https://api.salescaddy.ai/api/companies/hilton.com/products/paged?page=0&size=20" -H "Authorization: Bearer $TOKEN"
const url = "https://api.salescaddy.ai/api/companies/hilton.com/products/paged?page=0&size=20";
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.TOKEN}` } });
console.log(await res.json());
import os, requests
r = requests.get("https://api.salescaddy.ai/api/companies/hilton.com/products/paged",
params={"page":0,"size":20},
headers={"Authorization": f"Bearer {os.environ['TOKEN']}"})
print(r.json())
var res = await http.GetAsync("https://api.salescaddy.ai/api/companies/hilton.com/products/paged?page=0&size=20");
Console.WriteLine(await res.Content.ReadAsStringAsync());
Sample response (trimmed):
{
"totalPages": 12,
"totalElements": 237,
"content": [
{ "companyDomain":"hilton.com", "productId":"prod_office365", "productName":"Microsoft 365", "vendorDomain":"microsoft.com", "category":"Productivity", "categoryId":"cat_productivity", "intensity":0.78 },
{ "companyDomain":"hilton.com", "productId":"prod_slack", "productName":"Slack", "vendorDomain":"salesforce.com", "category":"Collaboration", "categoryId":"cat_collab", "intensity":0.55 }
]
}
Prefer multiple pages over very large
size
values; this reduces timeouts and avoids 429s.
Verify products in use (deterministic)
Send a list of product IDs to confirm whether they are used by the company. The response includes confidence (0.0–1.0) per product.
Endpoint: POST /companies/{companyDomain}/products-in-use
Body (JSON):
{ "productIds": ["prod_office365", "prod_slack"] }
Example Products‑in‑Use
curl -sS -X POST "https://api.salescaddy.ai/api/companies/hilton.com/products-in-use" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{ "productIds": ["prod_office365","prod_slack"] }'
const res = await fetch("https://api.salescaddy.ai/api/companies/hilton.com/products-in-use", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.TOKEN}`, "Content-Type":"application/json" },
body: JSON.stringify({ productIds:["prod_office365","prod_slack"] })
});
console.log(await res.json());
import os, requests
r = requests.post("https://api.salescaddy.ai/api/companies/hilton.com/products-in-use",
headers={"Authorization": f"Bearer {os.environ['TOKEN']}", "Content-Type":"application/json"},
json={"productIds":["prod_office365","prod_slack"]})
print(r.json())
using System.Text;
var payload = new StringContent("{"productIds":["prod_office365","prod_slack"]}", Encoding.UTF8, "application/json");
var res = await http.PostAsync("https://api.salescaddy.ai/api/companies/hilton.com/products-in-use", payload);
Console.WriteLine(await res.Content.ReadAsStringAsync());
Sample response (trimmed):
[
{ "productId":"prod_office365", "inUse": true, "confidence": 0.93 },
{ "productId":"prod_slack", "inUse": false, "confidence": 0.21 }
]
Use this endpoint to validate AI leads or to gate actions that require high confidence.
Tips & best practices
- Choose CSV for bulk analytics, JSONL for streaming, Paged JSON for interactive apps.
- Reuse
productId
andcategoryId
across search and metrics endpoints. - Handle 401/429/5xx with retries (see Errors & Rate Limits).
- For exports, always pass
X-On-Behalf-Of-User
and store files with timestamps/versioning.
Errors
Code | Meaning | How to fix |
---|---|---|
400 | Bad request | Validate path/query/body; check page/size are integers (when used). |
401 | Unauthorized | Provide/refresh Bearer token. |
403 | Forbidden | Check permissions; for CSV include X-On-Behalf-Of-User . |
404 | Not found | Unknown companyDomain or no products present. |
429 | Rate limit exceeded | Retry with exponential backoff; respect Retry-After . |
500 | Internal server error | Retry later; contact support if persistent. |