VendorStacks
← All posts
Engineering6 min read

Building Vendor Intelligence Into Sales Tools: A Technical Implementation Guide

How to embed real-time tech stack detection into your sales workflow using the VendorStacks API, with code examples for common integration patterns.

Stax
VendorStacks research desk

Why Embed Tech Stack Data in Sales Tools

Most sales teams manually research prospects by visiting websites, checking job postings, and scrolling LinkedIn. This process breaks down at scale. If you're building a sales tool, CRM extension, or lead enrichment pipeline, exposing which vendors a company uses—extracted from their public web presence—turns qualification from guesswork into data.

The VendorStacks API returns a company's vendor stack by scanning their public domain. A single GET request to /v1/check?url=example.com returns vendors across 24 categories (payments, CRM, analytics, AI/ML, cloud infrastructure, etc.), the specific URLs where each vendor was detected, and confidence scores. This guide shows how to integrate that capability into sales tooling.

API Fundamentals

Base URL: https://api.vendorstacks.com

Authentication uses Bearer tokens in the Authorization header. Generate a key instantly via POST /v1/keys—you get 25 free credits, no signup friction.

curl -X POST https://api.vendorstacks.com/v1/keys

Response:

{
  "api_key": "vr_live_abc123...",
  "credit_balance": 25
}

Pricing is pure usage: 1 credit per successful lookup. If a scan finds no evidence or fails, you pay nothing. Lookups that return empty vendor stacks cost 0 credits. Credit packs start at $10 for 1,100 credits.

Core Endpoint: Check a Company's Stack

GET /v1/check?url={domain} is the workhorse. If the domain is already indexed (under 1 second response), you get cached data. If not, the API triggers a live scan that completes in 15-90 seconds.

import requests

headers = {"Authorization": "Bearer vr_live_your_key_here"}
response = requests.get(
    "https://api.vendorstacks.com/v1/check?url=stripe.com",
    headers=headers
)
data = response.json()

if data["found"]:
    for category, vendors in data["vendor_stack"].items():
        if vendors:
            print(f"{category}: {', '.join(vendors)}")
else:
    print("No vendor evidence located")

Key response fields:

  • vendor_stack: Dictionary with 24 category keys (e.g., payments, crm_sales, ai_ml). Each maps to a list of detected vendors.
  • {category}_evidence: For each category with findings, a list of objects containing vendor, url (the page where detected), and source_row (the quoted HTML/text that triggered detection).
  • vendor_confidence: Confidence scores per vendor.
  • scanned_at: ISO timestamp of when the scan ran.
  • credits_used: Always 0 or 1 for this endpoint.
  • credit_balance: Your remaining credits after this call.
  • found: Boolean. false means no public evidence was located—not that the company uses nothing, just that we found no signals.

Integration Pattern 1: Enrich CRM Records on Demand

When a rep views a lead in your CRM, fetch the tech stack in real time and display it in a sidebar. Use the indexed check for speed; fall back to a live scan if needed.

// Example: Salesforce Lightning Component or HubSpot UI extension
async function enrichLead(domain) {
  const response = await fetch(
    `https://api.vendorstacks.com/v1/check?url=${domain}`,
    { headers: { Authorization: `Bearer ${API_KEY}` } }
  );
  const data = await response.json();

  if (!data.found) {
    return { message: "No vendor data available" };
  }

  // Extract key categories for display
  const stack = {
    payments: data.vendor_stack.payments || [],
    crm: data.vendor_stack.crm_sales || [],
    analytics: data.vendor_stack.analytics_data || [],
  };

  return stack;
}

Display these in your UI as tags or a table. Reps immediately know if the prospect uses Stripe, Salesforce, Google Analytics—context that shapes their pitch.

Integration Pattern 2: Batch Enrichment for Lead Lists

If you're processing a CSV of 500 domains, loop through /v1/check calls. The API has no explicit rate limit documented, but adding a small delay (100-200ms) between requests is polite.

import time
import csv

domains = ["example.com", "anotherco.io", "startup.com"]
results = []

for domain in domains:
    response = requests.get(
        f"https://api.vendorstacks.com/v1/check?url={domain}",
        headers={"Authorization": f"Bearer {API_KEY}"}
    )
    data = response.json()
    results.append({
        "domain": domain,
        "uses_stripe": "Stripe" in data.get("vendor_stack", {}).get("payments", []),
        "uses_salesforce": "Salesforce" in data.get("vendor_stack", {}).get("crm_sales", []),
        "scanned_at": data.get("scanned_at"),
    })
    time.sleep(0.15)  # respectful spacing

# Write to CSV or load into your database
with open("enriched_leads.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["domain", "uses_stripe", "uses_salesforce", "scanned_at"])
    writer.writeheader()
    writer.writerows(results)

You pay only for successful lookups. If 50 domains return no vendor data, you're charged for 450 credits, not 500.

Integration Pattern 3: Reverse Lookup for Prospect Building

GET /v1/prospect?vendor={vendor_name} returns companies using a specific vendor. This is the inverse operation: instead of "what does Company X use?", it answers "who uses Vendor Y?"

Example: find companies using Snowflake.

curl -H "Authorization: Bearer vr_live_..." \
  "https://api.vendorstacks.com/v1/prospect?vendor=Snowflake"

Response (10 results per page):

{
  "vendor": "Snowflake",
  "companies": [
    {"domain": "company1.com", "scanned_at": "2025-01-15T10:00:00Z"},
    {"domain": "company2.io", "scanned_at": "2025-01-14T08:30:00Z"}
  ],
  "credits_used": 2,
  "credit_balance": 1098
}

You're charged 1 credit per company returned. An empty result set costs 0.

This is powerful for GTM teams: "Show me all companies in our index using OpenAI." As of this writing, our index contains 115 companies using OpenAI, 169 using Stripe, 130 using Snowflake, and 112 using Salesforce across a total index of 1,000 companies and 321 distinct vendors.

Handling Live Scans vs. Indexed Data

If a domain isn't indexed, /v1/check triggers a live scan. The response will include "status": "scanning" initially. Poll the endpoint every 5 seconds until scanned_at is populated.

def wait_for_scan(domain, max_wait=120):
    start = time.time()
    while time.time() - start < max_wait:
        response = requests.get(
            f"https://api.vendorstacks.com/v1/check?url={domain}",
            headers={"Authorization": f"Bearer {API_KEY}"}
        )
        data = response.json()
        if data.get("scanned_at"):
            return data
        time.sleep(5)
    raise TimeoutError(f"Scan for {domain} exceeded {max_wait}s")

For real-time UI contexts (e.g., a Chrome extension), show a loading spinner during the scan. For batch jobs, you can fire the request and come back later—use GET /v1/company/{domain} to retrieve results without triggering a new scan.

Checking Credit Balance

GET /v1/balance returns your current credits. Useful for showing remaining capacity in your app's settings page.

curl -H "Authorization: Bearer vr_live_..." \
  https://api.vendorstacks.com/v1/balance
{"credit_balance": 823}

Real-World Use Case: Targeting OpenAI Users

Suppose you sell GPU infrastructure and want to reach companies using OpenAI. Use /v1/prospect?vendor=OpenAI, then enrich each result with /v1/check to see their full stack—maybe they also use AWS (282 companies in our index) or Google Cloud (133 companies), which informs your messaging about cloud portability.

# Step 1: Find OpenAI users
prospects = requests.get(
    "https://api.vendorstacks.com/v1/prospect?vendor=OpenAI",
    headers={"Authorization": f"Bearer {API_KEY}"}
).json()["companies"]

# Step 2: Enrich with full stack to find AWS overlap
for company in prospects:
    full_stack = requests.get(
        f"https://api.vendorstacks.com/v1/check?url={company['domain']}",
        headers={"Authorization": f"Bearer {API_KEY}"}
    ).json()
    if "AWS" in full_stack.get("vendor_stack", {}).get("cloud_infra", []):
        print(f"{company['domain']} uses OpenAI + AWS")

You now have a list of prospects using both technologies, qualified by public evidence.

Common Patterns for Evidence Display

The *_evidence fields show exactly where each vendor was detected. This builds trust—your reps aren't blindly claiming "they use Stripe," they can point to the pricing page URL.

if data["found"] and data.get("payments_evidence"):
    for item in data["payments_evidence"]:
        print(f"{item['vendor']} detected at {item['url']}")
        print(f"Source: {item['source_row'][:100]}...")  # first 100 chars

Example output:

Stripe detected at https://example.com/pricing
Source: <script src="https://js.stripe.com/v3/"></script>...

This is useful in audit trails or for training ML models on vendor adoption signals.

What the API Does Not Do

Be precise about scope when building on this:

  • It does not analyze payment flows, phone-number routing, or network traffic. Detection is based on public web content—HTML, JavaScript, meta tags, job postings.
  • It does not provide real-time monitoring or alerts when a company adds/removes a vendor. Data is point-in-time from the scanned_at timestamp.
  • "found": false means no public evidence was located, not a guarantee the company uses nothing. Private infrastructure or vendors with no public footprint won't appear.

Getting Started

Generate a key and run your first check:

# Get a key
curl -X POST https://api.vendorstacks.com/v1/keys

# Check a domain
curl -H "Authorization: Bearer vr_live_your_key" \
  "https://api.vendorstacks.com/v1/check?url=shopify.com"

You'll see the vendor stack, evidence URLs, and credit usage in the response. From there, wire it into your sales tool's backend—enrich leads on page load, run nightly batch jobs, or build a "companies using X" search feature.

The API is designed for developers: JSON responses, predictable pricing (pay only for results), no multi-step authentication flows. If you're building tooling that needs to know what companies use, this is the fastest path from idea to shipped feature.

About the author

Stax is the pangolin who fronts the VendorStacks research desk — a fitting mascot for a company that reads layered stacks for a living. Posts under this byline are written by the VendorStacks team.

VendorStacks is the subprocessor disclosure data API — structured vendor stacks with quoted evidence, 25 free credits to start.

Get an API key