# AI Tooling Detector Company AI Adoption Signals for Clay (`mambalabs/ai-tooling-detector`) Actor

Detects whether a company declares, deploys, or charges for AI. Returns a flat Clay-ready row with an AI maturity tier, detected AI vendors, llms.txt status, and pricing-page evidence.

- **URL**: https://apify.com/mambalabs/ai-tooling-detector.md
- **Developed by:** [Mamba Labs](https://apify.com/mambalabs) (community)
- **Categories:** Lead generation, Automation, AI
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.55 / 1,000 domain analyzeds

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

## AI Tooling Detector Company AI Adoption Signals for Clay

Give it a domain. It tells you whether the company just talks about AI, actually runs AI tooling on its site, or charges money for AI.

Most AI detectors return a boolean, which is close to useless for targeting. "Published an llms.txt" and "bills $0.99 per AI resolution" are the same answer to a yes-or-no question and completely different sales situations. This actor returns a four-level `ai_maturity` tier with the evidence behind it, as one flat Clay-ready row per domain.

### What's Inside

- [Features](#features)
- [The ai\_maturity ladder](#the-ai_maturity-ladder)
- [Input](#input)
- [Output](#output)
- [Pricing](#pricing)
- [Usage Examples](#usage-examples)
- [Error Handling](#error-handling)
- [Limitations](#limitations)

### Features

- **Four-level maturity tier, not a boolean.** none, declared, deployed, commercialized. Each rung needs its own class of evidence.
- **Pricing-page commercialization detection.** Finds AI credits, token allowances, AI add-ons, AI-named plans, and per-outcome AI pricing. This is the tier that tells you a company already pays for AI.
- **50+ AI vendor fingerprints.** Support agents (Sierra, Decagon, Ada, Intercom Fin, Forethought), AI search (Glean, Algolia, Inkeep, Kapa), personalization (Mutiny, Dynamic Yield), direct inference endpoints (OpenAI, Anthropic, Azure OpenAI, Bedrock, Gemini, Groq, Together, Fireworks), vector stores, and app frameworks.
- **Validated llms.txt, not just a 200.** A lot of single-page apps answer `/llms.txt` with their HTML shell. Those return `has_llms_txt: false` with a reject reason, so the strongest signal in the pack stays clean.
- **robots.txt AI crawler policy.** Reports which of 26 AI crawlers a company allows or blocks, with the rule that produced the verdict.
- **An explicit `blocked` flag.** A domain behind a bot challenge is reported as blocked at low confidence, never as a confident no. Without it a challenged domain looks identical to a company with no AI.
- **Evidence you can quote.** Every verdict ships the strings it was built from, so a rep can paste one into an email.
- **Batch input.** One domain or an array of them, analyzed concurrently.
- **HTTP only.** No browser, no proxy, 256MB. Runs finish in seconds.

### The ai\_maturity ladder

| Tier | What it means | What proves it |
|------|---------------|----------------|
| `commercialized` | The company charges for AI | AI credits, token allowances, an AI add-on, an AI-named plan, or a per-outcome AI price on the pricing page |
| `deployed` | AI tooling is running on the site | An AI-native vendor, a direct inference endpoint, or an AI-capable platform backed by AI copy |
| `declared` | The company says AI, nothing observable | A validated llms.txt, AI crawler rules in robots.txt, or weighted marketing copy |
| `none` | No signal fired | Nothing |

The ladder is strict. An llms.txt can never on its own reach `deployed`, and a chat widget can never on its own reach `commercialized`.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `domain` | string | `intercom.com` | A single company domain. Ignored when `domains` is filled. |
| `domains` | array | `[]` | Batch mode. Takes precedence over `domain`. |
| `check_pricing` | boolean | `true` | Fetch and score the pricing page. Turning this off makes runs faster but caps results at `deployed`, since `commercialized` can only be proven on a pricing page. |
| `batchSize` | integer | `5` | Domains analyzed concurrently, 1 to 10. |
| `request_timeout_ms` | integer | `9000` | Per-request timeout, 3000 to 20000. |
| `skipCache` | boolean | `false` | Ignore the 7 day result cache. |
| `qa_test_mode` | boolean | `false` | Emit a single summary row and skip all network work. |

### Output

One flat row per domain, snake\_case, Clay-native.

| Field | Type | Example |
|-------|------|---------|
| `domain` | string | `intercom.com` |
| `resolved_url` | string | `https://www.intercom.com/` |
| `http_status` | integer | `200` |
| `ai_maturity` | string | `commercialized` |
| `uses_ai` | boolean | `true` |
| `confidence` | number | `1` |
| `has_llms_txt` | boolean | `true` |
| `llms_txt_url` | string | `https://intercom.com/llms.txt` |
| `llms_txt_reject_reason` | string | `html_catch_all_route` |
| `has_ai_txt` | boolean | `false` |
| `robots_ai_directives` | array | `[{"agent":"GPTBot","policy":"block","rule":"disallow: /"}]` |
| `detected_tools` | array | `[{"vendor":"Intercom Fin","category":"support","ai_native":true,"confidence":"high","evidence":"markup match: fin.ai"}]` |
| `detected_tool_names` | string | `Intercom Fin` |
| `detected_categories` | array | `["support"]` |
| `ai_copy_matches` | array | `[{"pattern":"ai_assistant","weight":2,"evidence":"AI Agent"}]` |
| `ai_copy_weight` | integer | `8` |
| `ai_pricing_detected` | boolean | `true` |
| `ai_pricing_score` | integer | `10` |
| `pricing_url` | string | `https://www.intercom.com/pricing` |
| `evidence` | array | `["AI priced per resolved outcome: \"$0.99 per Fin outcome\""]` |
| `signals_fired` | array | `["llms_txt","vendor_fingerprint","pricing_commercialization"]` |
| `signals_missing` | array | `["ai_txt","robots_ai_directives"]` |
| `blocked` | boolean | `false` |
| `blocked_reason` | string | `http_202_challenge` |
| `is_js_rendered` | boolean | `false` |
| `fetch_error` | string | `null` |
| `is_summary_row` | boolean | `false` |
| `notice` | string | `null` |
| `checked_at` | string | `2026-08-05T17:20:00.000Z` |

Read `confidence` and `signals_missing` before trusting a `none`. A verdict built on one reachable page should not be read like a verdict built on five.

### Pricing

Pay per event. You are charged once per domain analyzed.

| Tier | Per domain | Per 1,000 domains |
|------|-----------|-------------------|
| Free | $0.003 | $3.00 |
| Bronze | $0.00285 | $2.85 |
| Silver | $0.0027 | $2.70 |
| Gold | $0.00255 | $2.55 |

Actor start is $0.00005 per run.

Free Apify-plan users get 15 results per calendar month. Paid plans are unlimited. When the free cap is reached the run exits cleanly with a notice row rather than an error.

Repeat lookups inside 7 days are served from cache.

### Usage Examples

#### Apify Console / API

```bash
curl -X POST "https://api.apify.com/v2/acts/EwkHhmqiuJgRoVEbE/runs?token=YOUR_TOKEN" \
  -H "content-type: application/json" \
  -d '{
    "domains": ["intercom.com", "notion.so", "berkshirehathaway.com"],
    "check_pricing": true,
    "batchSize": 5
  }'
```

#### Clay Integration

Add an Apify enrichment column, point it at this actor, and map your domain column to `domain`. Every output field lands as its own Clay column.

Useful follow-on formulas:

- Target companies that already buy AI: `ai_maturity = "commercialized"`
- Target companies that talk about AI but have not shipped it: `ai_maturity = "declared"`
- Suppress unreliable rows: `blocked = false AND confidence >= 0.6`

#### MCP Integration

```json
{
  "mcpServers": {
    "mamba-ai-tooling-detector": {
      "command": "npx",
      "args": ["-y", "@mambalabsdev/mcp-ai-tooling-detector"],
      "env": { "APIFY_TOKEN": "your_apify_token" }
    }
  }
}
```

This actor is also a tool on the [Mamba Labs GTM Suite](https://www.npmjs.com/package/@mambalabsdev/mcp-gtm-suite) server, which exposes the whole fleet through one install.

### Error Handling

| Condition | Behavior | Output |
|-----------|----------|--------|
| Homepage returns an anti-bot challenge | Row is still emitted, flagged, and confidence pinned to 0.15 | `blocked: true`, `blocked_reason` set |
| Homepage returns 200 with no server-side text | Row emitted and flagged as a client-rendered shell | `is_js_rendered: true`, confidence reduced |
| Pricing page unreachable or missing | Analysis continues; the verdict caps at `deployed` | `pricing_url: null`, `ai_pricing_score: 0` |
| `/llms.txt` answers 200 with an HTML shell | Not counted as an llms.txt | `has_llms_txt: false`, `llms_txt_reject_reason` set |
| Connection reset or timeout | Row emitted with the transport error recorded | `fetch_error` set, `http_status: null` |
| Key-value store unavailable | Fails open: runs without the cache and without quota enforcement | Normal rows |
| Free-tier monthly cap reached | Exits cleanly before any network work | One notice row, `is_summary_row: true` |
| No domain supplied | Exits cleanly | One notice row |

The run always produces at least one dataset item.

### Limitations

- **Vendor recall is capped by what the server sends.** Modern chat widgets are injected by client-side JavaScript, so a company running an AI widget that never appears in the served markup will read as `declared` rather than `deployed`. On a 15 domain AI-forward sample, 9 reached `deployed` or better and 14 reached at least `declared`. Adding a browser would raise recall and would also raise the memory floor to 1024MB and the price with it. The tradeoff was made deliberately in favor of price.
- **Anti-bot challenges affect roughly 10% of domains**, concentrated in large consumer brands and retail. Those rows come back `blocked: true` rather than silently negative. No proxy is configured by default.
- **`commercialized` requires a reachable pricing page.** Companies that gate pricing behind "contact sales" cannot be proven to commercialize AI from the outside.
- **`declared` is a claim, not a deployment.** That is the point of separating it, but do not read it as adoption.
- **llms.txt prevalence is only 5 to 13%.** It is a high-precision positive whose absence proves nothing.
- **Fingerprints need maintenance.** Vendors change script URLs. The category's incumbent has gone 138 days without a rebuild, which is what fingerprint rot looks like.

***

**Part of the [Mamba Labs GTM Intelligence Suite](https://apify.com/mambalabs)**

| Actor | Actor ID |
|-------|----------|
| [GTM Hiring Signal Scraper](https://apify.com/mambalabs/gtm-hiring-signal-scraper) | D7O1SA2EqwHGsGr1P |
| [GTM Tech Stack Signal Enrichment](https://apify.com/mambalabs/gtm-tech-stack-signal-scraper) | qyd7nNyqFPelQViBx |
| [GTM Signals Aggregator](https://apify.com/mambalabs/b2b-buying-signals-hiring-tech-stack-intent-for-clay) | xKdRfnfFNkdMpFuNs |
| [Job Board Keyword Signal Scanner](https://apify.com/mambalabs/job-board-keyword-signal-scanner) | 4DvqpvhMR74NLcDDY |
| [Domain to LinkedIn URL Resolver](https://apify.com/mambalabs/domain-to-linkedin-url-resolver) | 3HtnSaqPHOg1Qg5gx |
| [ICP Fit Scorer](https://apify.com/mambalabs/icp-account-lead-scoring-fit-scorer-0-100-for-clay) | W161DT8W4kW55dMFh |
| [Domain Deliverability Checker](https://apify.com/mambalabs/domain-deliverability-checker) | 0tVgxI7A6o9jMlxmc |
| [Company Firmographic Enricher](https://apify.com/mambalabs/company-firmographic-enricher) | YlUtLWjfPpqykmB8g |
| [Company Social Presence Mapper](https://apify.com/mambalabs/company-social-presence-mapper) | 4k6CCemkgBDz18m2h |
| [Company Identity Resolver](https://apify.com/mambalabs/company-identity-resolver) | lr8fTRAmZCBZmuwwh |
| [Funding & Press Signal Scanner](https://apify.com/mambalabs/funding-press-signal-scanner) | FS13X6dhQVgX3XOM6 |
| [Company Change-Event Feed](https://apify.com/mambalabs/company-change-event-feed) | oX44rS0fkEJ3rXLWe |
| [Job Posting Monitor](https://apify.com/mambalabs/gtm-job-discovery) | QCfICD9kOPiOdj5iI |
| [AI Tooling Detector](https://apify.com/mambalabs/ai-tooling-detector) | EwkHhmqiuJgRoVEbE |

Built by [Mamba Labs](https://apify.com/mambalabs).

# Actor input Schema

## `domain` (type: `string`):

A single company domain, for example intercom.com. Ignored when Company domains is filled.

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

Analyze many domains in one run. Takes precedence over the single domain field.

## `check_pricing` (type: `boolean`):

Fetch the pricing page to detect whether AI is actually charged for. Turning this off makes runs faster but caps the result at deployed, since commercialized can only be proven on a pricing page.

## `batchSize` (type: `integer`):

How many domains to analyze at once. 1 to 10.

## `request_timeout_ms` (type: `integer`):

Per-request timeout. 3000 to 20000.

## `skipCache` (type: `boolean`):

Ignore the 7 day result cache and re-analyze every domain from scratch.

## `qa_test_mode` (type: `boolean`):

Emit a single summary row and skip all network work. Used for automated checks.

## Actor input object example

```json
{
  "domain": "intercom.com",
  "domains": [],
  "check_pricing": true,
  "batchSize": 5,
  "request_timeout_ms": 9000,
  "skipCache": false,
  "qa_test_mode": 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 = {
    "domain": "intercom.com",
    "domains": [],
    "check_pricing": true,
    "batchSize": 5,
    "request_timeout_ms": 9000,
    "skipCache": false,
    "qa_test_mode": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("mambalabs/ai-tooling-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 = {
    "domain": "intercom.com",
    "domains": [],
    "check_pricing": True,
    "batchSize": 5,
    "request_timeout_ms": 9000,
    "skipCache": False,
    "qa_test_mode": False,
}

# Run the Actor and wait for it to finish
run = client.actor("mambalabs/ai-tooling-detector").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "domain": "intercom.com",
  "domains": [],
  "check_pricing": true,
  "batchSize": 5,
  "request_timeout_ms": 9000,
  "skipCache": false,
  "qa_test_mode": false
}' |
apify call mambalabs/ai-tooling-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=mambalabs/ai-tooling-detector",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/EwkHhmqiuJgRoVEbE/builds/hicnHg1RW2hDzZ0Bh/openapi.json
