# AI Visibility Competitor Share of Voice (`zinin/ai-visibility-competitor-share-of-voice`) Actor

Compare target-brand and competitor positions across buyer-supplied AI visibility observations with transparent overall and segment metrics.

- **URL**: https://apify.com/zinin/ai-visibility-competitor-share-of-voice.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Marketing, SEO tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $16.15 / 1,000 ai visibility competitor share-of-voice report delivereds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## AI Visibility Competitor Share of Voice

Turn AI-answer observations you already own into one deterministic competitive visibility report. Compare your target brand with up to ten competitors across model family, market, and language—without calling an LLM, crawling a website, or sending data outside Apify.

![Buyer observations become exact competitive metrics](https://api.apify.com/v2/key-value-stores/yG6I9e4kTpoDj0zr7/records/share-of-voice-metric-flow.png)

### What this Actor does

Each successful run writes exactly one complete row to the default Dataset. It includes visibility, configured-entity share of voice, first-position rate, average position, a deterministic competitor ranking, and bounded breakdowns by model family, market, and language. Every percentage retains its numerator and denominator.

The result is designed for recurring client reports, dashboard ingestion, competitive benchmarking, and before/after comparisons where repeatability matters more than opaque scoring.

### Who this is for

AI-search marketers, agencies, analysts, and measurement teams that already own normalized observations and need a repeatable competitive summary.

### The business question it answers

For the exact supplied sample: how often was the target mentioned, how did configured competitors compare, which competitor led, and how did the result vary by model family, market, and language?

### Input: inline observations

Run the public Task `compare-ai-visibility-share-of-voice` (Task ID `fEJHMBaHfH2exSoeW`). Its fictional Acme prefill contains six normalized observations and produces one complete example report with no provider API key or private Dataset reference.

For your own analysis, supply 2–500 observations directly in `observations`. The smallest valid shape contains two rows:

```json
{
  "schemaVersion": "1.0",
  "analysisId": "acme-q4-benchmark",
  "targetBrand": "Acme",
  "competitors": ["Beta", "Gamma"],
  "observations": [
    {
      "schemaVersion": "1.0",
      "observationId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "brand": "Acme",
      "competitors": ["Beta"],
      "modelFamily": "ChatGPT",
      "market": "US",
      "language": "en",
      "mentioned": true,
      "position": 1
    },
    {
      "schemaVersion": "1.0",
      "observationId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
      "brand": "Acme",
      "competitors": ["Gamma"],
      "modelFamily": "Gemini",
      "market": "US",
      "language": "en",
      "mentioned": false,
      "position": null
    }
  ],
  "maximumSegmentsPerDimension": 10
}
```

The repeated-character IDs above illustrate the required 64-character lowercase SHA-256 shape; use immutable content hashes in production.

### Exact observation contract

| Field | Required | Meaning |
| --- | --- | --- |
| `schemaVersion` | Yes | Input contract version; currently `1.0`. |
| `analysisId` | Yes | Your stable identifier for this analysis. |
| `targetBrand` | Yes | Canonical target label shared by every observation. |
| `competitors` | Yes | One to ten unique canonical competitor labels. |
| `observations` | Yes | Two to 500 normalized observations supplied inline. |
| `maximumSegmentsPerDimension` | Yes | Required API display cap from 1 to 20; the UI prefill is 10. |

Each observation supplies its immutable ID, target label, ordered mentioned competitors, model family, market, language, target mention boolean, and target position or `null`. Compatible producer extras are ignored. Unknown, duplicate, partial, ambiguous, or internally inconsistent input fails before output. Source Dataset references are not accepted.

### Metrics and formulas

- **Visibility rate** = entity mentions ÷ eligible observations.
- **Share of voice** = entity mentions ÷ all target-plus-configured-competitor mentions.
- **First-position rate** = first positions ÷ positioned mentions.
- **Average position** = position sum ÷ positioned mentions.

All displayed values use integer half-up rounding.

### Overall and segment completeness

Overall metrics always include every accepted unique observation. Model-family, market, and language groups are ordered deterministically and bounded by `maximumSegmentsPerDimension`. `SEGMENTS_TRUNCATED` declares omitted display groups; it never hides source truncation.

### Output schema

The default Dataset receives one closed report object:

```json
{
  "schemaVersion": "ai-visibility-competitor-share-of-voice-report-1.0",
  "reportId": "823054fffa8e6d22b86efbe4b8f4540869a5658e1e831fa26bd1873737592c6b",
  "analysisId": "acme-ai-sov-2026-q4",
  "status": "COMPLETE",
  "targetBrand": "Acme",
  "competitors": ["Beta", "Gamma"],
  "source": {
    "mode": "INLINE",
    "suppliedObservationCount": 6,
    "acceptedUniqueObservationCount": 6
  },
  "overall": {
    "observationCount": 6,
    "totalEntityMentions": 11
  }
}
```

The complete row also contains entity-level fractions, formatted percentages, ranking, segment items, limitations, and exact billing facts. No KVS OUTPUT, HTML, CSV, webhook, secondary Dataset, or synthetic diagnostic row is written.

### Pricing and paid unit

Pay Per Event charges the platform Actor Start event and one `result-found` event only after the complete report is durably delivered.

| Tier | Actor start | Complete report | Maximum total |
| --- | ---: | ---: | ---: |
| Free | $0.006000 | $0.019000 | $0.025000 |
| Bronze | $0.005700 | $0.018050 | $0.023750 |
| Silver | $0.005400 | $0.017100 | $0.022500 |
| Gold | $0.005100 | $0.016150 | $0.021250 |
| Platinum | $0.004920 | $0.015580 | $0.020500 |
| Diamond | $0.004800 | $0.015200 | $0.020000 |

Invalid or incomplete work emits no `result-found` event. The public Task caps total charge at **$0.025**, enough for exactly one report at every tier.

![A complete Dataset row is confirmed before the paid result event](https://api.apify.com/v2/key-value-stores/yG6I9e4kTpoDj0zr7/records/paid-complete-report-path.png)

### Use with Make, n8n and the API

Start the public Task through the Apify API:

```bash
curl -X POST \
  "https://api.apify.com/v2/actor-tasks/fEJHMBaHfH2exSoeW/runs?token=YOUR_APIFY_TOKEN&waitForFinish=120"
```

Read `defaultDatasetId` from the returned Run and fetch that Dataset's single item. In Make or n8n, use the same endpoint, wait for a terminal status, and pass the row to your reporting or warehouse step. Check the original Run before retrying a timed-out request so a completed paid run is not duplicated.

### Privacy, rights and retention

- The Actor runs with limited permissions and accepts inline observations only.
- It requests no provider tokens, cookies, proxies, Dataset access, or arbitrary Run IDs.
- It makes no external network, model, search, or child-Actor calls.
- You must own or be authorized to process the supplied observations and labels.
- Extra prose, citations, and PII-like fields are not promoted into the output contract.

### Limitations

This report covers only the supplied sample and configured entities. It does not measure sentiment, citations, recommendation quality, universal model coverage, traffic, market share, conversion, revenue, or causation. Competitor positions are reconstructed only from the supplied ordered mentions and target position.

### Troubleshooting

- **Input fails immediately:** verify every observation ID is unique, labels match the top-level configuration, and the Input contains 2–500 rows.
- **Position is rejected:** ensure `position` agrees with the target and ordered competitor mentions; use `null` when the target is not mentioned.
- **No report is written:** inspect the Run error, correct the Input, and confirm the charge limit covers the current tier before starting a new run.
- **Some segment groups are absent:** raise `maximumSegmentsPerDimension`; overall metrics are never truncated.

### FAQ

**Does it collect live AI answers?** No. It analyzes normalized observations you supply.

**Can overall metrics be truncated?** No. Only bounded segment presentation can be truncated.

**Why retain numerators and denominators?** They make percentages auditable and allow downstream aggregation without reverse-engineering rounded values.

**Can one run produce several reports?** No. One successful run produces exactly one complete report and at most one `result-found` event.

# Actor input Schema

## `schemaVersion` (type: `string`):

Fixed contract version. Keep 1.0.

## `analysisId` (type: `string`):

Stable buyer-defined identifier for this report.

## `targetBrand` (type: `string`):

Exact tracked brand used for all observation validation. Every observations\[].brand value must match this value after normalization.

## `competitors` (type: `array`):

One to ten exact competitor names included in share-of-voice metrics. Names must remain unique after normalization, must not equal targetBrand, and form the allowlist for every observations\[].competitors value.

## `observations` (type: `array`):

Two to 500 buyer-supplied normalized AI visibility observations. Use a unique observationId in every row; brand must exactly match targetBrand; row competitors must be unique members of the top-level competitors list; position must be null when mentioned is false and otherwise no greater than the row competitor count plus one.

## `maximumSegmentsPerDimension` (type: `integer`):

Retain the top one to 20 model, market and language groups; overall metrics always remain complete.

## Actor input object example

```json
{
  "schemaVersion": "1.0",
  "analysisId": "acme-ai-sov-2026-q4",
  "targetBrand": "Acme",
  "competitors": [
    "Beta",
    "Gamma"
  ],
  "observations": [
    {
      "schemaVersion": "1.0",
      "observationId": "1dd0242ec51569d105f1d541f97fec03202ff2632f507b5b03f45393a0985793",
      "brand": "Acme",
      "competitors": [
        "Beta"
      ],
      "modelFamily": "ChatGPT",
      "market": "US",
      "language": "en",
      "mentioned": true,
      "position": 1
    },
    {
      "schemaVersion": "1.0",
      "observationId": "6d5d40cc4239b90a29a6b01f05afc95f6014e147653733a88c0b8b0cc2f9608b",
      "brand": "Acme",
      "competitors": [
        "Beta",
        "Gamma"
      ],
      "modelFamily": "ChatGPT",
      "market": "US",
      "language": "en",
      "mentioned": false,
      "position": null
    },
    {
      "schemaVersion": "1.0",
      "observationId": "02bb02668bb610c21e80f39887124fcbe21ba70cce9ea951f5545cfee30a11dd",
      "brand": "Acme",
      "competitors": [
        "Gamma"
      ],
      "modelFamily": "Gemini",
      "market": "US",
      "language": "en",
      "mentioned": true,
      "position": 2
    },
    {
      "schemaVersion": "1.0",
      "observationId": "6d2f681dd1da0ee26756b2b6d918f20534226762040feaf0ef200c419008c7d7",
      "brand": "Acme",
      "competitors": [],
      "modelFamily": "Gemini",
      "market": "UK",
      "language": "en",
      "mentioned": true,
      "position": 1
    },
    {
      "schemaVersion": "1.0",
      "observationId": "4ca3603e3fc5118141211654becfa32d6a52b8d9c175e750205f249ffadced9c",
      "brand": "Acme",
      "competitors": [
        "Beta"
      ],
      "modelFamily": "Perplexity",
      "market": "UK",
      "language": "en",
      "mentioned": false,
      "position": null
    },
    {
      "schemaVersion": "1.0",
      "observationId": "75156e90a81c700b669dec421a50880014a91bc7a42a7a337d1f7655a3cb7cba",
      "brand": "Acme",
      "competitors": [
        "Beta",
        "Gamma"
      ],
      "modelFamily": "Perplexity",
      "market": "US",
      "language": "en",
      "mentioned": true,
      "position": 1
    }
  ],
  "maximumSegmentsPerDimension": 10
}
```

# Actor output Schema

## `report` (type: `string`):

One complete report with overall and bounded model, market and language segments.

# 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 = {
    "schemaVersion": "1.0",
    "analysisId": "acme-ai-sov-2026-q4",
    "targetBrand": "Acme",
    "competitors": [
        "Beta",
        "Gamma"
    ],
    "observations": [
        {
            "schemaVersion": "1.0",
            "observationId": "1dd0242ec51569d105f1d541f97fec03202ff2632f507b5b03f45393a0985793",
            "brand": "Acme",
            "competitors": [
                "Beta"
            ],
            "modelFamily": "ChatGPT",
            "market": "US",
            "language": "en",
            "mentioned": true,
            "position": 1
        },
        {
            "schemaVersion": "1.0",
            "observationId": "6d5d40cc4239b90a29a6b01f05afc95f6014e147653733a88c0b8b0cc2f9608b",
            "brand": "Acme",
            "competitors": [
                "Beta",
                "Gamma"
            ],
            "modelFamily": "ChatGPT",
            "market": "US",
            "language": "en",
            "mentioned": false,
            "position": null
        },
        {
            "schemaVersion": "1.0",
            "observationId": "02bb02668bb610c21e80f39887124fcbe21ba70cce9ea951f5545cfee30a11dd",
            "brand": "Acme",
            "competitors": [
                "Gamma"
            ],
            "modelFamily": "Gemini",
            "market": "US",
            "language": "en",
            "mentioned": true,
            "position": 2
        },
        {
            "schemaVersion": "1.0",
            "observationId": "6d2f681dd1da0ee26756b2b6d918f20534226762040feaf0ef200c419008c7d7",
            "brand": "Acme",
            "competitors": [],
            "modelFamily": "Gemini",
            "market": "UK",
            "language": "en",
            "mentioned": true,
            "position": 1
        },
        {
            "schemaVersion": "1.0",
            "observationId": "4ca3603e3fc5118141211654becfa32d6a52b8d9c175e750205f249ffadced9c",
            "brand": "Acme",
            "competitors": [
                "Beta"
            ],
            "modelFamily": "Perplexity",
            "market": "UK",
            "language": "en",
            "mentioned": false,
            "position": null
        },
        {
            "schemaVersion": "1.0",
            "observationId": "75156e90a81c700b669dec421a50880014a91bc7a42a7a337d1f7655a3cb7cba",
            "brand": "Acme",
            "competitors": [
                "Beta",
                "Gamma"
            ],
            "modelFamily": "Perplexity",
            "market": "US",
            "language": "en",
            "mentioned": true,
            "position": 1
        }
    ],
    "maximumSegmentsPerDimension": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/ai-visibility-competitor-share-of-voice").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 = {
    "schemaVersion": "1.0",
    "analysisId": "acme-ai-sov-2026-q4",
    "targetBrand": "Acme",
    "competitors": [
        "Beta",
        "Gamma",
    ],
    "observations": [
        {
            "schemaVersion": "1.0",
            "observationId": "1dd0242ec51569d105f1d541f97fec03202ff2632f507b5b03f45393a0985793",
            "brand": "Acme",
            "competitors": ["Beta"],
            "modelFamily": "ChatGPT",
            "market": "US",
            "language": "en",
            "mentioned": True,
            "position": 1,
        },
        {
            "schemaVersion": "1.0",
            "observationId": "6d5d40cc4239b90a29a6b01f05afc95f6014e147653733a88c0b8b0cc2f9608b",
            "brand": "Acme",
            "competitors": [
                "Beta",
                "Gamma",
            ],
            "modelFamily": "ChatGPT",
            "market": "US",
            "language": "en",
            "mentioned": False,
            "position": None,
        },
        {
            "schemaVersion": "1.0",
            "observationId": "02bb02668bb610c21e80f39887124fcbe21ba70cce9ea951f5545cfee30a11dd",
            "brand": "Acme",
            "competitors": ["Gamma"],
            "modelFamily": "Gemini",
            "market": "US",
            "language": "en",
            "mentioned": True,
            "position": 2,
        },
        {
            "schemaVersion": "1.0",
            "observationId": "6d2f681dd1da0ee26756b2b6d918f20534226762040feaf0ef200c419008c7d7",
            "brand": "Acme",
            "competitors": [],
            "modelFamily": "Gemini",
            "market": "UK",
            "language": "en",
            "mentioned": True,
            "position": 1,
        },
        {
            "schemaVersion": "1.0",
            "observationId": "4ca3603e3fc5118141211654becfa32d6a52b8d9c175e750205f249ffadced9c",
            "brand": "Acme",
            "competitors": ["Beta"],
            "modelFamily": "Perplexity",
            "market": "UK",
            "language": "en",
            "mentioned": False,
            "position": None,
        },
        {
            "schemaVersion": "1.0",
            "observationId": "75156e90a81c700b669dec421a50880014a91bc7a42a7a337d1f7655a3cb7cba",
            "brand": "Acme",
            "competitors": [
                "Beta",
                "Gamma",
            ],
            "modelFamily": "Perplexity",
            "market": "US",
            "language": "en",
            "mentioned": True,
            "position": 1,
        },
    ],
    "maximumSegmentsPerDimension": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("zinin/ai-visibility-competitor-share-of-voice").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 '{
  "schemaVersion": "1.0",
  "analysisId": "acme-ai-sov-2026-q4",
  "targetBrand": "Acme",
  "competitors": [
    "Beta",
    "Gamma"
  ],
  "observations": [
    {
      "schemaVersion": "1.0",
      "observationId": "1dd0242ec51569d105f1d541f97fec03202ff2632f507b5b03f45393a0985793",
      "brand": "Acme",
      "competitors": [
        "Beta"
      ],
      "modelFamily": "ChatGPT",
      "market": "US",
      "language": "en",
      "mentioned": true,
      "position": 1
    },
    {
      "schemaVersion": "1.0",
      "observationId": "6d5d40cc4239b90a29a6b01f05afc95f6014e147653733a88c0b8b0cc2f9608b",
      "brand": "Acme",
      "competitors": [
        "Beta",
        "Gamma"
      ],
      "modelFamily": "ChatGPT",
      "market": "US",
      "language": "en",
      "mentioned": false,
      "position": null
    },
    {
      "schemaVersion": "1.0",
      "observationId": "02bb02668bb610c21e80f39887124fcbe21ba70cce9ea951f5545cfee30a11dd",
      "brand": "Acme",
      "competitors": [
        "Gamma"
      ],
      "modelFamily": "Gemini",
      "market": "US",
      "language": "en",
      "mentioned": true,
      "position": 2
    },
    {
      "schemaVersion": "1.0",
      "observationId": "6d2f681dd1da0ee26756b2b6d918f20534226762040feaf0ef200c419008c7d7",
      "brand": "Acme",
      "competitors": [],
      "modelFamily": "Gemini",
      "market": "UK",
      "language": "en",
      "mentioned": true,
      "position": 1
    },
    {
      "schemaVersion": "1.0",
      "observationId": "4ca3603e3fc5118141211654becfa32d6a52b8d9c175e750205f249ffadced9c",
      "brand": "Acme",
      "competitors": [
        "Beta"
      ],
      "modelFamily": "Perplexity",
      "market": "UK",
      "language": "en",
      "mentioned": false,
      "position": null
    },
    {
      "schemaVersion": "1.0",
      "observationId": "75156e90a81c700b669dec421a50880014a91bc7a42a7a337d1f7655a3cb7cba",
      "brand": "Acme",
      "competitors": [
        "Beta",
        "Gamma"
      ],
      "modelFamily": "Perplexity",
      "market": "US",
      "language": "en",
      "mentioned": true,
      "position": 1
    }
  ],
  "maximumSegmentsPerDimension": 10
}' |
apify call zinin/ai-visibility-competitor-share-of-voice --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zinin/ai-visibility-competitor-share-of-voice"
        }
    }
}

```

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/JcFP4albwZvb6EMlw/builds/UrsPo3ieyedvy4awC/openapi.json
