# Website Tech Stack & Security Header Detector (`craigtechservicesllc/website-tech-stack-security-header-detector`) Actor

Detect 72 public website technologies and assess eight browser-security headers in bulk using bounded, SSRF-resistant HTTP analysis.

- **URL**: https://apify.com/craigtechservicesllc/website-tech-stack-security-header-detector.md
- **Developed by:** [Daniel Craig](https://apify.com/craigtechservicesllc) (community)
- **Categories:** Developer tools, SEO tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 public website analyzeds

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

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 Tech Stack & Security Header Detector

Analyze public websites in bulk and export evidence-based technology fingerprints plus eight browser-security-header checks. The Actor uses bounded raw HTTP requests, stores no page HTML, requires no external API key, and charges the per-site event only when a public HTML page is successfully analyzed.

### What it detects

The built-in catalog currently covers 72 technologies across:

- CMS and commerce: WordPress, WooCommerce, Shopify, Wix, Squarespace, Webflow, Drupal, Joomla, Ghost, Magento, BigCommerce, PrestaShop, Contentful, and Sanity.
- Frameworks: Next.js, Nuxt, React, Vue, Angular, Svelte/SvelteKit, Gatsby, Astro, Remix, Express, Laravel, Django, Rails, ASP.NET, Java Servlet, and PHP.
- CDN and hosting: Cloudflare, Akamai, Fastly, CloudFront, KeyCDN, Bunny CDN, Vercel, Netlify, Fly.io, Render, Heroku, and GitHub Pages.
- JavaScript and CSS: jQuery, Bootstrap, Tailwind CSS, Alpine.js, HTMX, Stimulus, GSAP, and Swiper.
- Analytics, marketing, support, and payments: Google Analytics, Google Tag Manager, Meta Pixel, Hotjar, Microsoft Clarity, Segment, Plausible, Matomo, HubSpot, Marketo, Klaviyo, Mailchimp, Intercom, Zendesk, Drift, Crisp, Tawk.to, Stripe, PayPal, Square, and Braintree.

Every detection contains short evidence labels such as `header:cf-ray` or `html:Next.js fingerprint`. Header values and page HTML are not copied into the evidence.

### Security-header checks

Each successful result explicitly reports whether the response provides:

1. Strict-Transport-Security
2. Content-Security-Policy
3. clickjacking protection through X-Frame-Options or CSP `frame-ancestors`
4. X-Content-Type-Options `nosniff`
5. Referrer-Policy
6. Permissions-Policy
7. Cross-Origin-Opener-Policy
8. Cross-Origin-Resource-Policy

Missing headers are returned as missing, never silently treated as present. This is an observation of one public response, not a penetration test or compliance certification.

### Input

Choose exactly one source:

```json
{
  "urls": [
    "https://wordpress.org",
    "https://shopify.com",
    "https://apify.com"
  ],
  "maxItems": 1000,
  "concurrency": 10,
  "timeoutMs": 15000,
  "maxResponseBytes": 2000000,
  "maxRedirects": 5,
  "deduplicate": true
}
```

Or use `items` / `datasetId` with `urlField`, including a nested dot path such as `company.website`.

Bare domains are interpreted as HTTPS. Identical normalized URLs can be emitted as uncharged duplicate records instead of being fetched twice.

### Output

One dataset row is emitted for every accepted source row. A successful row contains the final URL, HTTP status, page title, detected technology names/categories/evidence, security-header assessment, redirect count, and response byte count. Failed and duplicate rows contain explicit uncharged statuses and error codes.

```json
{
  "sourceIndex": 0,
  "inputUrl": "https://example.com",
  "normalizedUrl": "https://example.com/",
  "finalUrl": "https://example.com/",
  "status": "analyzed",
  "httpStatus": 200,
  "pageTitle": "Example Domain",
  "technologyNames": [],
  "securityHeaders": {
    "presentCount": 2,
    "assessedCount": 8,
    "missing": ["content-security-policy"]
  },
  "charged": true
}
```

### Network and privacy boundary

- Only public HTTP and HTTPS targets are allowed.
- Local/private hostnames, credentials in URLs, and private, loopback, link-local, reserved, multicast, test-network, or otherwise non-unicast IP addresses are blocked.
- DNS answers are checked before the connection and the approved public IP is pinned for that request.
- Every redirect is resolved and checked again before it is followed.
- Response size, redirects, concurrency, source rows, and request time are bounded.
- Full HTML, response-header values, cookies, screenshots, and individual request bodies are not stored in the dataset or logs.
- Logs contain aggregate settings and counts only.

### Evidence limitations

This Actor examines the raw public HTTP response. Client-rendered technologies that leave no initial HTML or header fingerprint may not be visible. A fingerprint can establish evidence that a technology is present, but absence of a fingerprint does not prove a technology is absent. The Actor does not claim exact versions or a complete private server-side stack.

### Pricing behavior

The Actor uses pay-per-event pricing:

- one small run-start event;
- one `site-analyzed` event for each successfully fetched and analyzed public HTML page;
- invalid, blocked, failed, non-HTML, spending-limited, and duplicate rows are not charged the per-site event.

Apify enforces the caller's maximum total charge. If the remaining spending limit cannot cover another site event, unfetched rows are returned with `SPENDING_LIMIT_REACHED` rather than silently overspending.

### Common uses

- enrich lead or company datasets with website-platform signals;
- identify CMS, commerce, analytics, and payment technologies across a domain list;
- segment migration, integration, or security-assessment opportunities;
- inventory public security-header coverage;
- feed structured website technology evidence into Apify schedules, webhooks, APIs, or MCP workflows.

# Actor input Schema

## `urls` (type: `array`):

One public HTTP or HTTPS URL per row. Bare domains are interpreted as HTTPS.

## `items` (type: `array`):

Objects containing a URL field. Use urlField to select a nested value.

## `datasetId` (type: `string`):

Dataset in the current Apify account. Never place an API token in this field.

## `urlField` (type: `string`):

Dot path used for JSON items or dataset rows.

## `maxItems` (type: `integer`):

Hard run limit. Truncation is explicitly reported in the run summary.

## `concurrency` (type: `integer`):

Number of public sites checked concurrently.

## `timeoutMs` (type: `integer`):

A slow site is stopped and returned as an explicit uncharged timeout instead of holding the run indefinitely.

## `maxResponseBytes` (type: `integer`):

Responses larger than this limit are stopped and returned as uncharged failures.

## `maxRedirects` (type: `integer`):

Every redirect target is independently checked against the public-network policy.

## `deduplicate` (type: `boolean`):

Duplicate rows are emitted as uncharged duplicate records rather than fetched again.

## `userAgent` (type: `string`):

Optional public request identifier, up to 300 characters. Do not place secrets here.

## Actor input object example

```json
{
  "urls": [
    "https://www.wordpress.org",
    "https://www.shopify.com",
    "https://www.apify.com"
  ],
  "urlField": "url",
  "maxItems": 1000,
  "concurrency": 10,
  "timeoutMs": 15000,
  "maxResponseBytes": 2000000,
  "maxRedirects": 5,
  "deduplicate": true
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset rows containing detected technologies, evidence labels, security-header checks, and bounded failure details.

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

Counts, truncation flags, effective settings, charged-event count, and the evidence boundary.

# 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 = {
    "urls": [
        "https://www.wordpress.org",
        "https://www.shopify.com",
        "https://www.apify.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("craigtechservicesllc/website-tech-stack-security-header-detector").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 = { "urls": [
        "https://www.wordpress.org",
        "https://www.shopify.com",
        "https://www.apify.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("craigtechservicesllc/website-tech-stack-security-header-detector").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 '{
  "urls": [
    "https://www.wordpress.org",
    "https://www.shopify.com",
    "https://www.apify.com"
  ]
}' |
apify call craigtechservicesllc/website-tech-stack-security-header-detector --silent --output-dataset

```

## MCP server setup

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

```

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/zJwgb2cPlVAZqJ9uK/builds/LQE1CCpr9SE99SgQU/openapi.json
