Input
--input <path>- Read newline, comma, or space-separated domains.
--stdin- Read domains from standard input.
--labels <a,b,c>- Add known candidate tracking labels.
--preserve-hostname- Scan the supplied hostname instead of its base domain.
DOCUMENTATION
Learn the CLI, understand every confidence level, and run careful public DNS research at scale.
These docs cover vendorprint 0.5.0 on npm, including the current signatures and package-version metadata. Use npx vendorprint@0.5.0 example.com to pin this release.
Node.js 20 or newer is the only runtime requirement. Run vendorprint directly from npm without installing it globally.
npx vendorprint@latest example.com
Install vendorprint globally when you use it regularly. The default output shows only observed technologies and their evidence.
npm install --global vendorprint
vendorprint example.com
vendorprint queries the configured recursive DNS resolver. It does not request company websites, tracking endpoints, login pages, or application APIs.
Install a reusable skill for company technographics. It gives your agent a workflow for scanning public DNS and interpreting vendor evidence.
Use a compatible coding agent with shell access, such as Codex, Claude Code, or Cursor. The skill runs the published vendorprint@0.5.0 scanner locally without a VendorPrint account or API key.
npx skills add danahmadi/vendorprint_cli --skill vendorprint
Run this in your project and choose your agent in the installer. The skills CLI currently requires Node.js 22.20 or newer. The scanner itself requires Node.js 20 or newer and network access to public DNS; the first run downloads it from npm. Start a new agent session if the installed skill is not yet visible.
Prefer a manual setup? Copy the entire skill folder from GitHub, including its references, into your agent's supported skills directory.
Use vendorprint to research example.com's software stack.
Show the evidence, confidence, and what remains unknown.
Replace example.com with the company domain. The agent returns the observed email and SaaS signals, their evidence, observation time, and any incomplete checks.
Use vendorprint to enrich the domains in accounts.txt with
DNS-visible technology signals. Save the results with their
evidence and flag partial scans.
Supply a text file with one domain per line. The skill includes guidance for JSON and NDJSON output, resuming interrupted batches, and using the Node.js library in your own application.
The skill distinguishes ownership records, email authorization, and platform configuration. It preserves inferred findings and partial scans. A missing signal is inconclusive; a positive record does not prove active usage, paid seats, or subscriptions.
Read the skill instructions or see the skills CLI documentation.
Use positional domains for quick scans, or file and stream inputs for larger jobs.
--input <path>--stdin--labels <a,b,c>--preserve-hostname--mode <value>--dns-transport <kind>--timeout <ms>--concurrency <n>--max-inflight-dns <n>--qps <n>--ct--ct-cache <path>--full--findings-only--format <value>--output <path>--pretty--include-unclassified--resume <path>--help0Scan completed. Individual domains may still contain DNS errors.1The CLI input was invalid.URLs and hostnames normalize to the registrable company domain using the Public Suffix List. Exact input hostnames are retained as prioritized CNAME candidates, alongside the base hostname and www.
https://www.example.co.uk/pricing
example.co.uk
Use --preserve-hostname when a delegated hostname is intentionally the scan target; its own CNAME is also queried. Invalid inputs are retained under invalidInputs instead of silently disappearing.
Keep per-company hostname hints in a JSON file, for example {"example.com": ["try.example.com", "join.campaign.example.com"]}. Run vendorprint example.com --hostname-hints hosts.json, or pass the same map as hostnameHintsByDomain to the library.
Hints must belong to the specified scan domain and augment requested accounts. Nested names receive wildcard controls. All queries share the 80-attempt budget; skipped hostnames remain visible in completeness diagnostics. Start a new output file after changing hints or package version because resume skips already-completed domains.
Result-first output keeps observed technologies, confidence, evidence, and caveats. Reports and NDJSON metadata/summary events also retain packageVersion and signatureCatalogVersion for reproducibility. Each fresh result includes observedAt and scanCompleteness. Empty categories and detailed scan internals stay out of the way.
{
"findings": [{
"domain": "example.com",
"status": "ok",
"observedAt": "2026-10-15T12:00:00.000Z",
"scanCompleteness": {
"status": "partial",
"scope": "bounded_checks",
"reasons": ["query_budget"],
"queryAttempts": 80,
"queryLimit": 80,
"skippedHostnames": 2,
"queriesSkippedDueToBudget": 1,
"dnsErrors": [],
"interpretation": "Completeness describes the bounded scan plan, not all possible DNS names or vendor usage. Absence remains inconclusive."
},
"email": {
"provider": "Google Workspace",
"confidence": "high"
},
"technologyProfile": {
"crm": [{
"provider": "Salesforce",
"confidence": "high",
"relationshipLevel": "platform_configuration",
"evidence": [{
"type": "cname",
"hostname": "support.example.com",
"target": "tenant.force.com"
}],
"caveat": "Configuration does not prove active seats."
}]
}
}]
}
status: "ok" describes DNS response availability. scanCompleteness.status reports whether the bounded plan finished. Partial scans expose query-budget limits, DNS errors, SPF lookup limits, CNAME depth limits, or optional discovery errors. A partial scan can still contain high-confidence positive evidence. Even a complete bounded scan cannot prove a vendor is absent.
domain, status, and normalized input diagnostics.
Mail routing, ownership proofs, sending authorization, CNAME services, and sales engagement.
Normalized categories include explicit inferred findings. Add --full to inspect unresolved candidate sets.
Add --full for query budgets, searched labels, retries, raw DNS, and wildcard diagnostics.
Inspect the versioned catalog, find recurring unknown records offline, and compare two scan snapshots.
vendorprint --input accounts.txt --full --include-unclassified --format ndjson --output findings.ndjson
vendorprint signatures --pretty
vendorprint signatures audit findings.ndjson --pretty
vendorprint diff before.json after.json --pretty
Use full output with --include-unclassified for complete audits. Audit schema 1.1 counts distinct domains and includes unknown MX, nested SPF targets, CNAME targets, and redacted TXT keys. Audit output contains aggregate unknown prefixes and target domains only. It excludes account domains and verification tokens, and it performs no network requests.
Browse the searchable signature catalog and benchmarks for GTM tools, trust centers, identity providers, and business software. Vanta, SafeBase, and Drata signals identify trust-center hosting. Fireflies and Read AI TXT records identify published domain relationships. Gong Engage link tracking does not identify general call recording. Snowflake domain verification does not establish warehouse usage. Smartsheet, Dynatrace, TeamViewer, and Adobe Acrobat Sign TXT rules identify domain relationships, not active subscriptions or completed verification.
Every mode checks the base CNAME, supplied hostnames, and www, then additional labels as the budget permits. Full mode has 50 additional labels. Fast has 11, including trust; balanced has 27, including trust, security, and trustcenter. All modes retain the 80-attempt cap. More labels can leave less budget for adaptive follow-ups.
vendorprint separates direct observations from derived relationships and unresolved candidates.
A vendor-owned MX or CNAME target, or a self-identifying ownership proof.
A product dependency or suite relationship, with rationale and caveats attached.
A non-exhaustive set that may be prioritized by independent corroborating evidence.
platform_configuration
An attributable custom hostname points to vendor infrastructure.
domain_relationship
A vendor-specific TXT record proves that domain ownership was configured.
sending_authorization
SPF authorizes a service to send mail but does not prove broader product use.
DNS cannot list arbitrary subdomains. Proxies, disabled branded tracking, and customer-selected labels can hide an otherwise active product.
Use NDJSON for long-running jobs. Each completed domain is appended immediately and becomes a durable checkpoint.
vendorprint --input accounts.txt \
--format ndjson \
--output findings.ndjson
vendorprint --input accounts.txt \
--resume findings.ndjson
Resume skips normalized domains already present, tolerates one partial final line, and appends only remaining results. New output files are created without overwriting an existing file.
Import the scanner without invoking the CLI, or consume completion-order events as an async iterator.
import { scanDomains } from "vendorprint";
const report = await scanDomains(["example.com"], {
concurrency: 4,
maxInflightDns: 32,
qps: 100,
});
import { scanDomainEvents } from "vendorprint";
for await (const event of scanDomainEvents(domains)) {
process.stdout.write(`${JSON.stringify(event)}\n`);
}
Keep the evidence attached, preserve unknown values, and use the built-in DNS limits.
Only research domains you are permitted to process. Follow applicable law, provider terms, data-governance rules, and retention policies.
These constraints protect the resolver and keep downstream decisions honest.
A configured record can remain after a tool is no longer actively used.
Cloudflare and other proxies can hide the vendor-owned CNAME target.
Wildcard-like answers are collapsed so repeated guesses do not inflate evidence.
A platform relationship does not prove a specific module, plan, seat, or recent activity.