# Website Tech Stack Analysis: Technographic & Firmographic Data (`stackscan/website-tech-stack-analysis`) Actor

Analyse the tech stack of any list of websites. Returns technographic data, the technologies each site runs, and optional firmographic data, the company behind it, at up to 100 domains per call.

- **URL**: https://apify.com/stackscan/website-tech-stack-analysis.md
- **Developed by:** [Stackscan](https://apify.com/stackscan) (community)
- **Categories:** Lead generation, E-commerce, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 tech stack enrichments

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 Tech Stack Analysis: Technographic & Firmographic Data

Give it a list of websites. Get back the tech stack of each one, and
optionally the company behind it.

Built on [StackScan](https://www.stackscan.com), which tracks which technologies
are live on which websites. Useful for scoring leads by their stack, finding
everyone on a competitor's platform, or filling in a CRM that only has domains.

### What you get

One dataset row per domain you submit, whatever happened to it:

| Field | |
|---|---|
| `domain` | normalised to a bare hostname |
| `status` | `resolved`, `not_found`, `invalid` or `skipped_insufficient_credits` |
| `technologies` | name, category, sub-category, the technology's own site, and how many websites run it |
| `companyName`, `industry`, `city`, `country`, `linkedinUrl` | the firmographics, when you ask for them |
| `totalTechnologies` | how many exist, which can exceed how many were returned |
| `hasMore` | true when there are more than you asked for |

Nothing disappears silently. A domain we hold no data for comes back as
`not_found` rather than being dropped, so your row count out matches your row
count in.

### Sample run

Input:

```json
{
  "domains": [
    "allbirds.com",
    "thisdomaindoesnotexist-stackscan.com"
  ],
  "technologiesPerDomain": 10
}
```

Output, two rows for two domains:

```json
[
  {
    "domain": "allbirds.com",
    "status": "resolved",
    "totalTechnologies": 21,
    "hasMore": true,
    "technologies": [
      {
        "techapi_id": "spf-sender-policy-framework-474451",
        "name": "SPF (Sender Policy Framework)",
        "website": "http://open-spf.org/SPF_Record_Syntax/",
        "parent_category": "Hosting & Infrastructure",
        "child_category": "Email Hosting",
        "total_sites": 126709527
      },
      {
        "techapi_id": "cloudflare-619110",
        "name": "Cloudflare",
        "website": "https://www.cloudflare.com/",
        "parent_category": "Hosting & Infrastructure",
        "child_category": "Cloud Hosting",
        "total_sites": 23294078
      },
      {
        "techapi_id": "google-workspace-849939",
        "name": "Google Workspace",
        "website": "https://workspace.google.com/",
        "parent_category": "Hosting & Infrastructure",
        "child_category": "Email Hosting",
        "total_sites": 20927947
      },
      {
        "techapi_id": "google-search-console-330271",
        "name": "Google Search Console",
        "website": "https://search.google.com/search-console/",
        "parent_category": "Marketing & SEO",
        "child_category": "Search Optimization",
        "total_sites": 19848692
      },
      {
        "techapi_id": "microsoft-365-660184",
        "name": "Microsoft 365",
        "website": "https://www.office.com/",
        "parent_category": "Business Operations",
        "child_category": "Business Tools",
        "total_sites": 7545028
      },
      {
        "techapi_id": "shopify-971069",
        "name": "Shopify",
        "website": "https://www.shopify.com/",
        "parent_category": "E-commerce & Sales",
        "child_category": "eCommerce Software",
        "total_sites": 3973575
      },
      {
        "techapi_id": "shopify-cdn-742015",
        "name": "Shopify CDN",
        "website": "https://cdn.shopify.com/",
        "parent_category": "E-commerce & Sales",
        "child_category": "Shopify Apps",
        "total_sites": 1866693
      },
      {
        "techapi_id": "jsdelivr-483920",
        "name": "jsDelivr",
        "website": "https://www.jsdelivr.com/",
        "parent_category": "Hosting & Infrastructure",
        "child_category": "Content Delivery Network",
        "total_sites": 1753911
      },
      {
        "techapi_id": "apple-business-manager-905613",
        "name": "Apple Business Manager",
        "website": "https://business.apple.com/",
        "parent_category": "Business Operations",
        "child_category": "Business Tools",
        "total_sites": 759229
      },
      {
        "techapi_id": "markmonitor-dns-217844",
        "name": "MarkMonitor DNS",
        "website": "https://www.markmonitor.com/",
        "parent_category": "DNS Services",
        "child_category": "Web Hosting DNS",
        "total_sites": 501269
      }
    ]
  },
  {
    "domain": "thisdomaindoesnotexist-stackscan.com",
    "status": "not_found",
    "technologies": [],
    "error": "No technology data for this domain"
  }
]
```

One charge, not two. The second domain resolved to nothing, so it cost nothing.

`total_sites` is how many websites in our whole index run that technology, which
is why the list opens with infrastructure almost everyone has and narrows to the
ones that actually distinguish a site. Sort by it ascending if the rare
technologies are the ones you care about.

### Before you start

Nothing. Paste your domains and press Start.

No StackScan account, no API key, no signup. The Actor carries its own access
and bills through Apify per result.

#### If you already have a StackScan account

Fill in **StackScan API token** and **Workspace ID** to run against the credits
you already hold. Get a token from **My Account** then **API Tokens**, and your
workspace IDs from `GET https://api.stackscan.com/v1/me`.

### Input

| Field | Required | |
|---|---|---|
| **Domains** | yes | Full URLs are fine, they are reduced to their domain |
| **StackScan API token** | no | Only if you want to spend your own StackScan credits |
| **Workspace ID** | no | Only alongside your own token |
| **Technologies per domain** | no | Default 50, which is the whole stack for almost every site. Does not change the price |
| **Only this category** | no | For example `Ecommerce` |
| **Include company data** | no | Adds firmographics. Off by default, see below |
| **Stop when credits run out** | no | Default on |

### What it costs

**From $1.00 per 1,000 resolved domains.** Charged per result, not per run.

| Your Apify plan | Per 1,000 | Per 10,000 |
|---|---|---|
| Free | $1.20 | $12.00 |
| Bronze, Silver | $1.10 | $11.00 |
| Gold and above | $1.00 | $10.00 |

Domains we hold no data for cost nothing, and neither do duplicates: the list is
deduplicated before any lookup happens, so the same domain three times is
charged once. Submit 10,000 and resolve 6,400 and you are charged for 6,400.

Turning on **Include company data** adds another $1.00 per 1,000 resolved
domains, because it is a second lookup. It is off by default, so you never pay
for firmographics you did not ask for.

Every run also carries a $0.0005 start fee, which covers its first five seconds
of compute. On a run of any real size it rounds to nothing. Apify charges for
the compute beyond that, as with any Actor.

With your own StackScan token, lookups are billed to your StackScan credits at
one bulk lookup credit per resolved domain rather than per result here, so the
same lookup is never paid for twice.

The Actor sends 100 domains per API call and paces itself to the published rate
limit, so a large list costs the same in credits as a small one per domain and
does not collect rate-limit errors on the way.

### When a run stops early

Two things can stop a run, and both keep everything already fetched. Domains
that were not attempted are still written to the dataset marked
`skipped_insufficient_credits`, so you know exactly where to resume.

**Your Apify spend limit was reached.** Raise it and run the rest.

**StackScan capacity was temporarily exhausted.** That one is on us, not you,
and nothing further is charged. Retry later, or tell us at
[stackscan.com/contact](https://www.stackscan.com/contact).

### Limits worth knowing

**We do not have every website.** Coverage is very good for commercial sites
and thinner for small or new ones. Expect some `not_found`, and treat it as
absence of data rather than absence of technology.

**`technologies` is capped per domain.** The default 50 returns the complete
stack for all but a handful of sites: half of all domains run 3 technologies,
99% run 19 or fewer, and fewer than one in ten thousand exceed 50. When a
domain does have more, `totalTechnologies` tells you how many exist and
`hasMore` is true. Lowering the cap does not lower the price, which is per
domain either way.

### Links

- [StackScan API documentation](https://api.stackscan.com/docs)
- [Support](https://www.stackscan.com/contact)

# Actor input Schema

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

Websites to look up. A full URL is fine, it is reduced to its domain. Duplicates are removed before anything is charged.

## `apiToken` (type: `string`):

Leave empty and this Actor uses its own StackScan access, billed through Apify per result. Only fill this in if you already have a StackScan account and would rather spend your own credits, in which case you are not charged per result here.

## `workspaceId` (type: `string`):

Only needed alongside your own API token. Each StackScan workspace has its own credits and data. GET /v1/me lists the workspaces your token can reach.

## `technologiesPerDomain` (type: `integer`):

How many technologies to return for each website. Does not change the price, which is per domain.

## `category` (type: `string`):

Return only technologies in one category, for example Ecommerce. Leave empty for all of them.

## `stopOnInsufficientCredits` (type: `boolean`):

Stop as soon as the workspace runs out of bulk lookup credits, rather than continuing to request domains that cannot be served. Remaining domains are still written to the dataset, marked skipped.

## `includeCompanyData` (type: `boolean`):

Also return the company behind each website: name, industry, city, country and LinkedIn. This is a second lookup, so it costs one extra bulk lookup credit per resolved domain on top of the technology lookup.

## Actor input object example

```json
{
  "domains": [
    "allbirds.com",
    "gymshark.com"
  ],
  "technologiesPerDomain": 50,
  "stopOnInsufficientCredits": true,
  "includeCompanyData": false
}
```

# 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",
        "gymshark.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("stackscan/website-tech-stack-analysis").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",
        "gymshark.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("stackscan/website-tech-stack-analysis").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",
    "gymshark.com"
  ]
}' |
apify call stackscan/website-tech-stack-analysis --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,stackscan/website-tech-stack-analysis"
        }
    }
}

```

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/zcFcCgqUhzmfDWVia/builds/MtiCObfuDyhaxd9wZ/openapi.json
