VendorStacks
← All posts
GTM6 min read

Tech Stack Lookup API: Filtering Prospects by Infrastructure and Vendor Combinations

How to build prospect filters using tech stack data to find companies running specific vendor combinations, infrastructure patterns, or technology profiles.

Stax
VendorStacks research desk

Tech Stack Lookup API: Filtering Prospects by Infrastructure and Vendor Combinations

Most sales teams filter prospects by company size, industry, or location. Fewer realize they can filter by technology profile: companies running Stripe and HubSpot, prospects using AWS but not Google Cloud, or businesses that recently adopted OpenAI.

This guide shows how to build those filters programmatically using a tech stack lookup API, with real code examples and practical filtering patterns.

Why Filter by Tech Stack

Vendor combinations reveal buying intent and operational maturity:

  • A company using Stripe + Snowflake + HubSpot likely has payment data flowing into a data warehouse and CRM — they're sophisticated enough to need integration tooling
  • A prospect using OpenAI or Anthropic is actively building AI features — good timing for dev tools, observability, or data infrastructure
  • Finding AWS users who aren't using a specific security vendor reveals a gap you can fill

Unlike firmographic filters, tech stack filters find companies based on what they've already chosen to buy and deploy.

Basic Vendor Detection: Single Lookup

Start with a single company lookup. The VendorStacks API returns a categorized vendor list extracted from public evidence:

curl -X GET "https://api.vendorstacks.com/v1/check?url=example.com" \
  -H "Authorization: Bearer vr_live_YOUR_KEY"

Response structure:

{
  "url": "example.com",
  "found": true,
  "vendor_stack": {
    "payments": [
      {
        "vendor": "Stripe",
        "vendor_confidence": 0.95,
        "evidence": "checkout.stripe.com/c/pay/cs_live_...",
        "evidence_source": "https://example.com/checkout"
      }
    ],
    "crm_sales": [
      {
        "vendor": "HubSpot",
        "vendor_confidence": 0.92,
        "evidence": "forms.hubspot.com/...",
        "evidence_source": "https://example.com/contact"
      }
    ],
    "cloud_infra": [
      {
        "vendor": "AWS",
        "vendor_confidence": 0.89,
        "evidence": "d3abc123.cloudfront.net/assets/...",
        "evidence_source": "https://example.com"
      }
    ]
  },
  "scanned_at": "2024-01-15T10:30:00Z",
  "credits_used": 1
}

The vendor_stack object groups vendors into 24 categories: marketing_ads, crm_sales, analytics_data, email, payments, support_cx, cloud_infra, productivity, sms_messaging, database_infra, realtime_infra, finance_accounting, privacy_compliance, ecommerce_pos, ai_ml, observability, security_fraud, hr_payroll, data_enrichment, integration_etl, esignature_contracts, media_cdn, auth_identity, search_discovery.

Pattern 1: AND Filters (Multiple Required Vendors)

Find companies using both Stripe and Snowflake — a signal they're sending payment data to a warehouse:

import requests

API_KEY = "vr_live_YOUR_KEY"
BASE_URL = "https://api.vendorstacks.com/v1"

def check_vendor_combination(domain, required_vendors):
    """Check if a domain uses all required vendors."""
    response = requests.get(
        f"{BASE_URL}/check",
        params={"url": domain},
        headers={"Authorization": f"Bearer {API_KEY}"}
    )
    
    if not response.json().get("found"):
        return False
    
    vendor_stack = response.json()["vendor_stack"]
    
    # Flatten all vendors across categories
    found_vendors = set()
    for category_vendors in vendor_stack.values():
        for v in category_vendors:
            found_vendors.add(v["vendor"])
    
    # Check if all required vendors are present
    return all(vendor in found_vendors for vendor in required_vendors)

# Test
prospect_domain = "acme-corp.com"
if check_vendor_combination(prospect_domain, ["Stripe", "Snowflake"]):
    print(f"{prospect_domain} uses both Stripe and Snowflake")

This costs 1 credit per lookup, charged only if data is found.

Pattern 2: NOT Filters (Finding Gaps)

Find AWS users who aren't using a specific observability tool:

def has_gap(domain, required_vendor, gap_category, excluded_vendors):
    """Check if domain uses required_vendor but lacks excluded_vendors in gap_category."""
    response = requests.get(
        f"{BASE_URL}/check",
        params={"url": domain},
        headers={"Authorization": f"Bearer {API_KEY}"}
    ).json()
    
    if not response.get("found"):
        return False
    
    vendor_stack = response["vendor_stack"]
    
    # Check for required vendor across all categories
    all_vendors = set()
    for category_vendors in vendor_stack.values():
        for v in category_vendors:
            all_vendors.add(v["vendor"])
    
    if required_vendor not in all_vendors:
        return False
    
    # Check gap_category for excluded vendors
    category_vendors = vendor_stack.get(gap_category, [])
    category_vendor_names = {v["vendor"] for v in category_vendors}
    
    # Return True if none of the excluded vendors are found
    return not any(v in category_vendor_names for v in excluded_vendors)

# Find AWS users without Datadog
if has_gap("prospect.com", "AWS", "observability", ["Datadog"]):
    print("Prospect uses AWS but not Datadog — potential customer")

This pattern works well for competitive displacement or category expansion plays.

Pattern 3: Category-Based Filters

Filter for companies using any AI vendor, indicating active AI development:

def uses_category(domain, category):
    """Check if domain uses any vendor in the specified category."""
    response = requests.get(
        f"{BASE_URL}/check",
        params={"url": domain},
        headers={"Authorization": f"Bearer {API_KEY}"}
    ).json()
    
    if not response.get("found"):
        return False
    
    vendor_stack = response["vendor_stack"]
    category_vendors = vendor_stack.get(category, [])
    
    return len(category_vendors) > 0

# Filter for AI adopters
if uses_category("startup.io", "ai_ml"):
    print("Company is using AI/ML vendors")

The ai_ml category currently includes vendors like OpenAI (91 companies in the index) and Anthropic (67 companies), extracted from public references in code snippets, documentation, or API calls visible in page sources.

Pattern 4: Reverse Lookup for Bulk Filtering

Instead of checking domains one by one, start with a vendor and get all companies using it:

def get_companies_using_vendor(vendor, limit=100):
    """Get list of companies using a specific vendor."""
    companies = []
    page = 1
    
    while len(companies) < limit:
        response = requests.get(
            f"{BASE_URL}/prospect",
            params={"vendor": vendor, "page": page},
            headers={"Authorization": f"Bearer {API_KEY}"}
        ).json()
        
        results = response.get("results", [])
        if not results:
            break
        
        companies.extend(results)
        page += 1
    
    return companies[:limit]

# Get Stripe users
stripe_users = get_companies_using_vendor("Stripe", limit=50)
print(f"Found {len(stripe_users)} companies using Stripe")

# Each result costs 1 credit
for company in stripe_users:
    print(f"{company['domain']}: {company['vendor_evidence']}")

Reverse lookup returns 10 results per page and costs 1 credit per result. An empty page costs 0 credits.

Then apply secondary filters:

# From Stripe users, find those also using Snowflake
stripe_and_snowflake = []

for company in stripe_users:
    domain = company["domain"]
    if check_vendor_combination(domain, ["Stripe", "Snowflake"]):
        stripe_and_snowflake.append(domain)

print(f"Filtered to {len(stripe_and_snowflake)} companies using both")

This two-pass approach is more efficient than checking arbitrary domains.

Pattern 5: Stack Maturity Scoring

Score prospects by infrastructure sophistication:

def calculate_stack_score(domain):
    """Score a company's tech stack maturity."""
    response = requests.get(
        f"{BASE_URL}/check",
        params={"url": domain},
        headers={"Authorization": f"Bearer {API_KEY}"}
    ).json()
    
    if not response.get("found"):
        return 0
    
    vendor_stack = response["vendor_stack"]
    score = 0
    
    # Points for data infrastructure
    if vendor_stack.get("database_infra"):
        score += 10
    if vendor_stack.get("analytics_data"):
        score += 10
    
    # Points for modern payment stack
    payments = {v["vendor"] for v in vendor_stack.get("payments", [])}
    if "Stripe" in payments:
        score += 15
    
    # Points for cloud infrastructure
    cloud = {v["vendor"] for v in vendor_stack.get("cloud_infra", [])}
    if "AWS" in cloud or "Google Cloud" in cloud:
        score += 10
    
    # Points for AI adoption
    if vendor_stack.get("ai_ml"):
        score += 20
    
    # Breadth bonus: using 5+ categories
    if len(vendor_stack.keys()) >= 5:
        score += 15
    
    return score

# Score a prospect
score = calculate_stack_score("techcompany.com")
if score >= 50:
    print(f"High-value prospect (score: {score})")

This creates a quantitative filter for "companies with mature tech stacks."

Real Vendor Distribution

When building filters, consider actual vendor prevalence. Based on the current index of 1,000 companies across 283 distinct vendors:

  • Google Analytics: 344 companies (most common)
  • AWS: 230 companies
  • Stripe: 155 companies
  • Meta: 123 companies (likely Facebook Pixel)
  • HubSpot: 106 companies
  • Google Cloud: 94 companies
  • Google Ads: 93 companies
  • OpenAI: 91 companies
  • Slack: 88 companies
  • LinkedIn: 71 companies

Filtering for common vendors like Google Analytics will return many results. Filtering for rare vendors or specific combinations will be more selective.

Handling "found": false

A response with "found": false means no public evidence was detected — not that the company uses no vendors. They may:

  • Use vendors that don't leave public evidence (internal tools, server-side services)
  • Have implementations that don't expose typical identifiers
  • Be newly launched with minimal public footprint

Don't treat false as "uses nothing." Treat it as "insufficient public data."

Cost Management

You're charged 1 credit per successful lookup result and 1 credit per reverse lookup result. Failed lookups and empty results cost 0 credits.

For bulk filtering:

def batch_check_with_budget(domains, budget_credits):
    """Check domains until budget is exhausted."""
    results = []
    
    for domain in domains:
        # Check remaining balance
        balance_response = requests.get(
            f"{BASE_URL}/balance",
            headers={"Authorization": f"Bearer {API_KEY}"}
        ).json()
        
        if balance_response["credit_balance"] < 1:
            print("Budget exhausted")
            break
        
        response = requests.get(
            f"{BASE_URL}/check",
            params={"url": domain},
            headers={"Authorization": f"Bearer {API_KEY}"}
        ).json()
        
        if response.get("found"):
            results.append(response)
    
    return results

Pricing: $10/1,100 credits, $50/6,000 credits, $250/35,000 credits.

Combining Filters with Traditional Signals

Tech stack filters work best combined with firmographic data:

# Pseudocode combining tech stack + firmographics
def is_qualified_prospect(domain, company_size, industry):
    # Traditional filters
    if company_size < 50 or industry not in ["SaaS", "Fintech"]:
        return False
    
    # Tech stack filter
    if not check_vendor_combination(domain, ["Stripe", "AWS"]):
        return False
    
    # Check for gap (no current competitor)
    if not has_gap(domain, "AWS", "observability", ["Datadog", "New Relic"]):
        return False
    
    return True

This creates a highly specific filter: 50+ employee SaaS/Fintech companies using Stripe + AWS but lacking Datadog or New Relic.

Next Steps

Get started:

  1. Get an API key with 25 free credits: POST https://api.vendorstacks.com/v1/keys
  2. Test vendor detection on a known domain: GET /v1/check?url=DOMAIN
  3. Build a simple AND filter for two vendors your product complements
  4. Use reverse lookup to build a seed list: GET /v1/prospect?vendor=Stripe

Tech stack filtering lets you target companies based on what they've already chosen to buy — one of the strongest signals of future buying intent.

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