# Video Ad Analyzer: Facebook & TikTok Ad Transcripts & Hooks (`deapi/video-ad-analyzer`) Actor

Analyse video ads from Facebook Ads Library, Meta Ad Library and TikTok Ads scrapers, or direct video links: timed transcript, on-screen timeline, 3-second hook, spoken CTAs, brand mentions and pacing per ad creative. From $0.02 per ad.

- **URL**: https://apify.com/deapi/video-ad-analyzer.md
- **Developed by:** [deAPI](https://apify.com/deapi) (community)
- **Categories:** AI, Marketing, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.84 / 1,000 analysed ad videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Video Ad Analyzer: Facebook & TikTok Ad Transcripts & Hooks

**Video ad analyzer** for competitor research: turn the video ads you scraped from the **Facebook Ads Library**, Meta Ad Library, TikTok Ads Library or any ad-library scraper into structured data — the full **transcript with word timing**, a **timed timeline of what is on screen**, the **3-second hook**, spoken **calls to action** and **brand mentions**, and the ad's pacing. One row per ad creative, ready for a spreadsheet, a dashboard, or ChatGPT and Claude.

**deAPI AI tools**

- Transcribing any audio or video file? → [Audio & Video Transcription: MP3, MP4 & Podcast to Text](https://apify.com/deapi/audio-video-to-text)
- Analysing TikTok, YouTube or X videos by link? → [AI Video Analyzer](https://apify.com/deapi/tiktok-video-scene-analyzer)

### What does Video Ad Analyzer do?

Ad-library scrapers give you thousands of ads with a link to each video — but not what the video says or shows. This Actor takes those video files, listens to them and watches them, and returns what a creative strategist would note down for every ad:

- **What is said** — the full transcript, with the time of every sentence and every word, and the language.
- **What is shown** — a timeline of on-screen moments, one to a few seconds each: people, products, actions, settings, and the text and brand names it can read.
- **The hook** — what is said and shown in the first 3 seconds, and how long until the first word.
- **Calls to action** — when "shop now", "use code", "link in bio", "download" and the ad's own CTA button text are spoken.
- **Brand mentions** — how often and how early the advertiser's name is said and shown.
- **Pacing** — words per minute, the share of the ad with someone talking, on-screen moments per 10 seconds, length and aspect ratio.

Each row also keeps the ad's own data from the scraper — **ad ID, advertiser, CTA button, landing page, ad text, start date and platforms** — so you can sort, filter and compare creatives in one table.

### Why use it?

- **Works on the ads you already scraped** — give it the dataset of [Facebook Ads Library Scraper](https://apify.com/apify/facebook-ads-scraper) or another ad-library scraper; it finds every video and its ad data.
- **One analysis per creative** — ad libraries list the same creative in 9:16 and 1:1. Versions of the same length but another shape are analysed once (the vertical cut), and the copies are free.
- **Timed, not just transcribed** — every word and every on-screen moment has a timestamp, so "what happens in the first 3 seconds" is a field, not a guess.
- **Reads the screen** — the HD video is analysed, so product names, prices and title cards are picked up. **Detailed** reading catches small text and logos.
- **Silent ads too** — music-only and text-on-screen ads get the full on-screen timeline, and videos without a soundtrack skip the transcript fee.
- **Priced per ad** — about **$0.02 per ad**: $0.021 for a 30-second ad. Failed and skipped videos are free.

### What data can you get?

| Data | Fields |
|---|---|
| 🏷️ **Ad** | `adId`, `advertiser`, `ctaText`, `linkUrl`, `adText`, `startDate`, `platforms` (from the scraper), `videoUrl`, `videoNumber`, `videosInAd` |
| 🎞️ **Video** | `durationSeconds`, `width`, `height`, `aspectRatio` (9:16, 1:1, 4:5, 16:9…), `hasAudio` |
| 🗣️ **Transcript** | `transcript`, `language`, `segments` (sentences with start and end), `words` (every word with start and end), `hasSpeech` |
| 👁️ **On screen** | `onScreenEvents` (start, end, description), `sceneSummaries` (longer descriptions of each part) |
| 🪝 **Hook** | `hook.speech` and `hook.onScreen` for the first 3 seconds, `timeToFirstWordSeconds` |
| 📣 **CTA & brand** | `ctaMentions` (phrase and the seconds it is said), `brandMentions` (spoken and on-screen counts, first times) |
| ⏱️ **Pacing** | `wordsPerMinute`, `speechCoveragePct`, `onScreenEventCount`, `onScreenEventsPer10s` |
| 💵 **Billing** | `billedVideos`, `billedTranscripts`, `billed10sUnits`, `billedDetailUnits`, `billedConversionUnits` |

### How to analyse video ads

1. **Scrape the ads.** Run an ad-library scraper — for example [Facebook Ads Library Scraper](https://apify.com/apify/facebook-ads-scraper) with an Ad Library search or page URL filtered to *Media type: Videos*.
2. **Give this Actor the scraper's dataset.** Pick it in **Dataset of ads**, or paste its ID. To do it automatically, connect this Actor as an **integration** of the scraper (see the tutorial below).
3. Click **Start**. To see what you get first, run it with the prefilled example — a public-domain U.S. Army TV ad — then swap in your scraper's dataset. Each ad video becomes a row; open the **Ad videos**, **Transcripts** or **On-screen timeline** views, or export everything as JSON, CSV or Excel.

**Run it soon after the scraper.** Ad-library video links are signed and expire after a few days (about four for Meta's). An expired link is a free `failed` row.

You can also paste **direct video links** in **Video URLs** — any public MP4, MOV, WebM, MKV, AVI or MPEG file.

#### Which scrapers work

Any scraper whose results contain links to the video files. The Facebook Ads Library Scraper layout is tested end to end on real ads; the others are recognised by their field names:

| Scraper | Videos found in | Ad data kept |
|---|---|---|
| Facebook Ads Library Scraper (apify) | `snapshot.videos[]`, `snapshot.cards[]` (`videoHdUrl`, `videoSdUrl`) | ad ID, page name, CTA, link, body text, dates, platforms |
| Meta Ad Library scrapers (snake_case) | `video_hd_url`, `video_sd_url`, `videos[]` | `ad_archive_id`, `page_name`, `cta_text`, `link_url`… |
| TikTok Ads Library scrapers | `videoUrl`, `video_url`, `videos[]` | `adId`, `advertiserName`… |

The HD copy is used when there is one (it lets the analysis read the screen), and the SD copy if the HD link fails. Image and text ads get a free `skipped` row, so every ad in the dataset is accounted for.

#### Limits

| | |
|---|---|
| **Video length** | up to 5 minutes (free plan: up to 60 seconds) |
| **File size** | up to 150 MB (free plan: 50 MB) |
| **Large files** | files over 48 MB are converted first, which takes several minutes; 1080p ads of up to about 4 minutes and 4K ads of up to about 1 minute are taken (with a conversion fee from November 11, 2026), heavier files are refused at once and not charged |
| **Formats** | MP4, MOV, WebM, MKV, AVI, MPEG |
| **Ads per run** | up to 1,000 ads with video (`maxAds`, default 50), up to 10 videos per ad |
| **Languages** | many languages, detected per video, or set `language` |

### Input

| Field | Values | Notes |
|---|---|---|
| `datasetId` | dataset ID or link | The dataset of an ad-library scraper run. |
| `videoUrls` | list of links | Direct links to video files. |
| `preset` | `balanced` (Standard) · `detail` (Detailed) | On-screen reading. Detailed reads small text and logos, for a surcharge. Default `balanced`. |
| `language` | `en`, `es`, `de`… | Two- or three-letter code of the spoken language. Empty = detect per video. |
| `analyzeAllVariants` | `true` · `false` | Analyse every version of a creative instead of one. Default `false`. |
| `maxAds` | 1–1,000 | Video ads taken from the dataset. Default 50. |
| `maxConcurrency` | 1–5 | Ads at the same time. Default 3. No effect on price. |

```json
{
    "datasetId": "YOUR_SCRAPER_DATASET_ID",
    "preset": "balanced",
    "maxAds": 50
}
```

### Output

A real row, for a public-domain U.S. Army TV ad from 2012 (lists shortened):

```json
{
    "source": "link",
    "videoUrl": "https://upload.wikimedia.org/wikipedia/commons/4/4b/Army_Strong_TV_ad%2C_2012.webm",
    "durationSeconds": 30.15,
    "width": 640,
    "height": 360,
    "aspectRatio": "16:9",
    "status": "success",
    "hasSpeech": true,
    "language": "en",
    "transcript": "It's back up. This is a breakthrough. It's a magnet. It's a game changer. It's relief. It's a role model. It's progress. It's more than a uniform. It's a chance to change the future. There's strong, and then there's Army strong. Try it on at GoArmy.com.",
    "words": [{"word": "It's", "start": 1.771, "end": 2.111}, {"word": "back", "start": 2.272, "end": 2.492}, "…"],
    "onScreenEvents": [
        {"start": 0.0, "end": 2.0, "description": "A soldier in camouflage fatigues adjusts his gear."},
        {"start": 2.0, "end": 3.5, "description": "A soldier runs across a dusty outdoor field."},
        {"start": 3.5, "end": 5.5, "description": "A soldier raises his hand in a salute."},
        {"start": 5.5, "end": 7.5, "description": "A soldier smiles while looking down."},
        "…"
    ],
    "hook": {
        "seconds": 3.0,
        "speech": "It's back This is a breakthrough.",
        "onScreen": ["A soldier in camouflage fatigues adjusts his gear.", "A soldier runs across a dusty outdoor field."]
    },
    "timeToFirstWordSeconds": 1.66,
    "wordsPerMinute": 91.5,
    "speechCoveragePct": 35.4,
    "onScreenEventCount": 14,
    "onScreenEventsPer10s": 4.64,
    "ctaMentions": [{"phrase": "try it", "atSeconds": [27.06]}],
    "brandMentions": null,
    "billedVideos": 1,
    "billedTranscripts": 1,
    "billed10sUnits": 3,
    "billedDetailUnits": 0,
    "billedConversionUnits": 0,
    "error": null
}
```

The hook follows the word timings: words that start inside the first 3 seconds, in spoken order.

A row from an ad-library dataset also carries the ad's data — for example `"adId": "2055369298426424"`, `"advertiser": "Sephora"`, `"ctaText": "Shop now"`, `"linkUrl"`, `"adText"`, `"platforms": ["FACEBOOK", "INSTAGRAM"]` — and `brandMentions` — for a 34-second Sephora ad from the Ad Library, `{"name": "Sephora", "spokenCount": 4, "firstSpokenAtSeconds": 5.84, "onScreenCount": 3, "firstOnScreenAtSeconds": 3.5}`.

Videos that could not be analysed have `status: "failed"` and an `error`. Copies of a creative, repeated videos, ads without a video, and videos left out by a run cost limit or the free plan have `status: "skipped"`. Neither is charged.

### How much does it cost?

**$0.00684 per analysed video + $0.01032 for its transcript + $0.00134 per started 10 seconds of video.** Videos without a soundtrack have no transcript and skip that fee. **Detailed** on-screen reading adds **$0.00043 per 10 seconds**.

| Ad length | Standard | Detailed | No soundtrack |
|---|---|---|---|
| up to 15 s | **$0.0198** | $0.0207 | $0.0095 |
| up to 30 s | **$0.0212** | $0.0225 | $0.0109 |
| up to 60 s | **$0.0252** | $0.0278 | $0.0149 |
| up to 2 min | **$0.0332** | $0.0384 | $0.0229 |
| 100 ads of 30 s | **$2.12** | $2.25 | $1.09 |

Length is counted in started 10-second blocks, with half a second of slack: a 30.3-second ad bills as 30 s, a 31-second ad as 40 s.

**Large files (from November 11, 2026):** a file over 48 MB has to be converted before it can be analysed, which takes several minutes of processing. Such a file adds **$0.0025 per started 10 seconds at 1080p and 30 fps** — 4K counts four times, 720p less than half, 60 fps twice. A 3-minute 1080p file at 25 fps adds $0.0375, a 1-minute 4K file $0.06. Files up to 48 MB, which covers almost every ad from an ad library, never pay it; the units are in `billedConversionUnits`.

The price covers the analysis. Ads collected with an ad-library scraper also cost whatever that scraper charges for its own run. Video files you link directly — your own ads, files on your server or cloud storage — need no scraper, so the price above is all you pay.

Failed videos — expired links, files that are not a video, videos over 5 minutes — are **never charged**, and neither are skipped copies of a creative, ads without a video, or videos left out by a run cost limit or the free plan. A soundtrack with music only costs the same as one with speech.

Set **maximum cost per run** to cap your spend: the Actor checks each video's price before it starts and stops at the first one the remaining budget cannot cover; that video and the rest get a free `skipped` row.

**Free plan:** 5 ad videos per calendar month (resets at 00:00 UTC on the 1st), each up to 60 seconds and 50 MB, within a daily capacity shared by all free users. Any paid Apify plan removes the free-plan limits.

### Use cases

- **Competitor ad research** — see what your competitors say in their first 3 seconds, how fast they talk, and when they ask for the click.
- **Creative strategy** — compare hooks, CTAs and pacing across hundreds of ads in one table; sort by `timeToFirstWordSeconds` or `onScreenEventsPer10s`.
- **Swipe files** — keep every competitor ad's script and shot timeline, searchable.
- **AI briefs** — give the rows to ChatGPT or Claude and ask for angles, offers and new hook ideas grounded in what is really in the ads.
- **Brand and compliance checks** — find where a brand name, a price or a claim is said or shown.

### Tutorial: analyse a competitor's video ads

#### 1. In the Console

Run [Facebook Ads Library Scraper](https://apify.com/apify/facebook-ads-scraper) on a brand's Ad Library page URL filtered to *Media type: Videos*. Open this Actor, pick that run's dataset in **Dataset of ads** and click **Start**. Each video ad becomes a row in the **Ad videos** view.

#### 2. Automatically after every scrape

In the scraper's **Integrations** tab, add **Run Actor**, choose this Actor, and set its input to `{"datasetId": "{{resource.defaultDatasetId}}"}`. Every scrape is then analysed while its video links are fresh.

#### 3. From Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
ads = client.actor("apify/facebook-ads-scraper").call(run_input={
    "startUrls": [{"url": "https://www.facebook.com/ads/library/?active_status=active&ad_type=all&country=US&media_type=video&q=skincare&search_type=keyword_unordered"}],
    "resultsLimit": 20,
})
run = client.actor("deapi/video-ad-analyzer").call(run_input={"datasetId": ads["defaultDatasetId"]})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["status"] == "success":
        print(row.get("advertiser"), row["durationSeconds"], row["hook"]["speech"])
```

#### 4. From JavaScript or cURL

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('deapi/video-ad-analyzer').call({
    videoUrls: ['https://upload.wikimedia.org/wikipedia/commons/4/4b/Army_Strong_TV_ad%2C_2012.webm'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].hook, items[0].onScreenEvents.length);
```

```bash
curl -X POST "https://api.apify.com/v2/acts/deapi~video-ad-analyzer/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"videoUrls": ["https://upload.wikimedia.org/wikipedia/commons/4/4b/Army_Strong_TV_ad%2C_2012.webm"]}'
```

### FAQ

#### How do I analyse Facebook ads?

Scrape them with a Facebook Ads Library scraper, then give its dataset to this Actor. It downloads each ad's video, transcribes it, describes what is on screen and measures the hook, and keeps the ad's ID, page, CTA and text next to the results. It does not search the Ad Library itself.

#### How much does it cost to analyse a Facebook ad?

About $0.021 for a 30-second video ad and $0.025 for a 60-second one; $0.0185 for the shortest. See the price table above; failed and skipped videos are free.

#### Can I get the transcript of a Facebook or Instagram ad?

Yes — every analysed ad has its full transcript with word timing in `transcript` and `words`. Meta ads run on Facebook and Instagram with the same video, so one analysis covers both.

#### Can I transcribe Facebook ads in bulk?

Yes. One run takes up to 1,000 video ads from a scraper's dataset, several at a time, and the results export as one CSV, Excel or JSON file.

#### Do I need an ad-library scraper?

No. Paste direct links to video files in **Video URLs** — your own ads before a campaign, files on your server or cloud storage, or any public video file — and the Actor analyses them as they are. It is also the cheapest way: you pay only the analysis. A scraper is needed only to collect other advertisers' ads from an ad library, which shows no direct video links; it bills its own runs separately.

#### Does it work with TikTok ads?

Yes, with a TikTok Ads Library scraper whose results include the video file link. For organic TikTok, YouTube or X videos by their page link, use [AI Video Analyzer](https://apify.com/deapi/tiktok-video-scene-analyzer).

#### Does it work with YouTube or Google Ads Transparency ads?

Only when the scraper returns direct video files. Ads given as YouTube links cannot be downloaded here — analyse those with [AI Video Analyzer](https://apify.com/deapi/tiktok-video-scene-analyzer), which takes YouTube links.

#### What is the hook of an ad?

The first seconds that decide whether someone keeps watching. The Actor records what is said in the first 3 seconds (`hook.speech`), what is shown (`hook.onScreen`) and when the first word comes (`timeToFirstWordSeconds`).

#### Does it read text on screen?

It describes what is on screen and reads larger text — title cards, product names, prices — in the standard mode. **Detailed** reading looks at the picture at a higher resolution and catches small text, labels and logos. Text is reported inside the on-screen descriptions, not as a separate subtitle file.

#### Does it work on ads without speech?

Yes. Music-only and text-on-screen ads get the full on-screen timeline; `hasSpeech` is `false` and the transcript is empty. Videos with no soundtrack at all are not charged the transcript fee.

#### Why is brandMentions 0 for my ad?

Brand mentions are matched on the advertiser's page name as the ad library lists it, as whole words. A page called "Nike Running" does not count a spoken "Nike".

#### Why was a video skipped as a copy?

Ad libraries list one creative several times — for example the 9:16 and 1:1 cuts of the same video. Videos of the same length (within half a second) but a different shape count as one creative: the vertical one is analysed, and the others get a free row with `copyOfVideoNumber`. Videos of the same length and shape are treated as different cards and all analysed. Turn on **Analyse every version of a creative** to analyse every version.

#### Why did a video fail?

Most often the ad-library link has expired — run the Actor soon after the scraper. Other causes: the link opens a web page rather than the file, the file is damaged, or the video is longer than 5 minutes. Failed videos are never charged; the reason is in `error`.

#### Is it free to try?

Yes. On Apify's free plan you can analyse 5 ad videos a month, each up to 60 seconds.

#### Can I use it with ChatGPT or Claude?

Yes. Export the dataset as JSON or CSV and give it to the model with a question, or call the Actor through the [Apify MCP server](https://mcp.apify.com) from your AI assistant. The timed transcript and on-screen timeline give it the facts of each ad to reason about.

#### Is this legal?

The Actor analyses video files you give it. Ads in public ad libraries are published for transparency; check the terms of the source and your local law before reusing creatives, and do not use the results to copy protected work.

### Support / feedback

Found a bug or need another scraper's fields supported? Open an issue on the Actor's **Issues** tab.

# Actor input Schema

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

The dataset of an ad-library scraper run — for example **Facebook Ads Library Scraper**, Meta Ad Library, TikTok Ads Library or any scraper whose results contain video file links. **How:** run the scraper, open its run, and pick its dataset here (or paste the dataset ID from the run's Storage tab). The Actor finds every ad video in it and keeps each ad's ID, advertiser, call to action, landing page and text next to the analysis. You can also connect this Actor as an integration that runs after the scraper. **Run it soon after the scraper: ad-library video links expire after a few days.**

## `videoUrls` (type: `array`):

Direct links to video files (MP4, MOV, WebM, MKV, AVI, MPEG), one per line — for example the `videoHdUrl` of an ad in a scraper's results. The prefilled link is a public-domain U.S. Army TV ad, so you can see the output before using your own ads. Links to a post or an ad page cannot be analysed. Videos up to **5 minutes** and 150 MB (free plan: up to 60 seconds and 50 MB). Files over 48 MB are converted first, for a conversion fee from November 11, 2026: 1080p ads of up to about 4 minutes and 4K ads of up to about 1 minute are taken.

## `preset` (type: `string`):

**Standard** describes what happens on screen, moment by moment — people, products, actions, settings — and reads larger text and brand names. **Detailed** reads the picture at a higher resolution in shorter windows, catching small text, labels and logos, for a surcharge per 10 seconds of video.

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

Two-letter code of the language spoken in the ads (`en`, `es`, `de`, `fr`, `pt`…). Leave empty to detect it per video.

## `analyzeAllVariants` (type: `boolean`):

Ad libraries often list one creative several times — for example in 9:16 and 1:1. By default videos of the same length (within half a second) but a different shape count as one creative, and only the vertical version is analysed and charged; the others get a free `skipped` row pointing to it. Videos of the same length and shape are different cards and are all analysed. Turn this on to analyse and pay for every version.

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

How many video ads to take from the dataset, in its order. Ads without a video are listed as skipped and do not count.

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

Ads analysed at the same time. No effect on price.

## Actor input object example

```json
{
  "videoUrls": [
    "https://upload.wikimedia.org/wikipedia/commons/4/4b/Army_Strong_TV_ad%2C_2012.webm"
  ],
  "preset": "balanced",
  "language": "",
  "analyzeAllVariants": false,
  "maxAds": 50,
  "maxConcurrency": 3
}
```

# Actor output Schema

## `ads` (type: `string`):

One row per ad video: the ad's ID, advertiser, call to action, landing page and text from the scraper; the video's length, size and aspect ratio; the transcript with sentence and word timing; the on-screen timeline; the 3-second hook; time to first word, words per minute and speech coverage; spoken calls to action and brand mentions with their times; and what was billed. Videos that could not be analysed carry status 'failed' with an 'error' field, and videos left out (other versions of a creative, duplicates, ads without video, free-plan or run cost limits) carry status 'skipped'. Neither is charged.

# 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 = {
    "videoUrls": [
        "https://upload.wikimedia.org/wikipedia/commons/4/4b/Army_Strong_TV_ad%2C_2012.webm"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("deapi/video-ad-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 = { "videoUrls": ["https://upload.wikimedia.org/wikipedia/commons/4/4b/Army_Strong_TV_ad%2C_2012.webm"] }

# Run the Actor and wait for it to finish
run = client.actor("deapi/video-ad-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 '{
  "videoUrls": [
    "https://upload.wikimedia.org/wikipedia/commons/4/4b/Army_Strong_TV_ad%2C_2012.webm"
  ]
}' |
apify call deapi/video-ad-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,deapi/video-ad-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/GwWu9ZasMLoboNzgM/builds/NHgFIKVEg8yEZedZI/openapi.json
