# Tech Stack & Email Provider Detector (`fieldfeed/tech-stack-email-provider-detector`) Actor

Find the CMS, ecommerce platform, analytics, marketing tools, payment providers and email provider (Google Workspace, Microsoft 365...) behind any list of websites. Clean table output. $3 per 1,000 websites, only pay for sites analyzed.

- **URL**: https://apify.com/fieldfeed/tech-stack-email-provider-detector.md
- **Developed by:** [Rama Y](https://apify.com/fieldfeed) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 domain checkeds

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Tech Stack & Email Provider Detector

Paste in a list of websites. For each one you get back what it runs on: **CMS, ecommerce platform, analytics and ad pixels, marketing, CRM and chat tools, payment providers, JavaScript frameworks, CDN/hosting and web server**, plus the company's **email provider** (Google Workspace, Microsoft 365, ...), the **sending services** in its SPF record, and the **SaaS tools it has verified** in DNS. Every technology comes with a confidence score and the evidence it was found from.

**$3 per 1,000 websites.** You only pay for websites that were reached and analyzed.

### Use cases

- **Lead lists for agencies and SaaS sales:** find every Shopify store using Klaviyo, every WordPress site without analytics, or every company on Microsoft 365.
- **Competitor research:** see which analytics, A/B testing, chat and payment tools competitors use.
- **Stack change alerts:** schedule it weekly with "Output only changed domains" on, and get only the websites whose stack changed, with added and removed lists (for example "moved from Mailchimp to Klaviyo" or "added Stripe").
- **Enrichment:** add CMS, ecommerce platform and email provider columns to any company list.

### What it detects

About 66 technologies:

| Category | Technologies |
|---|---|
| CMS | WordPress, Wix, Squarespace, Webflow, Drupal, Joomla, Ghost, HubSpot CMS |
| Ecommerce | Shopify, WooCommerce, BigCommerce, Magento, PrestaShop |
| Analytics, tags and ads | Google Analytics (GA4), Google Tag Manager, Google Ads, Meta Pixel, TikTok Pixel, LinkedIn Insight Tag, Hotjar, Segment, Mixpanel, Plausible, Microsoft Clarity, Cookiebot, OneTrust |
| Marketing, CRM and chat | HubSpot, Klaviyo, Mailchimp, Intercom, Drift, Zendesk, Crisp, Tawk.to |
| Payments | Stripe, PayPal, Shop Pay |
| Frameworks and libraries | React, Next.js, Vue.js, Nuxt.js, Angular, Svelte/SvelteKit, Gatsby, jQuery, Bootstrap, Tailwind CSS |
| CDN and hosting | Cloudflare, Vercel, Netlify, Amazon CloudFront, Fastly, Akamai |
| Servers | nginx, Apache, LiteSpeed, Microsoft IIS, PHP, Express |
| A/B testing and reviews | Optimizely, VWO, Trustpilot, Yotpo, Judge.me |
| Fonts | Google Fonts, Adobe Fonts |

**From DNS:**

- **Email provider** (MX records): Google Workspace, Microsoft 365, Zoho, Proton, Fastmail, Mimecast, Proofpoint, Barracuda, Cisco, Amazon WorkMail, Yandex, iCloud, GoDaddy, OVH, IONOS, Cloudflare Email Routing and more.
- **Sending services** (SPF): Google, Microsoft 365, SendGrid, Mailgun, Amazon SES, Mailchimp, HubSpot, Salesforce, Marketo, Zendesk, Klaviyo, Postmark, Brevo and more.
- **Verified services** (TXT records): Google, Meta, Microsoft 365, Atlassian, Apple, DocuSign, Stripe, Adobe, Zoom, Slack, OpenAI and more. Only the service name is output, never the token.

### Input

| Field | Default | What it does |
|---|---|---|
| Domains | (required) | Domains or URLs. Paths are ignored and duplicates removed. |
| Extra same-site pages to fetch | 1 | Also checks up to 2 more pages like /pricing or /shop. Never more than 3 pages per website. |
| Check DNS | on | Looks up the email provider, SPF services and verifications. |
| Max concurrency | 10 | Websites checked in parallel. |
| Request timeout | 15 s | Timeout per request. |
| Output only changed domains | off | Only outputs websites whose stack changed since your previous run. |

Example input:

```
{
  "domains": ["example-store.com", "https://www.example-saas.io/pricing"],
  "followLinks": 1,
  "checkDns": true
}
```

### Output

One row per website, with a clean table view in the dataset:

```
{
  "domain": "example-store.com",
  "status": "ok",
  "technologies": [
    {"name": "Shopify", "category": "Ecommerce", "confidence": 100,
     "evidence": ["header x-shopify-stage: production"]},
    {"name": "Klaviyo", "category": "Email marketing", "confidence": 95,
     "evidence": ["script src: https://static.klaviyo.com/onsite/js/klaviyo.js"]}
  ],
  "flags": {"is_shopify": true, "ecommerce_platform": "Shopify", "cms": "Shopify",
            "email_provider": "Google Workspace", "uses_stripe": false, "has_analytics": true},
  "emailProvider": "Google Workspace",
  "spfServices": ["Google Workspace", "Klaviyo"],
  "verifiedServices": ["Google Search Console / Workspace", "Meta Business"],
  "pagesFetched": 2,
  "changes": {"added": ["Klaviyo"], "removed": ["Mailchimp"], "firstSeen": false},
  "checkedAt": "2026-10-06T12:00:00+00:00"
}
```

**Status values:** ok (analyzed), http_error (the site answered 4xx/5xx), blocked_by_robots, unreachable, dns_only (site down but DNS found), invalid_domain, error.

### Pricing

**$0.003 per successfully checked website** ($3 per 1,000).

- You are only charged when a website was reached and analyzed. Invalid, unreachable, robots-blocked and error websites are free.
- With "Output only changed domains", unchanged websites are still checked and charged.
- If you set a maximum charge for a run, the Actor stops starting new websites once it is reached.

### Limits

- Up to 3 pages per website, no JavaScript rendering. Tools that load only after the page runs (for example tags injected by Google Tag Manager) may be missed. Tag Manager itself is detected.
- Detection is fingerprint-based and can be wrong. Use the confidence and evidence fields to judge each result.
- Sites behind strong bot protection may return http_error.

### Responsible use

- **Public pages only.** No logins, no forms, no cookies sent back, no URLs with query strings. Login, account, cart and checkout pages are skipped.
- **robots.txt is respected** on every page (user-agent token FieldfeedTechStack), with crawl-delay honored up to 5 seconds.
- **No personal data.** No emails, phone numbers or names are collected. Evidence text is scrubbed of anything that looks like an email or phone number, and cookie values and DNS tokens are never output.
- You are responsible for using the results in line with applicable laws and each site's terms.

### Support

Found a website it gets wrong, or need a custom version? Open an issue on this Actor.

# Actor input Schema

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

Domains or URLs to analyse, e.g. example.com or https://www.example.com. Paths are ignored; duplicates are removed.

## `followLinks` (type: `integer`):

Besides the homepage, fetch up to this many same-site links (prefers /pricing, /about, /shop ...). Hard cap: 3 pages per domain.

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

Look up MX and TXT records to identify the email provider, SPF-authorised sending services and domain-verification tokens (only the service name is reported).

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

How many domains are processed in parallel. Pages within one domain are always fetched sequentially.

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

Timeout for each HTTP request and DNS lookup.

## `changedOnly` (type: `boolean`):

Compare with the previous run's results (stored in the named key-value store 'fieldfeed-techstack-state') and output only domains whose technology set, email provider or SPF services changed, with added/removed lists. Domains seen for the first time count as changed.

## Actor input object example

```json
{
  "domains": [
    "apify.com",
    "shopify.com"
  ],
  "followLinks": 1,
  "checkDns": true,
  "maxConcurrency": 10,
  "requestTimeoutSecs": 15,
  "changedOnly": false
}
```

# Actor output Schema

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

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("fieldfeed/tech-stack-email-provider-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 = { "domains": [
        "apify.com",
        "shopify.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("fieldfeed/tech-stack-email-provider-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 '{
  "domains": [
    "apify.com",
    "shopify.com"
  ]
}' |
apify call fieldfeed/tech-stack-email-provider-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fieldfeed/tech-stack-email-provider-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/0lFo434I2l4WOWhWW/builds/Pe4AJ2xflw81zg7y5/openapi.json
