# Website Technology Lookup API - Tech Stack by Domain (`nabeelbaghoor/website-technology-lookup-api`) Actor

Look up the full technology stack behind any website: ecommerce platform, CMS, analytics, ads, payments, hosting and thousands more, with first and last detected dates, monthly tech spend and company details. Or list every website using a given technology, filtered by country, spend, rank and size.

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

## Pricing

from $20.00 / 1,000 website technology profile returneds

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 Lookup API - Tech Stack by Domain

Find out what any website is built with, or find every website built with a given technology, and get the company behind each domain in the same row.

### What it does

- **Two directions, one dataset.** Domain mode profiles websites you already care about. Technology mode finds websites using a technology you sell against or integrate with. Both write the same columns, so an account list and a prospect list are comparable.
- **Reads the whole stack, not just the obvious layer.** Ecommerce platform, CMS, analytics, tag managers, advertising pixels, payment processors, shipping, email marketing, CDN, hosting, frameworks, widgets and thousands more, each with its tag and categories.
- **Dates every detection.** First detected and last detected on each technology, merged across the subdomains where it appears, so you can see what a site adopted, what it kept, and what it dropped.
- **Estimates budget.** Average monthly technology spend in US dollars, plus estimated monthly ecommerce sales revenue and unique product count for online stores.
- **Names the company.** Company name, city, state, postcode, country and vertical, with telephone numbers and social profiles, so a domain becomes an account.
- **Ranks the site.** Traffic ranks from several sources, employee count and social follower count, which is how a list of a hundred thousand sites becomes a list of the two hundred worth calling.
- **Filters a technology list the way a territory is drawn.** Country, minimum employees, minimum monthly tech spend, minimum estimated sales, minimum product count, minimum followers and maximum traffic rank, plus a second technology the site must also run.
- **Finds recent adopters and recent leavers.** Date range filters on both first and last detection, so "sites that added this in the last quarter" and "sites that dropped it" are single runs.
- **Pages a list properly.** The provider pages by anchor rather than page number, and the run follows it to the end marker instead of guessing when to stop.
- **Leaves personal data out unless you ask.** Personal names and email addresses are suppressed by default.

### Input

#### Profile a list of domains

```json
{
  "mode": "domains",
  "domains": ["shopify.com", "notion.so", "example.com"],
  "liveOnly": true,
  "includeCompanyMeta": true
}
```

#### Find websites using a technology

```json
{
  "mode": "technology",
  "technology": "Shopify",
  "alsoUsing": ["Klaviyo"],
  "countries": ["US", "GB"],
  "minEmployees": 25,
  "minSpend": 500,
  "maxTrafficRank": 500000,
  "maxResults": 1000
}
```

#### Find recent adopters of a technology on sites you already track

```json
{
  "mode": "domains",
  "domains": ["example.com", "example.org"],
  "firstDetectedFrom": "2026-01-01"
}
```

### Example output

One row per website.

```json
{
  "domain": "example.com",
  "found": true,
  "technologyCount": 47,
  "technologies": ["Shopify", "Klaviyo", "Google Analytics", "Cloudflare"],
  "technologyDetails": [
    {
      "name": "Shopify",
      "tag": "shop",
      "categories": ["Ecommerce Platform"],
      "isPremium": "yes",
      "firstDetected": "2019-04-02T00:00:00Z",
      "lastDetected": "2026-08-30T00:00:00Z"
    }
  ],
  "categories": ["Ecommerce Platform", "Email Marketing", "Analytics"],
  "monthlyTechSpendUsd": 4364,
  "estimatedMonthlySalesUsd": 298538,
  "companyName": "Example Inc.",
  "city": "San Francisco",
  "state": "CA",
  "country": "US",
  "vertical": "Retail",
  "employees": 240,
  "socialFollowers": 51200,
  "trancoRank": 82311,
  "firstIndexed": "2012-07-29T14:00:00Z",
  "lastIndexed": "2026-08-30T14:00:00Z"
}
```

### Frequently asked questions

#### How do I find every website using a specific technology?

Set the mode to technology, put the technology name in, and set a row limit. Add filters to keep the list usable: country, minimum employees, minimum technology spend, minimum estimated sales, or a maximum traffic rank. A popular platform has millions of sites behind it, so the row limit and the filters are what decide the size and cost of the run.

#### Can I find sites using two technologies at once?

Yes. Put the main technology in the technology field and the others in the also using list, up to sixteen. The list then contains only sites running all of them, which is how you target a stack rather than a single tool, for example every store on one ecommerce platform that also runs a particular email tool.

#### What technologies are detected?

Everything the provider detects from a site's code and headers: ecommerce platforms, content management systems, analytics and tag managers, advertising and tracking pixels, payment and checkout, shipping, email and marketing automation, CDN and hosting, frameworks, JavaScript libraries, widgets, and server and infrastructure signals. Each detection carries a tag, a set of categories, and the dates it was first and last seen.

#### How do I write the technology name?

Write it as the provider names it. Spaces become dashes, and this actor converts them for you, so both Google Analytics and Google-Analytics work. If a list comes back empty, the usual cause is a name the provider spells differently rather than a site count of zero, because an unrecognised technology name returns no rows rather than an error.

#### Can I see when a site started or stopped using something?

Yes. Every technology carries a first detected and a last detected date. Where the same technology appears on several subdomains, the dates are merged to the widest window, because the question is whether the company uses it rather than which page shows it. The date range filters then let you ask for recent adopters or for sites where a technology has stopped being detected.

#### What is monthly technology spend?

An estimate, in US dollars, of what a site spends per month on the paid technologies detected on it. It is a budget proxy rather than an invoice: it is useful for sorting a large list by how much a company invests in its stack, and for filtering out sites running nothing but free tools.

#### Do I need my own API key?

Yes. This actor is bring your own key: it calls the technology data API using your own account key, so you keep your own credit balance, your own rate limits and your own agreement with the provider. Sign in to the provider and copy the key from its API section.

#### Why did a run return no rows instead of an error?

If it happens on every row, check the key. This provider answers an unrecognised key with HTTP 200 and an error inside the body rather than with an authentication status, so a dead key looks like an empty result to anything that only reads the status line. This actor inspects the body on every call and ends the run with a clear message instead, so a run that produced nothing will say why.

#### How much does a run cost?

Charging is per row. A full domain profile carries the whole stack, spend estimates, ranks and company details, and is priced accordingly. A row in a technology list carries one technology and the site's details, and costs less. Domains the provider has no profile for are not charged. Set `maxResults` to cap the rows a run can produce.

#### What are the rate limits?

The provider allows ten requests a second with eight running at once. This actor paces itself at 120 requests a minute by default and is capped at 300. Because domain mode sends sixteen domains per request, the request rate is rarely the limit that matters.

### Keyword map

website technology lookup API, technographics API, tech stack lookup, what technology does a website use, BuiltWith style API, detect website technologies, ecommerce platform detection, Shopify store list, Magento sites list, CMS detection API, analytics detection, tag manager detection, technology install base, competitor technology tracking, technology spend estimate, ecommerce revenue estimate, lead lists by technology, technology adoption tracking, web technology profiler, domain technology profile

# Actor input Schema

## `mode` (type: `string`):

Domain mode takes websites you already care about and returns what each one runs, which is how you profile an account list. Technology mode takes one technology and returns the websites using it, which is how you build a prospect list. The two read different parts of this form, so fields belonging to the other mode are ignored rather than causing an error.

## `apiKey` (type: `string`):

Your own account's API key for this provider, shown in its API section once you are signed in. Bring your own key: nothing is shared between runs and the key is never written to the dataset.

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

Websites to look up, one per line. A full URL works and is reduced to its domain, so pasting a column of links from a CRM is fine. Up to 16 domains go into each request.

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

The technology to list websites for, written the way the provider names it, for example Shopify, Google-Analytics, Klaviyo or Magento. Spaces are converted to dashes for you.

## `alsoUsing` (type: `array`):

Narrow a technology list to sites that also run these, one per line, up to 16. This is how you find a stack rather than a single tool, for example every Shopify store that also runs Klaviyo.

## `countries` (type: `array`):

Limit a technology list to these countries, as two letter ISO codes, one per line. Leave empty for worldwide.

## `since` (type: `string`):

Limit a technology list to sites seen using it since this point. Takes a date as YYYY-MM-DD, or the provider's own relative wording such as 30 Days Ago. Leave empty for all current sites.

## `includeHistorical` (type: `boolean`):

Include sites that used the technology in the past as well as those using it now. Takes precedence over the detected since filter, because the provider treats the two as incompatible.

## `minEmployees` (type: `integer`):

Only list sites whose company has at least this many employees. Leave empty for no employee filter.

## `minSpend` (type: `integer`):

Only list sites whose estimated monthly technology spend is at least this many US dollars. A useful proxy for budget when qualifying a list.

## `minRevenue` (type: `integer`):

Only list ecommerce sites whose estimated monthly sales revenue is at least this many US dollars. Non-ecommerce sites report zero here, so setting this excludes them.

## `minProducts` (type: `integer`):

Only list ecommerce sites carrying at least this many unique products. Separates a real catalogue from a placeholder store.

## `minSocialFollowers` (type: `integer`):

Only list sites whose social profiles have at least this many followers in total.

## `maxTrafficRank` (type: `integer`):

Only list sites inside this traffic rank, using the Tranco top one million. A lower number is a more popular site, so 100000 means the top hundred thousand sites.

## `liveOnly` (type: `boolean`):

In domain mode, return only technologies the provider still considers live on the site, leaving out ones it has stopped detecting.

## `firstDetectedFrom` (type: `string`):

In domain mode, only return technologies first detected on or after this date, as YYYY-MM-DD. This is how you find what a site adopted recently.

## `firstDetectedTo` (type: `string`):

In domain mode, only return technologies first detected on or before this date, as YYYY-MM-DD.

## `lastDetectedFrom` (type: `string`):

In domain mode, only return technologies last detected on or after this date, as YYYY-MM-DD. Useful for filtering out long dead detections.

## `lastDetectedTo` (type: `string`):

In domain mode, only return technologies last detected on or before this date, as YYYY-MM-DD. This is how you find what a site has dropped.

## `includeDescriptions` (type: `boolean`):

Keep the description, link, tag and category fields on each detected technology. Turning this off makes domain lookups noticeably faster and the rows much smaller.

## `includeCompanyMeta` (type: `boolean`):

Return the company behind the domain: name, city, state, postcode, country, vertical, telephone numbers and social profiles. Turning this off improves performance.

## `includeAttributes` (type: `boolean`):

Return the site attribute block in domain mode: traffic ranks, employee count, follower count, product count, ecommerce category and tag manager containers.

## `includeContactNames` (type: `boolean`):

Include personal names and email addresses in the company details where the provider holds them. Off by default: the provider already removes them for some jurisdictions, and most uses of this data do not need them.

## `skipEmptyProfiles` (type: `boolean`):

Leave domains with no detected technologies out of the dataset. They are never charged for either way, so this is about the shape of your output.

## `maxResults` (type: `integer`):

Stop after this many rows. In technology mode this is the main control on how much a run costs, because a popular technology has millions of sites behind it.

## `requestsPerMinute` (type: `integer`):

How fast this actor calls the provider. The documented limits are ten requests a second and eight at once, so this is capped at 300 a minute, which leaves headroom on an account that is also serving your own application.

## Actor input object example

```json
{
  "mode": "domains",
  "domains": [
    "shopify.com"
  ],
  "technology": "Shopify",
  "includeHistorical": false,
  "liveOnly": false,
  "includeDescriptions": true,
  "includeCompanyMeta": true,
  "includeAttributes": true,
  "includeContactNames": false,
  "skipEmptyProfiles": false,
  "maxResults": 100,
  "requestsPerMinute": 120
}
```

# Actor output Schema

## `websites` (type: `string`):

One row per website, alongside the domain or technology it was found from.

# 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": [
        "shopify.com"
    ],
    "technology": "Shopify"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/website-technology-lookup-api").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": ["shopify.com"],
    "technology": "Shopify",
}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/website-technology-lookup-api").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": [
    "shopify.com"
  ],
  "technology": "Shopify"
}' |
apify call nabeelbaghoor/website-technology-lookup-api --silent --output-dataset

```

## MCP server setup

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

```

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/xhfeTnq3IdjyUHOTM/builds/Fch3mof0VSHudal3T/openapi.json
