# Brand DNA (`solutionssmart/brand-dna`) Actor

Extract structured brand identity from any website — colors, fonts, tone, positioning, and reusable marketing templates — using deterministic heuristics with no AI hallucinations.

- **URL**: https://apify.com/solutionssmart/brand-dna.md
- **Developed by:** [Solutions Smart](https://apify.com/solutionssmart) (community)
- **Categories:** AI, Automation, SEO tools
- **Stats:** 98 total users, 13 monthly users, 99.1% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $5.00 / 1,000 results

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

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

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

### 🚀 Brand DNA Actor (No LLM)

**Website Brand Analysis & Identity Extraction — Deterministic & Repeatable**

<img src="https://api.apify.com/v2/key-value-stores/edURsFKDP50Zm9aGO/records/brand-dna-hero.png" alt="Brand DNA visual concept" width="980" />

*Visual concept for Brand DNA live view, brand signal extraction, and campaign insight output.*

Brand DNA Actor automatically analyzes any business website and builds a structured Brand DNA profile — visual identity, tone, positioning, and reusable marketing templates — using deterministic heuristics only.

No LLMs. No hallucinations. No unpredictable output.

Just repeatable brand intelligence you can plug into audits, automation, and marketing workflows.

👉 Extract brand signals in seconds.

### 🔍 Why Use Brand DNA Actor?

Understanding a brand manually takes time:

- visual style analysis
- tone detection
- positioning evaluation
- copy signal extraction

This actor automates the entire process — turning website content into structured brand intelligence.

Perfect for agencies, growth teams, analysts, and automation builders.

### 🆚 Brand DNA vs Creation Tools

<img src="https://api.apify.com/v2/key-value-stores/edURsFKDP50Zm9aGO/records/brand-dna-vs-brand-creation.png" alt="Brand intelligence vs brand creation comparison" width="980" />

*A positioning snapshot showing Brand DNA as a deterministic brand intelligence engine built for structured extraction, workflows, and automation use cases.*

### ⚡ What Happens When You Run It

For each website:

✅ Crawl homepage + key internal pages \
✅ **SPA detection with Playwright fallback** (new in v2.0) \
✅ Extract colors, fonts, logo candidates \
✅ **CSS variable extraction for brand colors** (new in v2.0) \
✅ Detect tone and voice dimensions \
✅ Identify positioning signals \
✅ **CTA extraction with weighted scoring** (new in v2.0) \
✅ **Multi-signal extraction: JSON-LD, NEXT_DATA, meta tags** (new in v2.0) \
✅ Generate hero/tagline candidates \
✅ Build reusable CTA & ad templates \
✅ Produce a structured brand summary \

All deterministic. All repeatable.

### 🎯 Ideal Use Cases

- Competitor brand analysis
- Client onboarding audits
- Marketing template generation
- Website tone evaluation
- Creative direction baselines
- Automation pipelines (n8n / CRM workflows)
- Brand intelligence dashboards

### 🧠 Key Capabilities

#### Visual Identity Extraction
- Primary/secondary colors
- Accessibility contrast signals
- Typography detection
- Logo candidates
- **CSS variables for brand colors**

#### Copy & Voice Signals
- Top keywords & phrases
- CTA analysis with scoring
- Tone heuristics
- Voice dimensions

#### Positioning Intelligence
- Industry guess
- Audience signals
- Value propositions
- Brand attributes
- Positioning summary

#### Marketing Templates
- CTA rewrite variants
- Social post skeletons
- Short ad copy templates

#### Multi-Signal Extraction (new in v2.0)
- JSON-LD structured data (Organization, WebSite, LocalBusiness)
- Next.js `__NEXT_DATA__` parsing
- Nuxt data detection
- Meta/OpenGraph tag collection

### 📦 Output

Each run writes to the **default dataset**. The actor does **not** create separate datasets named "BrandKit" and "Templates".

Each analyzed website writes one `type: "brandDNA"` item to the default dataset.

Optional extras are nested into that same item:

- `brandKit`
- `templates`
- `pages` when `outputPages` is enabled
- `delta` when `outputDiff` is enabled
- `debug` when debug output is enabled
- `campaignInsights` for dashboard-ready monitoring, benchmarking, CTA prediction, localization, and automation cues 📊

The `brandDNA.brandKit` payload includes:

- Visual identity
- Tone & positioning
- Hero/tagline candidates
- Contacts
- **Signals from JSON-LD, NEXT_DATA, meta tags**
- Markdown brand summary

For multi-URL comparison runs, the side-by-side comparison is written to the key-value store as `comparison.json` instead of adding an extra dataset item.

The visual live view is written to the **default key-value store** for every successful run:

- `brand-dna-live.html`
- Sample live view: https://api.apify.com/v2/key-value-stores/7hwYhRVe1sq3aszvC/records/brand-dna-live.html

Optional extra file exports are written to the **default key-value store**, not the dataset:

- `brand-dna-output.json`
- `brand-dna-report.md`
- `brand-dna-report.pdf`
- `RUN_SUMMARY`
- `homepage-screenshot.png` when screenshots are enabled

The Actor now also defines a **key-value store schema** and an expanded **output schema**, so Apify Console can surface these files more clearly in the **Output** and **Storage** tabs. Collections are grouped as:

- HTML reports
- JSON exports
- Written reports
- Screenshots
- Comparison outputs
- Run summaries

#### Example Output

```json
{
  "type": "brandDNA",
  "startUrl": "https://www.apify.com",
  "detectedLanguage": "en",
  "artifacts": {
    "liveView": {
      "key": "brand-dna-live.html",
      "contentType": "text/html"
    },
    "runSummary": {
      "key": "RUN_SUMMARY",
      "contentType": "application/json"
    }
  },
  "brandKit": {
    "name": "Apify",
    "style": {
      "fonts": {
        "body": "Inter",
        "headings": "Inter",
        "buttons": "Inter"
      },
      "logo": {
        "url": "https://www.apify.com/img/apify-logo/wordmark.svg"
      }
    },
    "positioning": {
      "industryGuess": [{ "label": "software", "confidence": 0.95 }],
      "audience": [{ "label": "B2B", "confidence": 0.95 }],
      "valueProps": ["automation", "speed", "security", "reliability"],
      "positioningStatement": "Software platform for businesses and developers focused on automation, speed, and security."
    }
  },
  "templates": {
    "ctaVariants": ["Talk to a specialist", "Get in touch", "Reach out"]
  },
  "campaignInsights": {
    "brandConsistencyMonitor": {
      "status": "stable"
    },
    "abTestingPredictor": {
      "winner": {
        "text": "Try it now",
        "confidence": "high"
      }
    }
  }
}
````

### 🆕 New in v2.0

#### Hybrid Crawling (HTML-First + Fallback Rendering)

- Fast HTML extraction by default using CheerioCrawler
- Automatic SPA shell detection with Playwright fallback
- Domain hit-rate tracking for adaptive rendering decisions
- Configurable rendering timeout and selector waiting

#### Anti-Bot & Stability

- Apify Proxy integration (Residential/Datacenter)
- Adaptive concurrency (starts low, scales on success)
- Exponential backoff for 403/429 responses
- Request pacing to avoid rate limiting

#### Enhanced CTA Extraction

- Weighted scoring based on position, class, text, and href
- Hero/main position bonus, nav/footer penalty
- Action verb detection and generic label filtering
- Top-N ranked results

#### Multi-Signal Extraction

- JSON-LD structured data (Organization, WebSite, LocalBusiness)
- Next.js `__NEXT_DATA__` parsing
- Nuxt data detection
- Meta/OpenGraph tag collection
- CSS variable extraction for brand colors

### 📥 Input Configuration

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `startUrl` | string | **required** | Website URL to analyze |
| `startUrls` | string\[] | - | Optional batch mode input (1-20 URLs). When provided, `startUrl` is ignored. |
| `maxPages` | integer | 8 | Maximum pages to crawl (1-50) |
| `respectRobotsTxt` | boolean | true | Respect robots.txt rules |
| `timeoutSecs` | integer | 120 | Maximum crawl duration |
| `includeBlog` | boolean | true | Include blog pages |

#### 🖥️ Rendering Options

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `useRenderingFallback` | boolean | true | Enable Playwright for SPA shells |
| `renderingTimeoutMs` | integer | 1200 | Rendering timeout in ms |
| `renderingWaitForSelectors` | string | "main, h1, button" | Selectors to wait for |

#### 🌐 Proxy Options

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `useProxy` | boolean | true | Enable Apify Proxy |
| `proxyGroup` | string | "DATACENTER" | Proxy group (RESIDENTIAL/DATACENTER) |

#### 🚦 Concurrency Options

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `maxConcurrency` | integer | 2 | Maximum concurrent requests (1-8) |
| `adaptiveConcurrency` | boolean | true | Auto-adjust based on success |
| `requestDelayMs` | integer | 0 | Delay between requests |

#### 🔁 Retry Options

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `maxRequestRetries` | integer | 3 | Max retries per request |

#### 🛣️ Path filtering (new)

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `includePaths` | string\[] | — | Optional path allowlist (wildcards, e.g. `/products/*`). Start URL is always included. |
| `excludePaths` | string\[] | — | Optional path denylist (wildcards, e.g. `/blog/*`, `/legal/*`). |

#### 🌍 Multi-language & translation

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `language` | string | "auto" | Content language: **auto** (detect), **en**, **de**, **es**, **fr**, **it**, **pt** |
| `useLanguageDetector` | boolean | true | When language is Auto, use Apify [Language Detector](https://apify.com/zsoftware/language-detector) for ML-based detection |
| `useTranslation` | boolean | false | Translate page content to a target language before extraction |
| `translateToLanguage` | string | "en" | Target language when translation is enabled |
| `translationActorId` | string | — | Apify actor ID for translation (e.g. `tkapler/deepl-actor`) when Use translation is enabled |
| `translationBatchMode` | boolean | true | Send all page texts in one batch to the translation actor; falls back to sequential mode if unsupported |

#### 📦 Output extras (new)

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `outputFormat` | string | "single" | `single`: one default-dataset item with `type: brandDNA` containing nested outputs. `split` is deprecated and Store runs are forced to single-item output for billing safety. |
| `outputComparison` | boolean | false | When 2-5 URLs are provided, write side-by-side comparison output to `comparison.json` in the key-value store. |
| `outputPages` | boolean | false | Push one dataset item per crawled page with page-level extracted fields. |
| `outputDiff` | boolean | false | Compare current brandKit with previous cached snapshot and output a `delta` item. |
| `exportFormats` | string\[] | — | Optional extra file exports to KV store: `json`, `markdown`, `html`, `pdf`. The visual `brand-dna-live.html` live view is now written automatically for every successful run; `html` remains supported for backward compatibility. |

#### 🔔 Webhook options (new)

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `webhook.url` | string | — | Webhook destination URL (preferred over `callbackUrl`). |
| `webhook.events` | string\[] | `["completed","failed"]` | Events to send: `started`, `completed`, `failed`. |
| `webhook.retries` | integer | 1 | Retry attempts on network error / 5xx. |
| `webhook.retryDelayMs` | integer | 2000 | Delay between retries. |
| `webhook.timeoutMs` | integer | 10000 | Request timeout per attempt. |
| `webhook.secret` | string | — | Optional HMAC signing secret (`x-branddna-signature: sha256=...`). |
| `webhook.headers` | object | — | Optional custom headers map. |
| `callbackUrl` | string | — | Legacy fallback URL used when `webhook.url` is not set. |

#### Cache & cost

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `cacheTtlSeconds` | integer | 0 | Reuse a persisted cached result for the same URL and settings across runs within this many seconds. |
| `forceRefresh` | boolean | false | Skip reading from cache and always perform a fresh crawl. |

#### Example Input

Use `https://www.apify.com` as the recommended demo and smoke-test URL. It produces a representative multi-page brand profile without requiring special handling.

```json
{
  "startUrl": "https://www.apify.com",
  "mode": "full",
  "maxPages": 8,
  "crawlScope": "site",
  "respectRobotsTxt": true,
  "useProxy": true,
  "proxyGroup": "DATACENTER",
  "captureScreenshot": true,
  "outputPages": true,
  "outputDiff": true,
  "exportFormats": ["json", "markdown", "pdf"]
}
```

Supported locales: **English (en)**, **German (de)**, **Spanish (es)**, **French (fr)**, **Italian (it)**, and **Portuguese (pt)**. Extraction uses locale-specific stopwords, tone markers, industry/audience keywords, CTA maps, and templates. Add more languages by adding a `src/data/xx.js` locale file and registering it in `src/data/index.js`.

##### 🧾 Translation actor contract

When **Use translation** is enabled, Brand DNA calls your translation actor to translate page content before extraction. The actor must accept:

- **Single-text input:** `text` (string), `targetLanguage` (e.g. `en`, `de`), and optionally `sourceLanguage` (e.g. `auto`).
- **Batch input (optional):** `texts` (array of strings), `targetLanguage`. If supported, Brand DNA will send one batch per run instead of one call per page.

The actor’s default dataset should return items where each item has a translated string in one of: `translatedText`, `text`, or `translation`. For batch mode, return either one item per text in the same order, or one item with a `translations` array.

Known-compatible actors include [DeepL (AI translation)](https://apify.com/tkapler/deepl-actor). If batch mode fails (e.g. actor does not support `texts`), Brand DNA falls back to sequential single-text calls.

#### 🔗 Integrations: n8n, Make, Slack/Teams

**n8n & Make:** Use the Apify node (n8n) or Apify module (Make) to run Brand DNA. Input: `startUrl` or `startUrls` (array, max 20), plus optional `mode`, `maxPages`, `language`, `outputFormat`, `exportFormats`, `webhook`, etc. Output goes to the default dataset primarily as `type: brandDNA` items, plus `type: error` when a URL fails. The visual live view is always exposed as `brand-dna-live.html`, and optional extra reports and summaries are exposed in the default key-value store and linked in the Actor Output tab.

**Webhook:** Set `webhook.url` to receive signed JSON events (`started`, `completed`, `failed`). Base payload includes `{ event, timestamp, runId, datasetId, status, startUrls, resultsCount, errorCount }`. Configure retries/timeout/headers with `webhook.retries`, `webhook.retryDelayMs`, `webhook.timeoutMs`, and `webhook.headers`. If `webhook.secret` is set, the actor adds `x-branddna-signature` (HMAC-SHA256). `callbackUrl` remains supported as a fallback for backward compatibility.

### 🔄 Demo Workflow

Run → extract brand profile → feed into workflow:

```
Brand DNA Actor
   ↓
n8n / automation tool
   ↓
brand audit / template generator / CRM enrichment
```

Instant brand intelligence — no manual review required.

### 🎥 Video Walkthrough

See how the actor works and why to use it:

https://youtu.be/Eaxrf\_17DXM

### 🔒 Deterministic by Design

Unlike AI-driven analysis:

✔ repeatable outputs
✔ explainable heuristics
✔ no hallucinations
✔ stable automation pipelines

Perfect for production workflows.

### 🛠 Integration Ready

Works seamlessly with:

- Apify scheduling
- n8n workflows ([docs](docs/n8n-integration.md), [workflow JSON](n8n-workflow-brand-dna.json))
- OpenClaw ([docs](docs/openclaw-integration.md), [skill](skills/brand-dna/SKILL.md))
- CRM pipelines
- Reporting dashboards

### ⭐ Rate This Actor

If this actor helped you, please rate it on Apify. Your rating helps others discover it and supports future improvements.

### ⚠ Limitations

- Rule-based approximations

Designed for structured automation — not creative AI writing.

### 🎯 Final Value

Instead of manually dissecting websites…

You get:

👉 automated brand intelligence \
👉 reusable marketing assets \
👉 structured identity signals \
👉 repeatable analysis \\

All in seconds.

### 💳 Pricing

Brand DNA uses Apify pay-per-event pricing and is billed per analyzed website.

- **Base result:** one analyzed website, including up to `8` crawled pages.
- **Extended crawl:** if a run crawls `9` to `20` pages, one extra `extended_pages` event is charged.
- **High-volume crawl:** if a run crawls `21+` pages, the run charges `extended_pages` plus `high_volume_pages`.
- **Single-result billing:** each website still produces one main `type: "brandDNA"` dataset item, so nested outputs do not multiply result charges.
- **Included in the same result:** `brandKit`, `templates`, `campaignInsights`, optional `pages`, optional `delta`, and optional `debug` data.
- **Not billed as extra dataset items:** the visual live view (`brand-dna-live.html`), `RUN_SUMMARY`, screenshots, and `comparison.json` are written to the key-value store.

Current Store pricing is designed around these tiers:

- `1-8` pages: base result price
- `9-20` pages: base result price + extended crawl
- `21+` pages: base result price + extended crawl + high-volume crawl

This keeps smaller runs affordable while letting deeper audits cover their additional crawl and extraction cost more fairly.

# Actor input Schema

## `startUrl` (type: `string`):

Business website URL to analyze (for example https://www.apify.com). Ignored if Start URLs is provided.

## `startUrls` (type: `array`):

Optional list of URLs to analyze in one run. Provide 1 to 20 URLs. If set, Start URL is ignored.

## `mode` (type: `string`):

Full runs the full extraction flow. Fast limits page count and skips language detection and translation. Core keeps the run on the homepage for a low-latency brand profile.

## `maxPages` (type: `integer`):

Maximum number of pages to crawl.

## `crawlScope` (type: `string`):

Controls how tightly the crawl stays around the start URL. Auto keeps Apify actor pages focused on the actor path.

## `sitemapUrl` (type: `string`):

Optional sitemap URL. When set, URLs are taken from the sitemap instead of link discovery.

## `respectRobotsTxt` (type: `boolean`):

Skip URLs disallowed by robots.txt.

## `timeoutSecs` (type: `integer`):

Timeout per request in seconds.

## `language` (type: `string`):

Content language for extraction: auto, en, de, es, fr, it, or pt.

## `useLanguageDetector` (type: `boolean`):

When Language is auto, use the Apify Language Detector actor for ML-based detection.

## `useTranslation` (type: `boolean`):

Translate page content to a target language before extraction.

## `translateToLanguage` (type: `string`):

Target language code when translation is enabled, for example en or de.

## `translationActorId` (type: `string`):

Apify actor ID for translation when Use translation is enabled, for example tkapler/deepl-actor.

## `translationBatchMode` (type: `boolean`):

When enabled, send all page texts in one batch to the translation actor and fall back to sequential translation if unsupported.

## `includeBlog` (type: `boolean`):

Prioritize blog pages in the crawl.

## `includePaths` (type: `array`):

Optional path allowlist. Wildcards are supported, for example /products/\*.

## `excludePaths` (type: `array`):

Optional path denylist. Wildcards are supported, for example /blog/\* or /legal/\*.

## `useRenderingFallback` (type: `boolean`):

Enable Playwright rendering for SPA shells when needed.

## `renderingTimeoutMs` (type: `integer`):

Timeout for Playwright rendering in milliseconds.

## `renderingWaitForSelectors` (type: `string`):

Comma-separated CSS selectors to wait for before extracting content.

## `useProxy` (type: `boolean`):

Enable Apify Proxy for requests.

## `proxyGroup` (type: `string`):

Apify Proxy group to use. Datacenter is faster; use Residential if the site blocks datacenter IPs.

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

Maximum concurrent requests.

## `adaptiveConcurrency` (type: `boolean`):

Automatically adjust concurrency based on success rate.

## `requestDelayMs` (type: `integer`):

Delay between requests in milliseconds. Set to 0 to disable.

## `maxRequestRetries` (type: `integer`):

Maximum number of retries per request.

## `cacheTtlSeconds` (type: `integer`):

If greater than 0, reuse a persisted cached result for the same URL and settings across runs within this many seconds.

## `forceRefresh` (type: `boolean`):

Skip reading from cache and always perform a fresh crawl.

## `outputFormat` (type: `string`):

Single emits one dataset item per analyzed website. Split is deprecated and Store runs are forced to single-item output for billing safety.

## `outputComparison` (type: `boolean`):

When 2 to 5 URLs are provided, output an extra dataset item with a side-by-side comparison.

## `outputPages` (type: `boolean`):

Push one dataset item per crawled page with page-level extracted fields.

## `outputDiff` (type: `boolean`):

Compare the current brandKit with the most recent persisted snapshot for the same URL and settings and push a delta item.

## `exportFormats` (type: `array`):

Optional extra file exports for the key-value store. The visual HTML live view is always written automatically; use this to add JSON, Markdown, and PDF files. html remains accepted for backward compatibility.

## `callbackUrl` (type: `string`):

Legacy webhook URL fallback used when webhook.url is not set.

## `webhook` (type: `object`):

Optional webhook settings for started, completed, and failed events.

## `debug` (type: `boolean`):

Push an extra dataset item with intermediate data for support and tuning.

## `captureScreenshot` (type: `boolean`):

Save a viewport screenshot of the first page as homepage-screenshot.png in the key-value store.

## `extractImageColors` (type: `boolean`):

Fetch the logo or og:image URL and compute a dominant color for signals.dominantImageColor.

## `output` (type: `object`):

Select which outputs are pushed to the dataset.

## Actor input object example

```json
{
  "startUrl": "https://www.apify.com",
  "mode": "full",
  "maxPages": 8,
  "crawlScope": "auto",
  "respectRobotsTxt": true,
  "timeoutSecs": 120,
  "language": "auto",
  "useLanguageDetector": true,
  "useTranslation": false,
  "translateToLanguage": "en",
  "translationBatchMode": true,
  "includeBlog": true,
  "useRenderingFallback": true,
  "renderingTimeoutMs": 1200,
  "renderingWaitForSelectors": "main, h1, button",
  "useProxy": true,
  "proxyGroup": "DATACENTER",
  "maxConcurrency": 4,
  "adaptiveConcurrency": true,
  "requestDelayMs": 0,
  "maxRequestRetries": 3,
  "cacheTtlSeconds": 0,
  "forceRefresh": false,
  "outputFormat": "single",
  "outputComparison": false,
  "outputPages": false,
  "outputDiff": false,
  "webhook": {
    "events": [
      "completed",
      "failed"
    ],
    "retries": 1,
    "retryDelayMs": 2000,
    "timeoutMs": 10000
  },
  "debug": false,
  "captureScreenshot": false,
  "extractImageColors": false,
  "output": {
    "brandKit": true,
    "templates": true
  }
}
```

# Actor output Schema

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

Default dataset items containing one Brand DNA result per analyzed website.

## `runSummary` (type: `string`):

Always-available JSON summary of the run outcome, counts, thresholds, and screenshot status.

## `primaryHtmlReport` (type: `string`):

Always-available visual HTML live view for single-website runs.

## `primaryJsonExport` (type: `string`):

Structured JSON export for single-website runs when json export is enabled.

## `primaryMarkdownReport` (type: `string`):

Markdown report for single-website runs when markdown export is enabled.

## `primaryPdfReport` (type: `string`):

PDF report for single-website runs when pdf export is enabled.

## `homepageScreenshot` (type: `string`):

Viewport screenshot of the first crawled page when screenshot capture is enabled.

## `comparison` (type: `string`):

Multi-website comparison JSON when comparison output is enabled for 2 to 5 websites.

## `htmlReports` (type: `string`):

All generated HTML report records, including suffixed files for multi-website runs.

## `jsonExports` (type: `string`):

All generated JSON export records, including suffixed files for multi-website runs.

## `writtenReports` (type: `string`):

All generated Markdown and PDF report files, including suffixed files for multi-website runs.

## `screenshots` (type: `string`):

Screenshot records stored in the default key-value store.

## `comparisons` (type: `string`):

Comparison payload records stored in the default key-value store.

# 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 = {
    "startUrl": "https://www.apify.com"
};

// Run the Actor and wait for it to finish
const run = await client.actor("solutionssmart/brand-dna").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 = { "startUrl": "https://www.apify.com" }

# Run the Actor and wait for it to finish
run = client.actor("solutionssmart/brand-dna").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 '{
  "startUrl": "https://www.apify.com"
}' |
apify call solutionssmart/brand-dna --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Brand DNA",
        "description": "Extract structured brand identity from any website — colors, fonts, tone, positioning, and reusable marketing templates — using deterministic heuristics with no AI hallucinations.",
        "version": "2.0",
        "x-build-id": "Vq8wAYFzAuZFbBfp2"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/solutionssmart~brand-dna/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-solutionssmart-brand-dna",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/solutionssmart~brand-dna/runs": {
            "post": {
                "operationId": "runs-sync-solutionssmart-brand-dna",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/solutionssmart~brand-dna/run-sync": {
            "post": {
                "operationId": "run-sync-solutionssmart-brand-dna",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "startUrl": {
                        "title": "🌐 Start URL",
                        "type": "string",
                        "description": "Business website URL to analyze (for example https://www.apify.com). Ignored if Start URLs is provided."
                    },
                    "startUrls": {
                        "title": "🌐 Start URLs",
                        "minItems": 1,
                        "maxItems": 20,
                        "type": "array",
                        "description": "Optional list of URLs to analyze in one run. Provide 1 to 20 URLs. If set, Start URL is ignored.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "mode": {
                        "title": "⚙️ Mode",
                        "enum": [
                            "full",
                            "fast",
                            "core"
                        ],
                        "type": "string",
                        "description": "Full runs the full extraction flow. Fast limits page count and skips language detection and translation. Core keeps the run on the homepage for a low-latency brand profile.",
                        "default": "full"
                    },
                    "maxPages": {
                        "title": "📄 Max pages",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of pages to crawl.",
                        "default": 8
                    },
                    "crawlScope": {
                        "title": "🧭 Crawl scope",
                        "enum": [
                            "auto",
                            "site",
                            "path-prefix",
                            "single-page",
                            "actor-page"
                        ],
                        "type": "string",
                        "description": "Controls how tightly the crawl stays around the start URL. Auto keeps Apify actor pages focused on the actor path.",
                        "default": "auto"
                    },
                    "sitemapUrl": {
                        "title": "🗺️ Sitemap URL",
                        "type": "string",
                        "description": "Optional sitemap URL. When set, URLs are taken from the sitemap instead of link discovery."
                    },
                    "respectRobotsTxt": {
                        "title": "🤖 Respect robots.txt",
                        "type": "boolean",
                        "description": "Skip URLs disallowed by robots.txt.",
                        "default": true
                    },
                    "timeoutSecs": {
                        "title": "⏱️ Request timeout",
                        "minimum": 10,
                        "maximum": 300,
                        "type": "integer",
                        "description": "Timeout per request in seconds.",
                        "default": 120
                    },
                    "language": {
                        "title": "🌍 Language",
                        "enum": [
                            "auto",
                            "en",
                            "de",
                            "es",
                            "fr",
                            "it",
                            "pt"
                        ],
                        "type": "string",
                        "description": "Content language for extraction: auto, en, de, es, fr, it, or pt.",
                        "default": "auto"
                    },
                    "useLanguageDetector": {
                        "title": "🧠 Use language detector",
                        "type": "boolean",
                        "description": "When Language is auto, use the Apify Language Detector actor for ML-based detection.",
                        "default": true
                    },
                    "useTranslation": {
                        "title": "🌐 Use translation",
                        "type": "boolean",
                        "description": "Translate page content to a target language before extraction.",
                        "default": false
                    },
                    "translateToLanguage": {
                        "title": "🈯 Translate to language",
                        "type": "string",
                        "description": "Target language code when translation is enabled, for example en or de.",
                        "default": "en"
                    },
                    "translationActorId": {
                        "title": "🧩 Translation actor ID",
                        "type": "string",
                        "description": "Apify actor ID for translation when Use translation is enabled, for example tkapler/deepl-actor."
                    },
                    "translationBatchMode": {
                        "title": "📦 Translation batch mode",
                        "type": "boolean",
                        "description": "When enabled, send all page texts in one batch to the translation actor and fall back to sequential translation if unsupported.",
                        "default": true
                    },
                    "includeBlog": {
                        "title": "✍️ Include blog",
                        "type": "boolean",
                        "description": "Prioritize blog pages in the crawl.",
                        "default": true
                    },
                    "includePaths": {
                        "title": "✅ Include paths",
                        "type": "array",
                        "description": "Optional path allowlist. Wildcards are supported, for example /products/*.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "excludePaths": {
                        "title": "🚫 Exclude paths",
                        "type": "array",
                        "description": "Optional path denylist. Wildcards are supported, for example /blog/* or /legal/*.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "useRenderingFallback": {
                        "title": "🖥️ Use rendering fallback",
                        "type": "boolean",
                        "description": "Enable Playwright rendering for SPA shells when needed.",
                        "default": true
                    },
                    "renderingTimeoutMs": {
                        "title": "⏳ Rendering timeout",
                        "minimum": 500,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Timeout for Playwright rendering in milliseconds.",
                        "default": 1200
                    },
                    "renderingWaitForSelectors": {
                        "title": "👀 Wait for selectors",
                        "type": "string",
                        "description": "Comma-separated CSS selectors to wait for before extracting content.",
                        "default": "main, h1, button"
                    },
                    "useProxy": {
                        "title": "🛡️ Use proxy",
                        "type": "boolean",
                        "description": "Enable Apify Proxy for requests.",
                        "default": true
                    },
                    "proxyGroup": {
                        "title": "🌐 Proxy group",
                        "enum": [
                            "RESIDENTIAL",
                            "DATACENTER"
                        ],
                        "type": "string",
                        "description": "Apify Proxy group to use. Datacenter is faster; use Residential if the site blocks datacenter IPs.",
                        "default": "DATACENTER"
                    },
                    "maxConcurrency": {
                        "title": "🚦 Max concurrency",
                        "minimum": 1,
                        "maximum": 8,
                        "type": "integer",
                        "description": "Maximum concurrent requests.",
                        "default": 4
                    },
                    "adaptiveConcurrency": {
                        "title": "📈 Adaptive concurrency",
                        "type": "boolean",
                        "description": "Automatically adjust concurrency based on success rate.",
                        "default": true
                    },
                    "requestDelayMs": {
                        "title": "🐢 Request delay",
                        "minimum": 0,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Delay between requests in milliseconds. Set to 0 to disable.",
                        "default": 0
                    },
                    "maxRequestRetries": {
                        "title": "🔁 Max retries",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Maximum number of retries per request.",
                        "default": 3
                    },
                    "cacheTtlSeconds": {
                        "title": "💾 Cache TTL (seconds)",
                        "minimum": 0,
                        "maximum": 86400,
                        "type": "integer",
                        "description": "If greater than 0, reuse a persisted cached result for the same URL and settings across runs within this many seconds.",
                        "default": 0
                    },
                    "forceRefresh": {
                        "title": "♻️ Force refresh",
                        "type": "boolean",
                        "description": "Skip reading from cache and always perform a fresh crawl.",
                        "default": false
                    },
                    "outputFormat": {
                        "title": "📦 Output format",
                        "enum": [
                            "single",
                            "split"
                        ],
                        "type": "string",
                        "description": "Single emits one dataset item per analyzed website. Split is deprecated and Store runs are forced to single-item output for billing safety.",
                        "default": "single"
                    },
                    "outputComparison": {
                        "title": "⚖️ Output comparison",
                        "type": "boolean",
                        "description": "When 2 to 5 URLs are provided, output an extra dataset item with a side-by-side comparison.",
                        "default": false
                    },
                    "outputPages": {
                        "title": "📄 Output pages",
                        "type": "boolean",
                        "description": "Push one dataset item per crawled page with page-level extracted fields.",
                        "default": false
                    },
                    "outputDiff": {
                        "title": "🕰️ Output historical diff",
                        "type": "boolean",
                        "description": "Compare the current brandKit with the most recent persisted snapshot for the same URL and settings and push a delta item.",
                        "default": false
                    },
                    "exportFormats": {
                        "title": "📤 Export formats",
                        "type": "array",
                        "description": "Optional extra file exports for the key-value store. The visual HTML live view is always written automatically; use this to add JSON, Markdown, and PDF files. html remains accepted for backward compatibility.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "json",
                                "markdown",
                                "html",
                                "pdf"
                            ]
                        }
                    },
                    "callbackUrl": {
                        "title": "🔗 Callback URL",
                        "type": "string",
                        "description": "Legacy webhook URL fallback used when webhook.url is not set."
                    },
                    "webhook": {
                        "title": "🔔 Webhook",
                        "type": "object",
                        "description": "Optional webhook settings for started, completed, and failed events.",
                        "properties": {
                            "url": {
                                "title": "🔗 Webhook URL",
                                "type": "string",
                                "description": "Destination URL for webhook events.",
                                "editor": "textfield"
                            },
                            "events": {
                                "title": "🛎️ Events",
                                "type": "array",
                                "description": "Webhook events to send.",
                                "editor": "select",
                                "items": {
                                    "type": "string",
                                    "enum": [
                                        "started",
                                        "completed",
                                        "failed"
                                    ]
                                }
                            },
                            "retries": {
                                "title": "🔁 Retries",
                                "type": "integer",
                                "description": "Retry attempts on network error or 5xx response.",
                                "default": 1,
                                "minimum": 0,
                                "maximum": 5
                            },
                            "retryDelayMs": {
                                "title": "⏳ Retry delay",
                                "type": "integer",
                                "description": "Delay between retries in milliseconds.",
                                "default": 2000,
                                "minimum": 250,
                                "maximum": 10000,
                                "unit": "ms"
                            },
                            "timeoutMs": {
                                "title": "⏱️ Timeout",
                                "type": "integer",
                                "description": "Webhook request timeout in milliseconds.",
                                "default": 10000,
                                "minimum": 1000,
                                "maximum": 30000,
                                "unit": "ms"
                            },
                            "secret": {
                                "title": "🔐 Signing secret",
                                "type": "string",
                                "description": "Optional shared secret for HMAC-SHA256 signing.",
                                "editor": "textfield"
                            },
                            "headers": {
                                "title": "🧾 Headers",
                                "type": "object",
                                "description": "Optional custom headers map.",
                                "editor": "json"
                            }
                        },
                        "default": {
                            "events": [
                                "completed",
                                "failed"
                            ],
                            "retries": 1,
                            "retryDelayMs": 2000,
                            "timeoutMs": 10000
                        },
                        "additionalProperties": false
                    },
                    "debug": {
                        "title": "🐞 Debug output",
                        "type": "boolean",
                        "description": "Push an extra dataset item with intermediate data for support and tuning.",
                        "default": false
                    },
                    "captureScreenshot": {
                        "title": "📸 Capture screenshot",
                        "type": "boolean",
                        "description": "Save a viewport screenshot of the first page as homepage-screenshot.png in the key-value store.",
                        "default": false
                    },
                    "extractImageColors": {
                        "title": "🎨 Extract image colors",
                        "type": "boolean",
                        "description": "Fetch the logo or og:image URL and compute a dominant color for signals.dominantImageColor.",
                        "default": false
                    },
                    "output": {
                        "title": "🧾 Output options",
                        "type": "object",
                        "description": "Select which outputs are pushed to the dataset.",
                        "properties": {
                            "brandKit": {
                                "title": "🧬 Brand kit",
                                "type": "boolean",
                                "description": "Include the brandKit payload.",
                                "default": true
                            },
                            "templates": {
                                "title": "✍️ Templates",
                                "type": "boolean",
                                "description": "Include CTA, social, and ad-copy templates.",
                                "default": true
                            }
                        },
                        "default": {
                            "brandKit": true,
                            "templates": true
                        },
                        "additionalProperties": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
