GTM Engineering

Find every confirmed customer of any SaaS product.

BuiltWith gives you a guess. This gives you a URL you can click. How SaaS tenant subdomains plus certificate transparency logs produce a confirmed customer list — not a probability score.

Deepline

The problem with technographic signals

BuiltWith says a company "uses Zendesk." G2 says they're a customer. Job postings mention the tool once. All of these are inferred. None of them prove active use today.

The real question for GTM is simpler: does a live tenant subdomain exist right now? If yes, they're a confirmed customer. If no, move on.

This distinction matters. A confirmed login URL is evidence. A BuiltWith tag is a guess from a browser extension that scraped a snippet two years ago.

The insight: SaaS tenant subdomains are public

Most enterprise SaaS platforms route tenants on subdomains. company.zendesk.com. company.my.salesforce.com. company.atlassian.net. To serve HTTPS on these subdomains, they issue TLS certificates. Every certificate issued is logged publicly in certificate transparency (CT) logs.

CT logs are meant for security auditing. But they also contain a complete history of every subdomain ever given a tenant slot. When you combine that with an HTTP probe to confirm the tenant is live today, you get a confirmed customer list.

This is Jordan Crawford's fingerprint-first methodology from Blueprint: identify the signal that proves active use before touching a single contact. In this case, the fingerprint is the live login URL.

Platform fingerprints: what 200 vs ghost means

Each platform behaves differently. Some use wildcard DNS (every slug resolves). Some return 404 for unknown tenants. Some redirect to a login page with a specific URL fragment. You have to know what you're looking for.

PlatformURL patternLive signalGhost signal
Salesforce{slug}.my.salesforce.comHTTP 200HTTP 404
Zendesk{slug}.zendesk.comHTTP 200HTTP 403
Freshdesk{slug}.freshdesk.comHTTP 302HTTP 404
Jamf Cloud{slug}.jamfcloud.comfinal URL has /view/sso/loginbare URL, no path
Atlassian{slug}.atlassian.netHTTP 200HTTP 404
ServiceNow{slug}.service-now.comHTTP 200timeout
Salesloft{slug}.salesloft.comHTTP 200DNS NXDOMAIN
PagerDuty{slug}.pagerduty.comHTTP 4050/timeout
Greenhousejob-boards.greenhouse.io/{slug}HTTP 200HTTP 404
Workday{slug}.myworkday.comCT logs onlywildcard DNS
BambooHR{slug}.bamboohr.comCT logs onlywildcard DNS
Outreach{slug}.outreach.ioCT logs onlywildcard DNS
Gong{slug}.app.gong.ioCT logs onlywildcard DNS
Monday.com{slug}.monday.comCT logs onlywildcard DNS
HubSpot{slug}.hubspot.comCT logs onlywildcard DNS
NetSuite{slug}.app.netsuite.comCT logs onlywildcard DNS
Datadog{slug}.datadoghq.comCT logs onlywildcard DNS
Greenhouse (ATS)boards.greenhouse.io/{slug}HTTP 200HTTP 404

Wildcard DNS platforms (Workday, BambooHR, etc.) return a valid DNS response for any slug. HTTP probing is unreliable there. Instead, you query certificate transparency logs, which only contain real tenant certs.

The pipeline

subfinder replaces crt.sh

crt.sh has 2-3 outages per week. Postgres timeouts. 502s. The solution is subfinder, which aggregates 50+ passive sources simultaneously: certificate transparency logs, Censys, SecurityTrails, Wayback Machine, VirusTotal. One command, one output, no babysitting.

subfinder -d jamfcloud.com -o subdomains.txt

On jamfcloud.com this returned 11,913 subdomains.

Filter to real slug candidates

Not all subdomains are tenant slugs. Strip nested subdomains (a.b.jamfcloud.com). Strip known internal infrastructure: help, status, api, mail, sandbox, dev, test, staging, demo, app, www.

After filtering: 2,893 clean slug candidates.

httpx probe with follow-redirects

httpx fires 100 concurrent HEAD requests. The critical flag is -fr (follow redirects). Without it, platforms that 302 before returning 200 — Jamf, Salesforce, Freshdesk — are missed entirely. This is the most common reason pipelines undercount.

httpx -l slugs.txt -fr -mc 200 -o live.txt -threads 100

After the httpx pass: 1,357 returned HTTP 200.

Fingerprint check

For Jamf specifically, 200 is not enough. The final URL after redirect must contain /view/sso/login. Wildcard responses exist that return 200 but are not real tenants. The Python script does this secondary check.

After fingerprint filtering: 436 confirmed real tenants.

Sample confirmed jamfcloud.com customers: github, cirruslogic, clearwateranalytics, vistaequitypartners, txstate, childrenscolorado.

Live confirmed customer URLs

These returned confirmed responses on 2026-05-07:

Salesforce: uber.my.salesforce.com, amazon.my.salesforce.com, walmart.my.salesforce.com, ibm.my.salesforce.com, adidas.my.salesforce.com

Zendesk: shopify.zendesk.com, slack.zendesk.com, squarespace.zendesk.com, box.zendesk.com

Atlassian: netflix.atlassian.net, nasa.atlassian.net, spotify.atlassian.net, linkedin.atlassian.net, lyft.atlassian.net

PagerDuty: netflix.pagerduty.com, airbnb.pagerduty.com, stripe.pagerduty.com, cloudflare.pagerduty.com

Jamf Cloud: ibm.jamfcloud.com, stanford.jamfcloud.com, autodesk.jamfcloud.com, metlife.jamfcloud.com

Not guesses. Clickable URLs returning 200 right now.

How slug generation works

The tenant slug is almost always the domain prefix. shopify.com becomes shopify. That's the first candidate tried.

The script generates up to 5 variants and tries each in order:

  • shopify.comshopify (wins immediately)
  • tcs.com → tries tcs, tata-consultancy-services, tc
  • tranetechnologies.com → tries trane, tranetechnologies
  • williams-sonomainc.com → tries williams, williams-sonomainc, williams-sonoma

Legal suffixes get stripped automatically: inc, corp, technologies, plc, ltd. Domain prefix beats company name — it's more reliable because it's what the company typed when they provisioned the account.

Cost model

StepProviderCost
Seed company list (25/platform)Bloomberry~$5.25 per platform
subfinder subdomain discoveryNone — open sourceFree
httpx HTTP probingNone — open sourceFree
Fingerprint checkNone — direct HTTPFree
Contact enrichment (optional)Dropleads / ApolloFree tier

$5-10 gets you a confirmed customer list for one platform. $50-100 covers 10 platforms, 250 companies each.

The whole HTTP probing side is free. The only real cost is the seed list. Bloomberry's bloomberry_get_current_customers is the cheapest technographic source for this at $0.21 per result.

How to run it

Install the tools:

brew install subfinder httpx

Run the full pipeline:

python3 ct_harvest.py --platform zendesk

Or with a Bloomberry seed list:

deepline tools execute bloomberry_get_current_customers \
  --payload '{"vendor_name":"Zendesk","company_employee_size_range":"5,001-10,000;10,001+","limit":20}'

python3 scripts/tenant-enum/slug_probe.py \
  --csv bloomberry_output.csv \
  --platforms zendesk salesforce atlassian jamf \
  --output confirmed_tenants.csv

The output CSV has: platform, slug, subdomain, login_url, confirmed, source. Filter confirmed=True. That's your list.

What to do with the list

You now have a list of companies with clickable tenant login URLs. That is a much stronger signal than "saw this tool mentioned." Some ways to use it:

Competitive displacement. Target confirmed users of a competitor. You know they're active, not just ex-customers.

ICP validation. If you're selling to Zendesk users, check whether your existing customers have Zendesk tenants. Confirm the pattern before scaling.

Account prioritization. Surface accounts where multiple relevant tools are confirmed active. Stack confirmed signals instead of stacking guesses.

Contact enrichment. Feed the confirmed tenant list back into Deepline to find VP Customer Success, Head of IT, or RevOps contacts at each account.

The list is the starting point. A confirmed login URL means the tool is in active use. Where you go from there depends on what you're selling.

Scripts are in scripts/tenant-enum/ in the deepline-api repo. 18 platforms supported. Start with the one your best prospects are most likely to use.

Build your confirmed customer list

Deepline runs the full pipeline: Bloomberry for the seed list, slug probe for confirmation, waterfall enrichment for contacts. One command, clean CSV output.