# Technology Lookup – Website Tech Stack & Companies Using X (`inovaflow/technology-lookup`) Actor

Website technology checker with active-use verification: CMS, ecommerce, analytics, pixels, CRM, marketing automation, chat, payments, hosting, email and DNS-verified SaaS, with evidence per technology. Reverse mode: companies confirmed using a technology. BuiltWith alternative, MCP-ready.

- **URL**: https://apify.com/inovaflow/technology-lookup.md
- **Developed by:** [inovaflow](https://apify.com/inovaflow) (community)
- **Categories:** Lead generation, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 domain lookups

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

**Website technology checker with active-use verification, plus a reverse mode that finds the companies using a technology.** Give it websites and get each one's tech stack — CMS, ecommerce platform, analytics, tag manager, ad pixels, CRM, marketing automation, live chat, help desk, payments, hosting, CDN, email provider and email marketing stack, and the SaaS the company is a verified customer of — with **evidence** next to every technology and an `activeVerified` flag that says whether the tool is actually running, not just mentioned. Give it a technology too, and the run returns only the companies **confirmed** using it.

If you sell into a stack, technographics are the sharpest targeting signal there is: a Drift customer is an Intercom prospect, a Shopify Plus store is a Klaviyo/Gorgias/Recharge prospect, a company on HubSpot with no ABM tag is a 6sense prospect. The problem with the usual tech-stack lookups is false positives — a tag that is *present* in the HTML is not a tool that is *in use*: half the "detections" are leftover snippets, deleted containers and dead pixels, and a sequence built on them burns replies. This Actor fetches the live resource for each detection and tells you which ones are real.

### Website tech stack lookup (forward mode)

One row per website, with the stack that matters for outreach as flat, sortable columns and the full list underneath:

| Field | What it tells you |
| --- | --- |
| `cms`, `websiteBuilder`, `ecommerce`, `ecommerceApps` | What the site runs on — WordPress, Shopify, Webflow, HubSpot CMS, Magento, BigCommerce… and the apps around it |
| `crm`, `marketingAutomation`, `emailMarketing`, `abm`, `cdp` | The revenue stack: HubSpot, Salesforce, Marketo, Pardot, Klaviyo, Mailchimp, 6sense, Demandbase, ZoomInfo, Clearbit, RB2B, Segment… |
| `chat`, `support`, `scheduling`, `forms` | Intercom, Drift, Zendesk, Gorgias, Crisp, Calendly, Chili Piper, Typeform… |
| `analytics`, `sessionReplay`, `tagManagers`, `advertising`, `abTesting` | GA4, Mixpanel, Amplitude, Hotjar, Clarity, GTM, Tealium, Meta/LinkedIn/TikTok pixels, Optimizely, VWO… |
| `payments`, `subscriptions` | Stripe, PayPal, Adyen, Klarna, Shop Pay, Chargebee, Recharge… |
| `hosting`, `cdn`, `dnsProvider`, `security`, `frameworks` | Vercel, Netlify, AWS, Cloudflare, Akamai, WP Engine, Next.js, React… |
| `emailProvider` | Google Workspace, Microsoft 365, Mimecast, Proofpoint… (who runs their mail) |
| `saasVerified` | SaaS the company is a **verified customer** of — Rippling, Atlassian, Zapier, KnowBe4, Miro, DocuSign, OpenAI, Anthropic, Cursor, Okta… |
| `technologies[]` | Every technology with `category`, `confidence` (0–100), `activeVerified`, `verification` method, `evidence[]`, version and vendor-side ids, plus `firstSeen` / `lastSeen` |
| `addedSinceLastCheck`, `removedSinceLastCheck`, `previousCheckAt` | What changed since your previous run — the switch-play trigger |
| `gtmContainers`, `dns` | The tag containers read and the DNS facts used |

The **Tech stacks** dataset view is the one-line-per-website table; **All technologies** shows the evidence; **Changes since last check** shows what moved.

### Active-use verification: how "really running" is decided

Every technology carries a `verification` method, and `activeVerified` is `true` only when something **live** confirmed it:

| `verification` | Meaning |
| --- | --- |
| `id-validated` | The vendor served the resource for **this site's own id** (tag container, CRM portal, chat app, heatmap site, CDP write key…). A deleted id returns 404 and the technology is downgraded with a note. |
| `endpoint-live` | A platform endpoint on the site answered (a storefront product feed, a CMS API index). |
| `script-served` | The vendor script the page references was fetched and served as JavaScript. |
| `gtm-container` | The tag is configured inside the site's **live tag-manager container** — tools loaded through Google Tag Manager never appear in the HTML, and most lookups miss them. |
| `dns-live`, `header-live`, `cookie-live` | A DNS record, a response header or a cookie from the live server named the vendor. |
| `none` | Pattern-only (a meta generator, an inline snippet). Reported, with lower confidence, but not verified. |

The result is a stack you can act on: a "Drift" whose script no longer loads is reported as *not verified*, a chat tool that only exists inside the tag container is still found.

### Companies using X (reverse mode)

Enter a **technology** — a name or a vendor domain (`HubSpot`, `Shopify`, `Intercom`, `Marketo`, `lemlist.com`) — together with a list of websites, and the run returns only the ones confirmed using it: `usesTechnology`, `matchActiveVerified` and `matchEvidence[]` per company, with the rest of the stack alongside. Technologies that *imply* the one you asked for count too (a WooCommerce store uses WordPress). Names outside the built-in catalog still work: they are matched as a marker in script hosts, DNS records and tag containers.

No website list yet? Give **discovery queries** (`marketing agency`, `dental clinic`) and a **location**, and the run first discovers companies by business search and then checks each one — the **Companies using the technology** view is your list. Websites that do not use the technology are checked for free.

### Changes between runs (the switch-play trigger)

With **Track changes** on (default), each website's stack is remembered in a named key-value store on your account. Every later run reports `firstSeen` / `lastSeen` per technology and `addedSinceLastCheck` / `removedSinceLastCheck` per website. Put a target-account list on a weekly **Schedule** and the **Changes since last check** view becomes a feed of "just added Intercom", "just dropped Drift", "moved to Shopify" — the moments a switch conversation is welcome.

### Who uses it

- **Outbound / GTM teams** — competitor-displacement lists ("every company using X"), stack-based segmentation, and change triggers.
- **Agencies** — audit a prospect's stack before the first call; find every store on a platform in a market.
- **Sales-intelligence & data teams** — a technographic column set to join to CRM and enrichment data, with confidence and evidence instead of a black box.
- **Product & partnership teams** — install bases of complementary tools, adoption of a category over time.
- **AI agents** — a keyword-discoverable, MCP-callable tool that runs unattended and returns a clean, typed dataset.

### Set it up in a minute

1. **Websites** — one per line (domains or URLs). Agents may also pass `urls`, `websites`, `startUrls` or a comma-separated `url`.
2. Optionally enter a **technology** for reverse mode, or **discovery queries + location** to build the list automatically.
3. Start. Re-run (or schedule) to get change signals.

Advanced settings (collapsed) control verification depth, tag-container reading, DNS, change tracking, category filters, concurrency, timeouts and proxy. The defaults are tuned for unattended runs.

### Use it from an agent or the API

The Actor is designed for tool calls: minimal required input, bounded runtime, a typed dataset and no UI to click through.

```json
{ "domains": ["acme.com", "globex.com"] }
```

```json
{ "technology": "Drift", "domains": ["acme.com", "globex.com", "initech.com"] }
```

```json
{ "technology": "Shopify", "discoverQueries": ["skincare brand"], "discoverLocation": "United States", "maxDomains": 300 }
```

Results are in the default dataset (`?view=overview`, `?view=technologies`, `?view=matches`, `?view=changes`); a run summary with the most common technologies and the full technology catalog by category is in the `OUTPUT` record of the run's key-value store. Through the Apify MCP server, call `inovaflow/technology-lookup` with the same input.

### Output example

```json
{
  "domain": "allbirds.com",
  "status": "ok",
  "ecommerce": ["Shopify"],
  "payments": ["Shop Pay"],
  "tagManagers": ["Google Tag Manager"],
  "advertising": ["Meta Pixel", "TikTok Pixel", "Criteo", "Microsoft Advertising (UET)"],
  "reviews": ["Yotpo"],
  "emailProvider": ["Microsoft 365"],
  "saasVerified": ["Rippling", "Miro", "DocuSign", "Cursor", "Apple Business Manager"],
  "cdn": ["Cloudflare"],
  "technologies": [
    { "name": "Shopify", "category": "ecommerce", "confidence": 100, "activeVerified": true, "verification": "endpoint-live",
      "evidence": ["script: https://cdn.shopify.com/…", "cookie: _shopify_essential", "dns: www CNAME shops.myshopify.com", "verified: GET /products.json?limit=1 → 200 JSON"] },
    { "name": "Google Tag Manager", "category": "tagManagers", "confidence": 100, "activeVerified": true, "verification": "id-validated", "ids": ["GTM-TH8KRSBJ"],
      "evidence": ["html: …gtm.js?id=…", "verified: https://www.googletagmanager.com/gtm.js?id=GTM-TH8KRSBJ → 200 (629 KB)"] },
    { "name": "TikTok Pixel", "category": "advertising", "confidence": 85, "activeVerified": true, "verification": "gtm-container", "viaGtm": true,
      "evidence": ["gtm: tag in live container GTM-TH8KRSBJ (analytics.tiktok.com)"] },
    { "name": "Rippling", "category": "saasVerified", "confidence": 100, "activeVerified": true, "verification": "dns-live",
      "evidence": ["dns: TXT rippling-domain-verification"] }
  ],
  "techCount": 22,
  "activeVerifiedCount": 20,
  "addedSinceLastCheck": [],
  "removedSinceLastCheck": [],
  "checkedAt": "2026-09-10T13:05:11.000Z"
}
```

### Pricing

Pay per result: a small fee per **website analyzed** in forward mode, and per **company confirmed** in reverse mode (websites that do not use the technology, and websites that could not be reached, are free). A run start fee applies per gigabyte of memory. There are no subscriptions and no minimums; typical cost is a few cents per website and well under the usual per-lookup APIs.

### Coverage and limits

- Several hundred technologies across 30+ categories, curated for sales and marketing relevance, with verification logic per technology. Custom vendor names are supported in reverse mode as markers.
- Detection reads the page, its response headers and cookies, the live tag-manager container(s) and DNS. No login and no browser are required; JavaScript-rendered single-page apps still expose their tags through the container, headers and DNS.
- A website that blocks automated access or is offline is reported with `status: unreachable` / `blocked` and is not charged.
- Only public information is used: the website's own pages and its public DNS records.

### FAQ

**How is this different from other tech-stack detectors?** Three things: every technology is verified live (with the evidence shown) rather than pattern-matched; tools loaded through the tag manager are found; and DNS is read — email provider, email marketing stack, hosting and SaaS the company is a verified customer of — which no page-only detector sees. Plus a reverse "companies using X" mode.

**Can I look for a technology you do not list?** Yes. Enter its name or vendor domain; it is matched as a marker in script hosts, DNS records and tag containers, with evidence.

**Does it work on single-page apps?** Yes. Headers, cookies, DNS and the tag container do not depend on client-side rendering; tags injected only by JavaScript at runtime without a tag manager may be missed.

**How fast is it?** Around one to three seconds per website; a 1,000-website list typically finishes in a few minutes.

**Is a proxy needed?** Not usually. The default configuration uses a datacenter proxy and falls back to a direct request automatically.

# Actor input Schema

## `domains` (type: `array`):

Domains or URLs ("acme.com", "https://www.acme.com/pricing"). One row per website with its full tech stack. Also accepted as `urls`, `websites`, `startUrls` or a comma-separated `url` string.

## `technology` (type: `string`):

Optional. A technology name or vendor domain ("HubSpot", "Shopify", "Intercom", "lemlist.com"). When set, the run checks every website above and returns only the companies CONFIRMED using it — with the evidence. Leave empty to get the full tech stack of each website.

## `discoverQueries` (type: `array`):

Optional, reverse mode only. Instead of a website list, discover companies by business search — e.g. "dental clinics", "marketing agencies" — together with a location below. The discovered websites are then checked for the technology.

## `discoverLocation` (type: `string`):

City, region or country for the discovery search (e.g. "Austin, TX", "Berlin").

## `maxDomains` (type: `integer`):

Upper bound on websites checked in one run.

## `categories` (type: `array`):

Optional. Keep only technologies in these categories (all when empty).

## `verifyActiveUse` (type: `boolean`):

Confirm each detected technology is actually live (vendor resource for the site's own id served, endpoint answers, script served) instead of trusting a leftover snippet. Recommended.

## `fetchGtmContainer` (type: `boolean`):

Fetch the site's GTM container and report the tags it loads (pixels, chat, ABM, analytics) that never appear in the HTML.

## `checkDns` (type: `boolean`):

Read MX, SPF, CNAME, NS and verification records: email provider, email marketing stack, hosting, and SaaS the company is a verified customer of.

## `trackChanges` (type: `boolean`):

Remember each website's stack in a named key-value store on your account so every run reports first/last seen per technology and what was added or removed since the previous check.

## `historyStoreName` (type: `string`):

Name of the key-value store that keeps the history (change it to keep separate watchlists apart).

## `includeNonMatches` (type: `boolean`):

Also output websites that do NOT use the technology (with their full stack, `usesTechnology: false`).

## `minConfidence` (type: `integer`):

Drop technologies below this confidence (0–100). Pattern-only hits score 75, dead snippets 40, implied technologies 60.

## `maxConcurrency` (type: `integer`):

How many websites are analyzed at once.

## `requestTimeoutSecs` (type: `integer`):

Per-request timeout for fetching a website.

## `maxVerifyFetches` (type: `integer`):

Cap on the extra requests used to verify technologies on one website.

## `proxyConfiguration` (type: `object`):

Optional. Requests go direct by default and fall back to Apify's datacenter proxy automatically when a website challenges the platform IP. Set a proxy here (e.g. residential) only for lists of websites that block datacenter traffic.

## `apifyMcpConnector` (type: `string`):

Optional. Connect an Apify MCP connector (Console → Settings → Integrations → MCP Connectors, server URL https://mcp.apify.com) and the reverse-mode company discovery runs under THAT account. Leave empty to run discovery on this account.

## Actor input object example

```json
{
  "domains": [
    "allbirds.com",
    "intercom.com",
    "techcrunch.com"
  ],
  "technology": "HubSpot",
  "discoverQueries": [
    "marketing agency"
  ],
  "discoverLocation": "Austin, TX",
  "maxDomains": 500,
  "verifyActiveUse": true,
  "fetchGtmContainer": true,
  "checkDns": true,
  "trackChanges": true,
  "historyStoreName": "technology-lookup-history",
  "includeNonMatches": false,
  "minConfidence": 50,
  "maxConcurrency": 10,
  "requestTimeoutSecs": 20,
  "maxVerifyFetches": 8,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `stacks` (type: `string`):

One row per website: CMS, ecommerce, analytics, CRM, marketing automation, chat, payments, hosting, email and the full verified technology list with evidence.

## `matches` (type: `string`):

Reverse mode: the websites confirmed using the technology, with the match evidence.

## `changes` (type: `string`):

Technologies added or removed on each website since the previous run.

## `summary` (type: `string`):

Counts, top technologies and the technology catalog by category.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "domains": [
        "allbirds.com",
        "intercom.com",
        "techcrunch.com"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("inovaflow/technology-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "domains": [
        "allbirds.com",
        "intercom.com",
        "techcrunch.com",
    ],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("inovaflow/technology-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "domains": [
    "allbirds.com",
    "intercom.com",
    "techcrunch.com"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call inovaflow/technology-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,inovaflow/technology-lookup"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/im2dKtUctl0EoLL6D/builds/8Cc6ZqrZ7OgqOT7xz/openapi.json
