# Ad Creative Pattern Analyzer: Ranked Patterns From Ad Data (`delta_tools/ad-creative-pattern-analyzer`) Actor

Turn any scraped ad dataset into ranked creative patterns with hook, angle and format counts, longevity from start dates, and example ads. Works on Facebook Ads Library scraper output. Includes image and text ads.

- **URL**: https://apify.com/delta_tools/ad-creative-pattern-analyzer.md
- **Developed by:** [Delta Tools](https://apify.com/delta_tools) (community)
- **Categories:** Business, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 ads

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Ad Creative Pattern Analyzer

Your ad scraper hands you thousands of rows. This Actor hands you the patterns inside them.

Point it at any scraped ad dataset, for example the output of a Facebook Ads Library scraper, or paste ad records directly. It reads every ad up to your max ads setting and returns the creative patterns that repeat across the set, ranked and counted, with longevity and real examples.

### What you get

**One summary record** with the totals: ads analyzed, advertisers found, patterns found, the single top pattern, top hook, top angle and top format, plus median and longest run times from the ad start dates in your data.

**One record per pattern.** A pattern is one persuasion angle combined with one hook style and one creative format, for example a price angle with an offer led hook in image format. Each pattern record carries its ad count, its share of the set, how many advertisers use it, its average and longest run time, a plain longevity label and up to three example ads taken from your own data.

**Breakdown records** for hooks, angles, formats, calls to action and link domains, so you can rank each dimension on its own. Hook styles include question hooks, number led hooks, offer led hooks, pain point hooks, curiosity hooks and social proof hooks. Angles include price and savings, social proof and trust, pain relief, transformation and results, ease and convenience, quality and craft, urgency and scarcity, education and discovery, comparison and new and novelty. Outputs can also carry a Transformation hook, a Direct callout hook, a Story opening hook, an Urgency hook, a Benefit statement hook or a No text hook label, and an angle can come back as General benefit pitch when no angle keywords match.

**One record per advertiser** with its ad count, share, favorite angle, hook and format and run time stats. Longevity matters because an ad that has been running for three months is usually an ad that works, and this Actor surfaces exactly those.

### Why it is different

Per ad teardown tools on the Store fetch one video ad at a time, charge far more per ad and skip image and text ads entirely. Scrapers only collect ads. None of them accepts an arbitrary ad dataset you already scraped and returns aggregate ranked patterns with counts, share, longevity and examples. This Actor is the downstream step the big ad scrapers leave undone.

### How the analysis works

The classification is deterministic and local. A transparent word and phrase lexicon reads the ad copy, the opening hook is classified from the first sentence, the angle is scored across the full copy including the headline and description, and the format is read from the media fields of each record, including nested snapshot objects from Meta style scrapers. Longevity is counted in days from each ad start date to its end date, or to the latest date present in your dataset when an ad is still running. The same input always produces the same output, and no ad data ever leaves the run for an outside AI service.

### Input

**Dataset ID with ads.** The output dataset of any ad library scraper. Or use **Inline ads** and paste a JSON array of ad records.

**Your Apify API token.** Only for dataset ID input. Apify runs cannot always read a dataset on their own: on accounts with restricted storage access the platform refuses the run, and your own token is the key that opens your dataset. It is a secret input, used once to read that one dataset and never written to the output. Inline ads never need it.

**Max ads to analyze.** The cap is also a spend cap, because you are charged only for ads actually analyzed.

### Pricing

Pay per event: $0.001 Actor start plus $0.002 per ad analyzed. Records with no usable creative content are skipped and never charged, and an empty or failed input charges no ad events at all. Analyzing 500 ads costs about one dollar, against five cents per ad for a single video teardown elsewhere. Actor start events are charged once per GB of memory, and higher Apify plan tiers pay less per event.

### Notes and limitations

Classification is lexicon based, so it is fast and repeatable, but it will not catch sarcasm or angles expressed in highly unusual wording. Records in the Meta Ads Library shape work best, flat or nested. Longevity is only as good as the dates your scraper captured: ads without a start date are analyzed for patterns and counted everywhere except the run time stats. Examples are shortened to 240 characters.

# Actor input Schema

## `datasetId` (type: `string`):

The Apify dataset that holds the ads, for example the output dataset of a Facebook Ads Library scraper. Paste its dataset ID. Leave empty when you paste ads below instead.

## `inlineAds` (type: `array`):

Ad records pasted directly as a JSON array. Each item is an object in the shape your ad scraper produced, flat or with a nested snapshot object. The sample below analyzes in seconds and shows the full output shape.

## `apifyApiToken` (type: `string`):

Your own Apify API token, needed only when you use a dataset ID and your account restricts storage access (the run then cannot read the dataset on its own). The token is a secret input, is used once to read that one dataset from api.apify.com, and is never stored in the output. Leave empty when you paste ads inline.

## `maxAds` (type: `integer`):

Maximum number of ads to analyze in one run. You are charged only for ads actually analyzed, so a cap is also a spend cap.

## Actor input object example

```json
{
  "inlineAds": [
    {
      "pageName": "Alpha Skin",
      "adText": "Tired of dull, tired skin? Our serum fixes the problem in minutes.",
      "startDate": "2026-09-01",
      "videos": [
        {
          "url": "https://example.com/v.mp4"
        }
      ],
      "ctaText": "Shop Now",
      "linkUrl": "https://alphaskin.example/shop"
    },
    {
      "pageName": "Alpha Skin",
      "adText": "Save 40 percent this week. Premium quality serum, now on sale with free shipping.",
      "startDate": "2026-06-01",
      "images": [
        "https://example.com/a.jpg"
      ],
      "ctaText": "Shop Now",
      "linkUrl": "https://alphaskin.example/sale"
    },
    {
      "pageName": "Beta Gear",
      "adText": "5 reasons ten thousand runners switched. Loved by customers everywhere, rated five stars.",
      "startDate": "2026-08-15",
      "endDate": "2026-10-01",
      "images": [
        "https://example.com/b.jpg"
      ]
    },
    {
      "pageName": "Beta Gear",
      "adText": "Introducing the brand new trail shoe. Our newest design is now available.",
      "startDate": "2026-09-20",
      "cards": [
        {
          "image": 1
        },
        {
          "image": 2
        },
        {
          "image": 3
        }
      ]
    },
    {
      "pageName": "Gamma Learn",
      "adText": "How it works: learn the system step by step in this free guide and discover more.",
      "startDate": "2026-09-10"
    }
  ],
  "maxAds": 5000
}
```

# Actor output Schema

## `recordType` (type: `string`):

The exact record kind: summary, pattern, breakdown, advertiser, or error.

## `error` (type: `string`):

Present only on an error record, which carries no ad analyzed charge.

## `adsAnalyzed` (type: `string`):

Ads actually analyzed and charged, on the summary record.

## `adsSkipped` (type: `string`):

Records skipped because they carried no usable creative content. No ad analyzed charge applies to skipped records.

## `advertisers` (type: `string`):

Distinct advertisers found, on the summary record.

## `patternsFound` (type: `string`):

Creative patterns found, on the summary record.

## `topPattern` (type: `string`):

Largest pattern overall, on the summary record.

## `topHook` (type: `string`):

Most used hook in the set on the summary record, and most used hook for the named advertiser on an advertiser record.

## `topAngle` (type: `string`):

Most used angle in the set on the summary record, and most used angle for the named advertiser on an advertiser record.

## `topFormat` (type: `string`):

Most used format in the set on the summary record, and most used format for the named advertiser on an advertiser record.

## `medianDaysActive` (type: `string`):

Median run time in days across dated ads, on the summary record.

## `adsWithDates` (type: `string`):

Ads that carried a usable start date, on the summary record.

## `earliestStart` (type: `string`):

Earliest ad start date in the set, on the summary record.

## `latestDate` (type: `string`):

Latest date present in the set, used as the reference date for ads still running, on the summary record.

## `source` (type: `string`):

Where the ads came from in this run: dataset, inline, or dataset+inline for both.

## `pattern` (type: `string`):

The combined angle, hook and format pattern, on a pattern record.

## `angle` (type: `string`):

Persuasion angle, on a pattern record.

## `hook` (type: `string`):

Hook style, classified from the first sentence of the ad copy.

## `format` (type: `string`):

Creative format: Video, Image, Carousel, or Text.

## `dimension` (type: `string`):

Breakdown dimension: hook, angle, format, cta, or domain, on a breakdown record.

## `value` (type: `string`):

The value counted by this breakdown record.

## `advertiser` (type: `string`):

Advertiser or page name, on an advertiser record.

## `topAdvertiser` (type: `string`):

Advertiser with the most ads inside this pattern.

## `adCount` (type: `string`):

Ads counted in this record.

## `sharePercent` (type: `string`):

Share of analyzed ads counted in this record, in percent.

## `advertiserCount` (type: `string`):

Distinct advertisers using this pattern or value.

## `averageDaysActive` (type: `string`):

Average run time in days for dated ads in this record.

## `maxDaysActive` (type: `string`):

Longest run time in days for dated ads in this record.

## `longevity` (type: `string`):

Plain label for the average run time of this record.

## `example1` (type: `string`):

First example ad for this record, taken from the input data.

## `example2` (type: `string`):

Second example ad for this record.

## `example3` (type: `string`):

Third example ad for this record.

## `runAt` (type: `string`):

UTC timestamp of the run.

# 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 = {
    "inlineAds": [
        {
            "pageName": "Alpha Skin",
            "adText": "Tired of dull, tired skin? Our serum fixes the problem in minutes.",
            "startDate": "2026-09-01",
            "videos": [
                {
                    "url": "https://example.com/v.mp4"
                }
            ],
            "ctaText": "Shop Now",
            "linkUrl": "https://alphaskin.example/shop"
        },
        {
            "pageName": "Alpha Skin",
            "adText": "Save 40 percent this week. Premium quality serum, now on sale with free shipping.",
            "startDate": "2026-06-01",
            "images": [
                "https://example.com/a.jpg"
            ],
            "ctaText": "Shop Now",
            "linkUrl": "https://alphaskin.example/sale"
        },
        {
            "pageName": "Beta Gear",
            "adText": "5 reasons ten thousand runners switched. Loved by customers everywhere, rated five stars.",
            "startDate": "2026-08-15",
            "endDate": "2026-10-01",
            "images": [
                "https://example.com/b.jpg"
            ]
        },
        {
            "pageName": "Beta Gear",
            "adText": "Introducing the brand new trail shoe. Our newest design is now available.",
            "startDate": "2026-09-20",
            "cards": [
                {
                    "image": 1
                },
                {
                    "image": 2
                },
                {
                    "image": 3
                }
            ]
        },
        {
            "pageName": "Gamma Learn",
            "adText": "How it works: learn the system step by step in this free guide and discover more.",
            "startDate": "2026-09-10"
        }
    ],
    "maxAds": 5000
};

// Run the Actor and wait for it to finish
const run = await client.actor("delta_tools/ad-creative-pattern-analyzer").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 = {
    "inlineAds": [
        {
            "pageName": "Alpha Skin",
            "adText": "Tired of dull, tired skin? Our serum fixes the problem in minutes.",
            "startDate": "2026-09-01",
            "videos": [{ "url": "https://example.com/v.mp4" }],
            "ctaText": "Shop Now",
            "linkUrl": "https://alphaskin.example/shop",
        },
        {
            "pageName": "Alpha Skin",
            "adText": "Save 40 percent this week. Premium quality serum, now on sale with free shipping.",
            "startDate": "2026-06-01",
            "images": ["https://example.com/a.jpg"],
            "ctaText": "Shop Now",
            "linkUrl": "https://alphaskin.example/sale",
        },
        {
            "pageName": "Beta Gear",
            "adText": "5 reasons ten thousand runners switched. Loved by customers everywhere, rated five stars.",
            "startDate": "2026-08-15",
            "endDate": "2026-10-01",
            "images": ["https://example.com/b.jpg"],
        },
        {
            "pageName": "Beta Gear",
            "adText": "Introducing the brand new trail shoe. Our newest design is now available.",
            "startDate": "2026-09-20",
            "cards": [
                { "image": 1 },
                { "image": 2 },
                { "image": 3 },
            ],
        },
        {
            "pageName": "Gamma Learn",
            "adText": "How it works: learn the system step by step in this free guide and discover more.",
            "startDate": "2026-09-10",
        },
    ],
    "maxAds": 5000,
}

# Run the Actor and wait for it to finish
run = client.actor("delta_tools/ad-creative-pattern-analyzer").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 '{
  "inlineAds": [
    {
      "pageName": "Alpha Skin",
      "adText": "Tired of dull, tired skin? Our serum fixes the problem in minutes.",
      "startDate": "2026-09-01",
      "videos": [
        {
          "url": "https://example.com/v.mp4"
        }
      ],
      "ctaText": "Shop Now",
      "linkUrl": "https://alphaskin.example/shop"
    },
    {
      "pageName": "Alpha Skin",
      "adText": "Save 40 percent this week. Premium quality serum, now on sale with free shipping.",
      "startDate": "2026-06-01",
      "images": [
        "https://example.com/a.jpg"
      ],
      "ctaText": "Shop Now",
      "linkUrl": "https://alphaskin.example/sale"
    },
    {
      "pageName": "Beta Gear",
      "adText": "5 reasons ten thousand runners switched. Loved by customers everywhere, rated five stars.",
      "startDate": "2026-08-15",
      "endDate": "2026-10-01",
      "images": [
        "https://example.com/b.jpg"
      ]
    },
    {
      "pageName": "Beta Gear",
      "adText": "Introducing the brand new trail shoe. Our newest design is now available.",
      "startDate": "2026-09-20",
      "cards": [
        {
          "image": 1
        },
        {
          "image": 2
        },
        {
          "image": 3
        }
      ]
    },
    {
      "pageName": "Gamma Learn",
      "adText": "How it works: learn the system step by step in this free guide and discover more.",
      "startDate": "2026-09-10"
    }
  ],
  "maxAds": 5000
}' |
apify call delta_tools/ad-creative-pattern-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,delta_tools/ad-creative-pattern-analyzer"
        }
    }
}
```

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/cxtHkrVTDZBLOJtcp/builds/ShoGzEueKgwmFDgpZ/openapi.json
