# B2B Domain & Tech-Spend Enricher API (`dekaz/b2b-domain-tech-enricher`) Actor

Enrich domains with 79 curated website technology signals, rule-based confidence and evidence, ecommerce detection, company metadata, social profiles, and HTTP status—fast, without a browser.

- **URL**: https://apify.com/dekaz/b2b-domain-tech-enricher.md
- **Developed by:** [Progamadores.com](https://apify.com/dekaz) (community)
- **Categories:** Lead generation, E-commerce, Developer tools
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 successful domain enrichments

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## B2B Domain & Tech-Spend Enricher API

This is a fast bulk domain enrichment Actor for sales intelligence, lead scoring, market research, and CRM enrichment. Submit company domains and receive structured signals from a catalog of **60+ B2B and ecommerce technologies**, plus company, social, page, and HTTP metadata.

> **Quick start:** Open the **Input** tab, paste `shopify.com` and `wordpress.com`, and click **Start**. The primary `domain-enriched` event is **$1.00 per 1,000 successful enrichments**. Error records do not trigger that event; the Actor start event and Apify platform usage can still apply as shown in the **Pricing** tab.

The Actor uses lightweight asynchronous HTTP requests instead of a headless browser. It shares connections, streams bounded responses, and processes domains concurrently, so it is designed to use less memory and compute than browser-based crawlers.

> **Tech-spend means technology adoption signals.** This Actor identifies tools a website appears to use; it does not calculate or estimate monetary software expenditure.
>
> **All detections are heuristic.** A match does not verify a commercial relationship, active subscription, legal company identity, or ownership of a linked logo or social profile.

### What does this domain enrichment API detect?

- **60+ curated signatures** across ecommerce, CMS, analytics, marketing, advertising, payments, customer support, frontend, and infrastructure categories
- Representative platforms and tools such as **Shopify, WordPress, WooCommerce, Magento, Google Analytics, Google Tag Manager, Stripe, HubSpot, Klaviyo, Next.js, and React**
- Structured technology details with category, `high` or `medium` heuristic confidence, and sanitized matching evidence
- Public profile links on **LinkedIn, Instagram, Facebook, Twitter, and X**
- Cart, checkout, product, storefront, and payment signals
- Company or site name, logo URL, favicon URL, language, homepage title, and meta description
- Canonical URL, final URL after redirects, final HTTP status, analysis timestamp, and detector catalog version
- A structured per-domain error when a website cannot be analyzed completely

Technology detection is pattern-based. The Actor inspects selected response headers and the returned HTML, including inline JavaScript and external script URLs present in that HTML. It does not launch a browser, execute JavaScript, crawl internal pages, download linked images, or download external JavaScript bundles.

### B2B sales intelligence and technographic use cases

Use this website technology lookup API to:

- Enrich company and prospect lists before importing them into a CRM
- Segment leads by ecommerce platform, analytics tool, or marketing technology
- Find Shopify, WooCommerce, Magento, PrestaShop, and BigCommerce stores
- Identify companies using HubSpot, Klaviyo, Stripe, Google Analytics, or Meta Pixel
- Prioritize outreach using technology adoption and ecommerce signals
- Build technographic datasets for market research
- Discover public company social profiles
- Add website titles and descriptions to incomplete lead records

### Input

Paste one domain or homepage URL per line in Apify Console, or send the following JSON through the API:

```json
{
  "domains": [
    "shopify.com",
    "https://wordpress.com"
  ],
  "maxConcurrency": 25,
  "requestTimeoutSecs": 10
}
```

#### Input fields

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `domains` | `string[]` | Yes | — | Between 1 and 1,000 public domains or homepage URLs. |
| `maxConcurrency` | `integer` | No | `25` | Simultaneous domain fetches, from 1 to 50. The worker count never exceeds the number of submitted domains. |
| `requestTimeoutSecs` | `integer` | No | `10` | Total network-fetch deadline per domain, from 3 to 30 seconds. |

The Actor normalizes uppercase and internationalized domain names and requests the website root. For a bare domain, it tries HTTPS first and may fall back to HTTP only when the TCP/TLS connection cannot be established or that connection attempt times out. An explicitly supplied `https://` URL is never downgraded. Explicit ports, credentials in URLs, IP address inputs, and non-public network destinations are rejected for safety.

### Output

Every submitted domain produces one item in the run's default Apify Dataset. The original v1.0 fields remain unchanged; v1.1 adds top-level fields so existing integrations can continue reading `domain`, `technologies`, `socialLinks`, `hasEcommerce`, and `titleAndDescription`.

The following is a **clearly illustrative** v1.1 response shape for `shopify.com`. Website metadata, linked assets, redirects, and detected technologies can change between runs, and none of the values represents third-party verification.

```json
{
  "domain": "shopify.com",
  "technologies": [
    "Shopify",
    "Google Tag Manager"
  ],
  "technologyDetails": [
    {
      "name": "Shopify",
      "category": "Ecommerce",
      "confidence": "high",
      "evidence": [
        "html:cdn.shopify.com",
        "html:/cdn/shop/"
      ]
    },
    {
      "name": "Google Tag Manager",
      "category": "Tag manager",
      "confidence": "high",
      "evidence": [
        "html:googletagmanager.com/gtm.js"
      ]
    }
  ],
  "socialLinks": [
    "https://www.linkedin.com/company/shopify"
  ],
  "hasEcommerce": true,
  "titleAndDescription": {
    "title": "Shopify: The All-in-One Commerce Platform",
    "description": "Start, run, and grow a business with Shopify."
  },
  "companyName": "Shopify",
  "logo": "https://www.shopify.com/cdn/shop/files/shopify-logo.svg",
  "favicon": "https://www.shopify.com/favicon.ico",
  "language": "en",
  "canonicalUrl": "https://www.shopify.com/",
  "finalUrl": "https://www.shopify.com/",
  "httpStatus": 200,
  "analyzedAt": "2026-08-07T10:00:00Z",
  "detectorVersion": "1.1.0"
}
```

#### Output fields

| Field | Type | Description |
| --- | --- | --- |
| `domain` | `string` | Canonical hostname when normalization succeeds; otherwise a safe label derived from the submitted value. |
| `technologies` | `string[]` | Backward-compatible technology names matched through selected response-header or HTML patterns. |
| `technologyDetails` | `object[]` | Additive v1.1 detail objects containing `name`, functional `category`, heuristic `confidence` (`high` or `medium`), and sanitized `evidence[]` markers. Evidence uses the prefixes `html:`, `header:`, `cookie-name:`, or `implied-by:` and never contains raw header or cookie values. The names correspond to the backward-compatible `technologies` array. |
| `socialLinks` | `string[]` | Public LinkedIn, Instagram, Facebook, Twitter, or X links; at most one per platform. |
| `hasEcommerce` | `boolean` | Whether ecommerce technology, cart, checkout, product, storefront, or payment signals were detected. |
| `titleAndDescription` | `object` | Homepage title and meta description; Open Graph or Twitter description is used as fallback, and either value can be `null`. |
| `companyName` | `string \| null` | Company or site name inferred from public page metadata; not a verified legal entity name. |
| `logo` | `string \| null` | Resolved logo URL found in page metadata, normalized without query or fragment. The asset is not downloaded or verified. |
| `favicon` | `string \| null` | Resolved favicon URL found in page metadata, normalized without query or fragment. The asset is not downloaded or verified. |
| `language` | `string \| null` | Language tag declared by the returned page. |
| `canonicalUrl` | `string \| null` | Absolute canonical URL declared by the returned page, normalized without query or fragment. |
| `finalUrl` | `string \| null` | Final fetched URL after redirects, normalized without query or fragment. |
| `httpStatus` | `integer \| null` | Final HTTP status, or `null` when no response was obtained. |
| `analyzedAt` | `string` | UTC ISO 8601 timestamp for completion of the domain analysis. |
| `detectorVersion` | `string` | Version of the technology signature catalog used for the record. |
| `error` | `string` | Optional stable error code and safe message when analysis was incomplete. |

If a domain fails, the Actor does not abort the rest of the batch. It returns the five main fields plus an `error` value:

```json
{
  "domain": "unavailable.example",
  "technologies": [],
  "technologyDetails": [],
  "socialLinks": [],
  "hasEcommerce": false,
  "titleAndDescription": {
    "title": null,
    "description": null
  },
  "companyName": null,
  "logo": null,
  "favicon": null,
  "language": null,
  "canonicalUrl": null,
  "finalUrl": null,
  "httpStatus": null,
  "analyzedAt": "2026-08-07T10:00:00Z",
  "detectorVersion": "1.1.0",
  "error": "DNS_FAILED: The domain could not be resolved"
}
```

When `error` is present, empty fields and `hasEcommerce: false` mean that no positive signal could be extracted; they are not proof that the unreachable website uses no ecommerce technology.

Common error codes include `INVALID_DOMAIN`, `DNS_FAILED`, `SSRF_BLOCKED`, `TIMEOUT`, `NETWORK_ERROR`, `NON_HTML`, `UNSUPPORTED_ENCODING`, `REDIRECT_LOOP`, `TOO_MANY_REDIRECTS`, and `HTTP_<status>`.

### Run the Actor with cURL

Replace `YOUR_APIFY_TOKEN` with your Apify API token:

```bash
curl -L -X POST \
  "https://api.apify.com/v2/actors/dekaz~b2b-domain-tech-enricher/run-sync-get-dataset-items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "domains": ["shopify.com", "wordpress.com"],
    "maxConcurrency": 25,
    "requestTimeoutSecs": 10
  }'
```

The synchronous endpoint can wait for up to 300 seconds. For large lists, start a regular asynchronous Actor run and retrieve its Dataset after completion.

### Run the Actor from Python

Install the official Apify API client:

```bash
pip install apify-client
```

```python
import os

from apify_client import ApifyClient


client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor(
    "dekaz/b2b-domain-tech-enricher"
).call(
    run_input={
        "domains": ["shopify.com", "wordpress.com"],
        "maxConcurrency": 25,
        "requestTimeoutSecs": 10,
    }
)

if run is None:
    raise RuntimeError("The Actor run did not finish successfully")

for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)
```

### Run the Actor asynchronously through the REST API

For long lists, start the run without holding an HTTP connection open:

```bash
curl -X POST \
  "https://api.apify.com/v2/actors/dekaz~b2b-domain-tech-enricher/runs" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["shopify.com", "wordpress.com"]}'
```

The response contains the run under `data`; use `data.id` for the run ID and `data.defaultDatasetId` for its Dataset. After the run finishes, retrieve all records from:

```text
https://api.apify.com/v2/datasets/DEFAULT_DATASET_ID/items
```

### Export and automate enriched B2B data

Results live in an Apify Dataset, so you can:

- Download domain enrichments as JSON, JSONL, CSV, Excel, XML, HTML, or RSS
- Schedule recurring lead-enrichment runs
- Trigger downstream workflows with webhooks
- Connect results to Make, Zapier, Google Sheets, CRMs, or custom applications
- Filter and select output fields through the Dataset API
- Monitor run status, usage, and individual website errors in Apify Console

### Performance and memory behavior

- A single shared asynchronous HTTP client handles all domains.
- Fixed-size worker and result queues prevent unbounded task creation.
- Responses are requested without compression, streamed, and capped at the first 750 KB of HTML.
- Results are written to the Dataset in small batches rather than retained until the run ends.
- Redirects are followed manually for at most five hops.
- DNS lookup, redirects, HTTPS-to-HTTP fallback, and response download share the configured network deadline. Bounded HTML parsing runs immediately afterward.

Increasing `maxConcurrency` can shorten a run, but also raises peak memory and network usage. The default value of 25 is intended as a balanced starting point; benchmark representative domains before raising it.

### Security and responsible use

The Actor accepts user-supplied destinations, so it validates the initial domain and every redirect. It rejects credentials, explicit ports, IP address inputs, and destinations resolving to private, loopback, link-local, reserved, multicast, or otherwise non-public addresses. Its network transport connects to the validated public IP while preserving the original Host header and TLS SNI, preventing a second DNS lookup from redirecting the socket to an internal address. TLS certificate verification remains enabled.

Only submit websites you are permitted to access. You are responsible for complying with applicable law, website terms, robots policies, and data-protection obligations. The Actor does not automatically request `robots.txt`, because doing so would add a separate network request for every domain.

### Limitations

- Pattern matching can produce false negatives or, less commonly, false positives.
- Client-rendered technologies can be missed because JavaScript is not executed.
- External script contents are not downloaded; only their URLs in the HTML are inspected.
- Consent managers, tag managers, bot protection, authentication, and geographic variants can hide signals.
- Only the final homepage HTML is analyzed; internal product, cart, contact, or checkout pages are not crawled.
- The response limit can omit signatures found very late in unusually large documents.
- Social share, login, OAuth, and intent URLs are excluded, but a discovered link is not independently verified.
- `hasEcommerce` is an inference. It does not perform a purchase or prove that checkout is operational.

### Frequently asked questions

#### Does this Actor execute JavaScript?

No. It inspects server-returned HTML, inline JavaScript, and script source URLs. This design keeps the Actor fast and memory-efficient.

#### Can I use it as a Shopify, WordPress, or WooCommerce detector?

Yes. All three are included in the built-in technology signature set, together with ecommerce, analytics, marketing, payment, and frontend tools.

#### Can I enrich domains in bulk?

Yes. One run accepts up to 1,000 unique input strings. For large jobs, prefer an asynchronous Actor run over the synchronous API endpoint.

#### Are the results suitable for CRM enrichment?

Yes. Each domain becomes a predictable Dataset item suitable for sales intelligence pipelines, lead scoring, spreadsheets, CRMs, and custom APIs.

#### Why is a known technology missing?

It may load only after JavaScript execution, behind a consent action, from an external bundle whose source is not downloaded, or on an internal page the Actor does not visit.

#### How is the Actor priced?

The Actor uses **pay-per-event** pricing. The `domain-enriched` event costs **$0.001 per successful domain enrichment ($1.00 per 1,000)**. It is charged only when a complete enrichment record is stored without an `error`; invalid or failed domains are returned for diagnostics but do not trigger this event. If the run reaches its maximum charge, remaining inputs receive a free `BUDGET_EXHAUSTED` record instead of an uncharged enrichment.

Apify platform usage is charged separately based on the resources consumed by the run. Each run also triggers the standard `apify-actor-start` event at **$0.00005 for up to 1 GB of allocated memory**, then once per additional GB. The total run price is therefore the event charges plus platform usage. Always check the Actor's **Pricing** tab for the effective pricing before starting a run, and use a representative sample to estimate completion time.

### Ready to enrich a domain list?

Open the **Input** tab, paste `shopify.com` and `wordpress.com`, and start a small run. Review the Dataset and effective **Pricing** before scaling to a production list of up to 1,000 domains.

# Actor input Schema

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

Paste one public domain or homepage URL per line. Examples: shopify.com or https://wordpress.com.

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

Maximum number of domains fetched at the same time. The default balances speed and memory use.

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

Maximum total network-fetch time per domain, including DNS lookup, redirects, HTTPS-to-HTTP fallback, and response download.

## Actor input object example

```json
{
  "domains": [
    "shopify.com",
    "wordpress.com"
  ],
  "maxConcurrency": 25,
  "requestTimeoutSecs": 10
}
```

# Actor output Schema

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

Technology, ecommerce, social, company metadata, and HTTP signals for every submitted domain. Existing v1.0 fields remain unchanged; v1.1 fields are additive.

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

// Run the Actor and wait for it to finish
const run = await client.actor("dekaz/b2b-domain-tech-enricher").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",
        "wordpress.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("dekaz/b2b-domain-tech-enricher").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",
    "wordpress.com"
  ]
}' |
apify call dekaz/b2b-domain-tech-enricher --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dekaz/b2b-domain-tech-enricher"
        }
    }
}

```

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/Tsua0AtxM51fvLC7C/builds/3AezPBFeg0VyBJjk9/openapi.json
