Company - Products

Retrieve detected technologies and product installs for a company.

Fetch a company’s installed technology stack in three formats (choose what fits your integration):

  1. CSV export (file).
  2. JSONL stream.
  3. Paged JSON.

Use Products‑in‑Use to verify specific product IDs with confidence.

Base URL: https://api.salescaddy.ai/api


Endpoints overview

  • CSVGET /companies/{companyDomain}/products?export=truetext/csv (binary) Requires header: X-On-Behalf-Of-User: <email>
  • JSONLGET /companies/{companyDomain}/products/json?export=falseapplication/jsonl
  • Paged JSONGET /companies/{companyDomain}/products/paged?page=0&size=20application/json
  • Verify (deterministic)POST /companies/{companyDomain}/products-in-use (body: { "productIds": [...] })

Path parameter

  • companyDomain — e.g., hilton.com

Common query parameters

  • page (int, default 0) — only for paged JSON
  • size (int, default 20, max ~200) — only for paged JSON
  • export (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 and categoryId 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

CodeMeaningHow to fix
400Bad requestValidate path/query/body; check page/size are integers (when used).
401UnauthorizedProvide/refresh Bearer token.
403ForbiddenCheck permissions; for CSV include X-On-Behalf-Of-User.
404Not foundUnknown companyDomain or no products present.
429Rate limit exceededRetry with exponential backoff; respect Retry-After.
500Internal server errorRetry later; contact support if persistent.