# Earned Media Value - What Was That Campaign Worth? (`reapx/campaign-emv-calculator`) Actor

What that campaign was actually worth. Earned media value per post, what you really paid per real engagement, and which posts carried the whole thing.

- **URL**: https://apify.com/reapx/campaign-emv-calculator.md
- **Developed by:** [Tarek Etman](https://apify.com/reapx) (community)
- **Categories:** Business, Marketing, For creators
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $70.00 / 1,000 emv calculation results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

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

## How to integrate an Actor?

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

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

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

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

# README

![reapX - the record of what changed](https://reapx.dev/reapx.gif)

## Earned Media Value Calculator - Campaign EMV & ROI

> "We spent 60,000 dollars. My VP asked what we got back. I have screenshots."

Screenshots are not evidence and likes are vanity metrics. Every tool hands you raw row counts and leaves you to build the ROI deck yourself, while agency clients and leadership demand defensible numbers.

Calculate Earned Media Value (EMV), reach proxy, cost per real engagement (CPE), and FTC disclosure status in one pass, with the exact rate card and evidence bundle attached.

Maintained by reapx. Permanent entity records, run citations, and reproducible datasets.

***

### ⬇️ Input

Configure campaign post URLs, creator handles, campaign fee/budget, and optional custom rate cards.

| Field | Type | Required | Description |
|---|---|---|---|
| `campaignKey` | String | No | Primary campaign name or hashtag to group results under (e.g. `nike_summer_2026`). |
| `postUrls` | Array | No | Array of post URLs across Instagram, TikTok, YouTube, or LinkedIn to evaluate. |
| `creatorHandles` | Array | No | Array of creator handles to evaluate for campaign performance. |
| `campaignSpendUsd` | Number | No | Total campaign fee or budget in USD to calculate cost per real engagement (CPE). |
| `platform` | String | No | Target platform filter (`auto`, `instagram`, `tiktok`, `youtube`, `linkedin`). Default: `auto`. |
| `customRateCard` | Object | No | Custom JSON rate card overriding standard benchmark rates for likes, comments, shares, and CPM. |
| `maxItems` | Integer | No | Maximum number of items to calculate in one run. Default: `100`. |

***

### ⬆️ Output

Every returned row contains the computed financial verdict, metric breakdown, FTC compliance status, and the exact rate card applied.

#### Dataset Schema Fields

| Field Name | Type | Description |
|---|---|---|
| `itemKey` | String | Stable per-row identifier (e.g. post shortcode or campaign post key). |
| `campaignKey` | String | Campaign identifier or hashtag. |
| `platform` | String | Social platform (instagram, tiktok, youtube, linkedin). |
| `postUrl` | String | Direct canonical URL of the post or video. |
| `creatorHandle` | String | Creator username or channel handle. |
| `creatorFollowers` | Integer | Observed follower or subscriber count. |
| `likes` | Integer | Observed like count. |
| `comments` | Integer | Observed comment count. |
| `views` | Integer | Observed video view count. |
| `shares` | Integer | Observed or estimated share count. |
| `saves` | Integer | Observed or estimated save/bookmark count. |
| `totalEngagements` | Integer | Total sum of all engagement actions. |
| `reachProxy` | Integer | Estimated reach and impression proxy `(followers * 0.08) + (engagements * 3.5)`. |
| `earnedMediaValue` | Number | Computed Earned Media Value (EMV) in USD. |
| `costPerRealEngagement` | Number | Cost per real engagement (CPE) in USD when campaign spend is supplied. |
| `disclosureStatus` | String | FTC disclosure compliance status (`COMPLIANT`, `NON_COMPLIANT`, `SUSPECTED_UNDISCLOSED`, `ORGANIC`). |
| `disclosureEvidence` | String | Detailed reasoning and token evidence for FTC compliance verdict. |
| `rateCardUsed` | String | JSON string of the rate card values applied for the calculation. |
| `evidenceBundle` | String | Decomposed metric inputs and observation window details. |
| `scrapedAt` | String | ISO timestamp when the calculation was generated. |

***

### How it works

1. **Input Normalization & Capture:** The engine parses post URLs or creator handles, resolving platform endpoints over unauthenticated HTTP/embed routes with $0 proxy overhead.
2. **Engagement & Impression Estimation:** Extracted engagement metrics (likes, comments, views) combine with follower counts to estimate reach proxy and organic impression volume using industry-standard Ayzenberg & Upfluence models.
3. **Earned Media Value (EMV) Computation:** Each engagement action multiplies against platform-specific Ad Equivalent Value (AEV) rate cards (e.g. Instagram likes at $0.25, comments at $1.50, Reel views at $0.03, plus CPM adjustments).
4. **FTC Disclosure Auditing:** Captions pass through an automated 16 CFR Part 255 heuristic engine checking for `#ad`, `paid partnership`, and paid endorsement disclosure position relative to the 125-character caption truncation fold.
5. **Data Delivery:** Computed rows push directly to your dataset with the complete evidence bundle attached.

***

### ❓ FAQ

#### What is Earned Media Value (EMV)?

Earned Media Value (EMV) quantifies the financial worth of social media content by computing the equivalent cost of purchasing that exact reach and engagement via paid advertising.

#### Are custom rate cards supported?

Yes. You can supply a `customRateCard` JSON object in the input to substitute your agency's or client's specific ad equivalent rates per platform and action.

#### Is an Instagram or TikTok login required?

No. The calculator reads publicly accessible metrics and embed endpoints without requesting your credentials, cookies, or account access.

#### Does this evaluate FTC compliance?

Yes. Post captions are checked against FTC 16 CFR Part 255 guidelines to flag missing disclosures, buried tags below the truncation fold, or vague non-compliant keywords.

***

### 💬 Your feedback

Need custom industry rate cards, multi-platform campaign unioning, or API integration support? Contact the maintenance team at reapxdev@proton.me.

Unofficial - not affiliated with Instagram, TikTok, YouTube, or LinkedIn. Collects accessible data only. reapx.

# Actor input Schema

## `campaignKey` (type: `string`):

Primary campaign identifier, hashtag, or campaign name to group results under. Leave empty to use default campaign key.

## `postUrls` (type: `array`):

Array of social media post URLs (Instagram, TikTok, YouTube, LinkedIn) to evaluate for EMV and FTC compliance.

## `creatorHandles` (type: `array`):

Array of creator handles to evaluate recent posts for campaign Earned Media Value (EMV).

## `campaignSpendUsd` (type: `number`):

Total campaign fee or budget in USD to calculate cost per real engagement (CPE) and ROI metrics. Leave empty if unpriced.

## `platform` (type: `string`):

Target social media platform filter.

## `customRateCard` (type: `object`):

Optional JSON object overriding standard benchmark rates for like, comment, share, save, video view, and CPM.

## `maxItems` (type: `integer`):

Maximum number of posts or creator records to evaluate in one run. Higher numbers increase run duration and memory consumption.

## `metrics` (type: `array`):

The engagement figures you already have, one entry per creator or post - <code>{"handle":"gymshark","followers":8600000,"likes":4500,"comments":120,"views":0}</code>. Your platform analytics or the creator's own screenshot has them. <b>Consequence:</b> everything is valued off these exact figures and the rate card is shown on the row. <b>Empty meaning:</b> the run comes back saying which numbers it still needs, and is not charged for those rows.

## Actor input object example

```json
{
  "campaignKey": "nike_summer_2026",
  "platform": "auto",
  "maxItems": 100,
  "metrics": []
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "campaignKey": "nike_summer_2026",
    "metrics": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/campaign-emv-calculator").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 = {
    "campaignKey": "nike_summer_2026",
    "metrics": [],
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/campaign-emv-calculator").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 '{
  "campaignKey": "nike_summer_2026",
  "metrics": []
}' |
apify call reapx/campaign-emv-calculator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reapx/campaign-emv-calculator"
        }
    }
}

```

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/PHhSY88DBmS2Y0sHi/builds/7p1Z1UdcUQa1ocPZe/openapi.json
