# WhatsApp Ad Scraper — Click-to-WhatsApp from Meta Ads (`scrapeify/whatsapp-ad-scraper`) Actor

Scrape WhatsApp click-to-chat ad creatives from Meta Ad Library with publisher\_platforms\[0]=whatsapp filter. Search by keyword, Page ID, or URL. Returns ad body, CTA, wa.me links, spend/impression estimates, dates, countries. Built for fintech, real estate, travel DR campaigns.

- **URL**: https://apify.com/scrapeify/whatsapp-ad-scraper.md
- **Developed by:** [Scrapeify](https://apify.com/scrapeify) (community)
- **Categories:** Developer tools, Lead generation, Social media
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $25.00 / 1,000 results

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/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

## WhatsApp Ad Scraper — Extract Click-to-WhatsApp Ad Creatives from Meta Ad Library

Collect **WhatsApp-destination ad creatives** directly from the **Meta Ad Library** with a hard `publisher_platforms[0]=whatsapp` constraint applied at URL construction. The Scrapeify WhatsApp Ad Scraper accepts a keyword, numeric Page ID, or full Ad Library URL and returns structured JSON — ad content, performance estimates, timing, distribution, status flags, and a comprehensive run summary — for every matching creative without manual UI filtering.

Built for fintech, local services, real estate, travel, and direct-response verticals where WhatsApp dominates CTA funnels and performance marketers need programmatic access to competitive creative data.

---

### Features

| Capability | Detail |
|---|---|
| **WhatsApp filter** | `publisher_platforms[0]=whatsapp` enforced at URL build for keyword/page seeds |
| **Three seed modes** | `keyword`, numeric `pageId`, or full Ad Library `url` passthrough |
| **URL validation** | Hostname check against `facebook.com/ads/library` and `meta.com/ads/library` |
| **Input coercion** | `maxResults` accepts positive integers and string-digit values |
| **300-second watchdog** | Scrape timeout with cancellation semantics |
| **Summary aggregates** | `totalSpend`, `totalImpressions`, `uniquePlatforms`, `pagesScraped`, `executionTimeSeconds` |
| **Typed error objects** | `INVALID_INPUT`, `INVALID_URL`, `SCRAPING_ERROR`, `TIMEOUT`, `NO_RESULTS` |
| **Consistent schema** | Identical nested structure as Scrapeify Meta and Instagram Ad Library actors |
| **Dataset + KV exports** | One Dataset row per ad; `OUTPUT` key in default KV store |

---

### Use Cases

#### Click-to-WhatsApp Creative Research
Study how brands structure WhatsApp CTA ads across verticals — messaging, offers, visual formats, and landing destinations. Identify the creative patterns driving high-intent chat conversions in your category.

#### Fintech & Financial Services Intelligence
Financial advertisers heavily use WhatsApp for lead conversion in emerging markets. Pull creative corpora for banking, insurance, loans, and investment products. Analyze offer messaging, disclosure patterns, and regulatory language.

#### Local Services & Real Estate
Map how local businesses (dentists, real estate agents, contractors) use WhatsApp ads to drive direct conversations. Track regional advertising patterns and emerging competitors.

#### Travel & Hospitality
Study how hotels, airlines, and tour operators use WhatsApp to drive booking conversations. Capture promotional cadences, offer types, and destination messaging.

#### Competitor Intelligence
Monitor rival brands' WhatsApp creative refreshes. Alert on surges in new archive IDs for tracked Page IDs indicating campaign launches or budget increases.

#### AI-Powered Compliance Screening
Feed structured ad copy into LLM classifiers to detect prohibited claims, misleading disclosures, or regulatory violations. JSON input beats screenshot-based manual review at scale.

#### Automation Workflows
Schedule nightly competitor folder syncs. Pull WhatsApp ad creatives for a brand roster → push to your data warehouse → update competitive intelligence dashboards.

#### Market Research
Pass custom browser-address URLs with geographic parameters to study regional WhatsApp advertising patterns. Compare strategies across markets using the `url` input mode.

---

### Why Choose This Actor

- **Platform-specific** — eliminates post-filter logic for WhatsApp placements from your codebase
- **Schema consistency** — identical nested structure as Scrapeify Meta and Instagram actors for unified warehousing
- **Operational transparency** — explicit `pagesScraped`, `executionTimeSeconds`, and typed error objects per run
- **Production-ready** — validated inputs prevent wasted runs; structured error envelopes simplify automated triage

---

### Quick Start

1. Open the Scrapeify **WhatsApp Ad Scraper** on Apify Console.
2. Choose your seed: enter a **`keyword`**, a numeric **`pageId`**, or paste a full **`url`** from the Meta Ad Library browser address bar.
3. Set **`maxResults`** — start with 50 ads for validation.
4. After completion: inspect **`OUTPUT.summary.searchUrl`** to confirm WhatsApp publisher filter propagation.
5. Export the **Dataset** as JSONL for your pipeline.

> **Tip:** To find a brand's numeric Page ID, use the [Scrapeify Brand Finder](https://apify.com/scrapeify/facebook-page-id-finder) actor first.

---

### Input Schema

```json
{
  "keyword": "home loans",
  "maxResults": 100
}
````

| Field | Type | Required | Description |
|---|---|---|---|
| `keyword` | string | One-of | Free-text search. WhatsApp platform filter applied automatically. |
| `pageId` | string | One-of | Numeric Meta Page ID. Must be a digit string. |
| `url` | string | One-of | Full Ad Library URL. Must contain `facebook.com/ads/library` or `meta.com/ads/library`. |
| `maxResults` | integer | Yes | Number of WhatsApp ads to collect. Must be positive. |

**Exactly one** of `keyword`, `pageId`, or `url` should be active per run.

***

### Output Schema

#### Dataset Row (one row per WhatsApp ad)

```json
{
  "metadata": {
    "scraped_at": "2026-05-07T04:00:00.000Z",
    "ad_archive_id": "987654321098765",
    "page_id": "1234567890",
    "page_name": "LoanCorp Financial",
    "page_like_count": 42000,
    "page_profile_uri": "https://www.facebook.com/loancorpfinancial",
    "page_categories": ["Financial Services"]
  },
  "ad_content": {
    "body": "Get instant home loan approval in 24 hours. Chat with us on WhatsApp now.",
    "title": "Home Loans Made Simple",
    "link_url": "https://wa.me/15550001234?text=I%20want%20a%20home%20loan",
    "cta_text": "Send Message",
    "images": ["https://scontent.xx.fbcdn.net/v/t45.1600-4/..."],
    "videos": [],
    "cards": []
  },
  "timing": {
    "start_date": "2026-04-15",
    "end_date": null,
    "total_active_time": null
  },
  "performance": {
    "impressions": 50000,
    "spend": 1200,
    "currency": "USD"
  },
  "distribution": {
    "publisher_platform": ["WHATSAPP"],
    "targeted_or_reached_countries": ["US", "IN", "BR"]
  },
  "status": {
    "is_active": true,
    "is_aaa_eligible": false,
    "contains_sensitive_content": false
  },
  "additional_info": {
    "categories": ["Financial Products & Services"],
    "collation_count": 1
  }
}
```

#### Run Summary (`OUTPUT` key in default KV store)

```json
{
  "summary": {
    "totalAds": 100,
    "searchType": "keyword_unordered",
    "identifier": "home loans",
    "searchUrl": "https://www.facebook.com/ads/library/?publisher_platforms[0]=whatsapp&country=ALL&q=home%20loans&search_type=keyword_unordered",
    "keyword": "home loans",
    "pageId": null,
    "url": null,
    "urlParams": {
      "publisher_platforms": ["whatsapp"],
      "country": "ALL"
    },
    "totalSpend": 9100.25,
    "totalImpressions": 625000,
    "uniquePlatforms": ["WHATSAPP"],
    "scrapedAt": "2026-05-07T04:00:00.000Z",
    "pagesScraped": 9,
    "executionTimeSeconds": 37.1,
    "status": "SUCCESS",
    "error": null
  },
  "data": {
    "ads": ["...array of full ad objects..."],
    "schema": {
      "metadata": ["scraped_at", "ad_archive_id", "page_id", "page_name", "page_like_count", "page_profile_uri", "page_categories"],
      "ad_content": ["body", "title", "link_url", "cta_text", "images", "videos", "cards"],
      "timing": ["start_date", "end_date", "total_active_time"],
      "performance": ["spend", "currency", "impressions"],
      "distribution": ["publisher_platform", "targeted_or_reached_countries"],
      "status": ["is_active", "is_aaa_eligible", "contains_sensitive_content"],
      "additional_info": ["categories", "archive_types", "collation_count"]
    }
  }
}
```

| Field | Type | Description |
|---|---|---|
| `summary.totalAds` | integer | WhatsApp-filtered ads collected |
| `summary.searchUrl` | string | Constructed URL with WhatsApp publisher filter |
| `summary.uniquePlatforms` | array | Should contain `["WHATSAPP"]` |
| `summary.status` | string | `SUCCESS`, `ERROR`, `NO_RESULTS`, or `TIMEOUT` |
| `summary.error` | object/null | Typed error: `type`, `message`, `details`, `suggestion` |

***

### API Examples

#### cURL

```bash
curl "https://api.apify.com/v2/acts/scrapeify~whatsapp-scraper-premium/runs?token=$APIFY_TOKEN" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "keyword": "travel deals",
    "maxResults": 120
  }'
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

## Search by keyword
run = client.actor("scrapeify/whatsapp-ad-scraper").call(
    run_input={"keyword": "travel deals", "maxResults": 120}
)

## Or by Page ID
run = client.actor("scrapeify/whatsapp-ad-scraper").call(
    run_input={"pageId": "1234567890", "maxResults": 200}
)

for ad in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(ad["ad_content"]["body"], ad["performance"]["impressions"])
```

#### JavaScript / Node.js

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

// Pass a custom URL with geographic filters from browser
const run = await client.actor("scrapeify/whatsapp-ad-scraper").call({
  url: "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=IN&q=real+estate",
  maxResults: 80,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Collected ${items.length} WhatsApp ads`);
```

***

### Integration Examples

#### ChatGPT / Custom GPT

Expose the Apify run endpoint as a Custom GPT action. Return structured ad JSON for the model to summarize WhatsApp CTA patterns, identify dominant offer types, or compare brands' messaging across verticals.

#### Claude Tool Use

Register a `whatsapp_ads_search` tool. Pass ad `body` and `cta_text` fields into compliance-checking prompts or brief generation workflows.

#### LangChain

```python
from langchain.tools import tool

@tool
def search_whatsapp_ads(keyword: str, max_results: int = 100) -> list:
    """Retrieve WhatsApp ad creatives from Meta Ad Library by keyword."""
    run = client.actor("scrapeify/whatsapp-ad-scraper").call(
        run_input={"keyword": keyword, "maxResults": max_results}
    )
    return client.dataset(run["defaultDatasetId"]).list_items().items
```

#### CrewAI

Chain: `BrandFinderAgent` (resolves Page ID) → `WhatsAppAdsAgent` (pulls creatives) → `ComplianceAgent` (checks for prohibited claims) → `ReportAgent` (drafts competitive brief).

#### n8n / Make.com / Zapier

Schedule trigger → Apify run → on `OUTPUT.summary.status != SUCCESS` route to Slack alert → on success iterate Dataset items → push to Airtable or Google Sheets.

#### RAG Systems

Chunk `ad_content.body` with metadata (`page_name`, `start_date`, `targeted_or_reached_countries`). Store in vector database. Enable retrieval for compliance checks, brief generation, and competitive research queries.

#### Webhook Automation

Configure Apify webhooks on `RUN.SUCCEEDED` → receive Dataset URL in payload → trigger downstream enrichment pipeline automatically.

***

### Frequently Asked Questions

**1. Are `wa.me` links included in output?**
Often appear under `ad_content.link_url`. The exact field depends on how the advertiser configured the ad — validate across a sample of payloads.

**2. Will Instagram or Facebook placements appear?**
The filter targets WhatsApp inventory specifically. Validate `distribution.publisher_platform` arrays occasionally — some ads may be eligible for multiple platforms.

**3. How is this different from the Meta Ad Library Scraper?**
Same underlying engine with a WhatsApp platform constraint applied at URL construction. The Meta scraper covers all platforms without a default filter.

**4. Can I filter by country or active status?**
Yes — paste a full Ad Library URL with your `country` and `active_status` parameters as the `url` input.

**5. What is `NO_RESULTS` status?**
Ad Library returned no WhatsApp-matching ads for the filter combination. Broaden geography, remove status filters, or try a different keyword.

**6. Are spend and impressions figures exact?**
No — these are Meta's publicly disclosed transparency **estimates**, not audited financial figures. Use as directional signals.

**7. How do I find a brand's numeric Page ID?**
Use the [Scrapeify Brand Finder](https://apify.com/scrapeify/facebook-page-id-finder) actor — enter the brand name and receive deduplicated Page ID candidates.

**8. What happens on TIMEOUT?**
Summary status is `TIMEOUT`. Reduce `maxResults` and rerun. Shard large requests across multiple runs.

**9. Are phone numbers in `link_url` data?**
WhatsApp `wa.me` URLs often contain phone numbers. Treat these as unstructured data — do not auto-dial without explicit consent verification.

**10. How do I deduplicate across runs?**
Key on `metadata.ad_archive_id` — the stable unique identifier per ad in the Meta Ad Library.

**11. Does this include archived ads?**
Depends on URL parameters. Pass `active_status=all` in a custom URL to include both active and archived creatives.

**12. Are financial ad disclosures preserved in output?**
Yes — ad copy passes through verbatim. Compliance teams should preserve full `body` text, not truncated summaries.

**13. What proxy setup is recommended?**
Use Apify RESIDENTIAL proxy groups if corporate IP egress yields sparse pagination results.

**14. Is there overlap with the Instagram scraper output?**
No overlap by design — WhatsApp and Instagram filters are mutually exclusive in Scrapeify's Ad Library actors. Verify `publisher_platform` arrays if needed.

**15. How do I handle currency mixing in spend aggregates?**
Check `performance.currency` per ad. Do not sum spend across ads with different currencies without FX normalization.

**16. Can I process multiple keywords in one run?**
No — one seed (keyword, pageId, or url) per run. Use a fan-out orchestrator for keyword lists.

**17. What is `collation_count` in `additional_info`?**
Indicates how many ad variations Meta has grouped under a single creative ID. Usually 1 for individual ads.

**18. What encoding are text fields in?**
UTF-8. Multilingual ad copy is preserved unchanged — useful for markets where WhatsApp ads run in Arabic, Hindi, Portuguese, etc.

**19. Can regulated category ads (health, finance) be collected?**
Coverage may be partial. Meta withholds or restricts some payloads in policy-constrained verticals.

**20. Are webhook payloads large?**
Link to Dataset from the webhook payload instead of embedding full ad arrays. Apify webhook payloads are not suited for large JSON responses.

**21. Can I use this for GDPR-regulated research?**
Page names and ad copy may constitute personal data in edge cases. Apply your organization's data retention and classification policies.

**22. How do I set up monitoring for new campaign launches?**
Schedule weekly runs → diff `ad_archive_id` sets between runs → alert when new IDs appear for tracked brands.

**23. What does `is_aaa_eligible` mean?**
Eligibility for Meta's "About This Ad" advertiser transparency feature. Not directly actionable for most research workflows.

**24. Is it possible to get video creative URLs?**
Yes — `ad_content.videos[]` contains URLs when video assets are present. Fetching and storing media is your responsibility.

**25. How should I tag Apify runs for traceability?**
Include `{ vertical, geo, brand, run_date }` in Apify run metadata. Enables filtering and auditing across large automation pipelines.

***

### Best Practices

- **Archive `searchUrl`** from `OUTPUT.summary` with each snapshot for reproducibility auditing
- **Separate staging and production tokens** in Zapier/Make triggers
- **Log Meta HTTP anomalies** for proxy rotation tuning
- **Shard by keyword** for large volume — horizontal runs outperform one massive pull
- **Validate `publisher_platform` arrays** in sample rows to confirm WhatsApp filter propagation
- **Add jitter between runs** to reduce request hotspots on high-frequency automation
- **Preserve verbatim disclosure text** — do not truncate regulated ad copy in financial/health verticals

***

### Performance & Scalability

| Factor | Guidance |
|---|---|
| **Throughput** | Pagination-latency dominant; `pagesScraped` scales with `maxResults` |
| **Timeout risk** | Very large `maxResults` may hit 300s watchdog — bisect and shard |
| **Horizontal scaling** | Fan-out per keyword or brand; stagger to avoid hotspot throttling |
| **Storage** | Dataset is authoritative; link to it from webhooks instead of embedding arrays |

***

### AI & Automation Workflows

**Compliance pipeline:** Schedule weekly → pull WhatsApp ads for a brand roster → classify `body` with a policy-rule LLM → flag suspected violations → queue for human review.

**Creative benchmarking:** Pull top 200 WhatsApp ads by vertical → extract CTA verbs → frequency rank → identify dominant conversion language for brief generation.

**Multi-market comparison:** Run with country-filtered URLs for IN, BR, and ID → compare creative strategies → identify regional messaging patterns for international expansion.

***

### Error Handling

| Scenario | Behavior |
|---|---|
| Non-numeric `pageId` | Validation error with descriptive message before any network requests |
| Invalid `url` hostname | Validation error — must contain Ad Library domain |
| `NO_RESULTS` | Clean completion; `summary.status = NO_RESULTS`, not a failure |
| `TIMEOUT` | Reduce `maxResults`; check logs for pagination progress |
| `SCRAPING_ERROR` | Typed error with `details` and `suggestion`; check proxy health |
| Multiple seeds active | Validation error — exactly one seed required |

***

### Trust & Reliability

Scrapeify maintains domain-specific Ad Library wrappers so filters don't silently drift when teams copy stale URLs manually. Each run exposes explicit operational metrics for SLA monitoring and automated pipeline health checks.

***

### Related Scrapeify Actors

Explore the full Scrapeify suite — chain these actors together for end-to-end automation pipelines:

| Actor | What it does |
|---|---|
| [Amazon Scraper](https://apify.com/scrapeify/amazon-scraper) | ASINs, prices, sponsored flags across 23 marketplaces |
| [Instagram Ad Library Scraper](https://apify.com/scrapeify/instagram-ad-library-scraper) | Instagram-only ads from Meta Ad Library |
| [Meta Ad Library Scraper](https://apify.com/scrapeify/meta-ad-library-scraper) | Facebook & Instagram ads with sort options |
| [YouTube Video Downloader](https://apify.com/scrapeify/youtube-video-downloader) | Videos & audio to Apify Key-Value Store |
| [Meta Brand & Page ID Finder](https://apify.com/scrapeify/facebook-page-id-finder) | Resolve brand names to numeric Page IDs |
| [Google Maps Scraper](https://apify.com/scrapeify/google-maps-scraper) | Local business leads, reviews, emails, contacts |
| [Google News Scraper](https://apify.com/scrapeify/google-news-scraper) | Headlines, sources, article URLs (up to 2K) |

***

*WhatsApp is a trademark of Meta Platforms, Inc. This actor is not affiliated with or endorsed by Meta.*

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "SoftwareApplication",
      "name": "Scrapeify WhatsApp Ad Scraper",
      "applicationCategory": "DeveloperApplication",
      "applicationSubCategory": "Ad Intelligence API",
      "operatingSystem": "Cloud (Apify Platform)",
      "description": "Scrape WhatsApp-destination ad creatives from the Meta Ad Library with a hard publisher_platforms[0]=whatsapp filter. Search by keyword, Page ID, or URL. No cookies or Meta API credentials required.",
      "url": "https://apify.com/scrapeify/whatsapp-ad-scraper",
      "featureList": [
        "WhatsApp-only platform filter",
        "Three seed modes: keyword, Page ID, URL",
        "wa.me link extraction",
        "Spend and impression estimates",
        "Multi-language support",
        "Typed error envelope"
      ],
      "offers": {
        "@type": "Offer",
        "category": "SaaS"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Scrapeify"
      }
    },
    {
      "@type": "FAQPage",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "Are wa.me links included in the scraper output?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Yes — they often appear under ad_content.link_url. The exact field depends on how the advertiser configured the ad."
          }
        },
        {
          "@type": "Question",
          "name": "How is this different from the Meta Ad Library Scraper?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Same underlying engine with a WhatsApp platform constraint applied at URL construction. The Meta scraper covers all platforms without a default filter."
          }
        },
        {
          "@type": "Question",
          "name": "Can I filter WhatsApp ads by country or active status?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Yes — paste a full Ad Library URL with your country and active_status parameters as the url input."
          }
        },
        {
          "@type": "Question",
          "name": "Are spend and impressions figures exact?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "No. These are Meta's publicly disclosed transparency estimates, not audited financial figures. Use as directional signals."
          }
        },
        {
          "@type": "Question",
          "name": "How do I find a brand's numeric Page ID?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Use the Scrapeify Brand Finder actor — enter the brand name and receive deduplicated Page ID candidates."
          }
        },
        {
          "@type": "Question",
          "name": "What does TIMEOUT status mean?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Summary status TIMEOUT means the run hit the 300-second scrape watchdog. Reduce maxResults and rerun, or shard large requests across multiple runs."
          }
        }
      ]
    }
  ]
}
</script>

# Actor input Schema

## `keyword` (type: `string`):

Optional. Search term or brand name (e.g. 'nike', 'adidas'). Use this OR pageId OR url—only one needed.

## `pageId` (type: `string`):

Optional. Facebook Page ID (brand ID). Use this OR keyword OR url—only one needed.

## `url` (type: `string`):

Optional. Full Facebook/Meta Ad Library URL. Use this OR keyword OR pageId—only one needed.

## `maxResults` (type: `integer`):

How many ads you want. We scrape until we have this many or there are no more results. No upper limit. All returned ads are WhatsApp platform.

## `proxyConfiguration` (type: `object`):

Apify Proxy configuration. RESIDENTIAL group is recommended for reliability. Defaults to Apify Proxy with RESIDENTIAL group if you don't customize.

## Actor input object example

```json
{
  "keyword": "nike",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapeify/whatsapp-ad-scraper").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 = { "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    } }

# Run the Actor and wait for it to finish
run = client.actor("scrapeify/whatsapp-ad-scraper").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 '{
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scrapeify/whatsapp-ad-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "WhatsApp Ad Scraper — Click-to-WhatsApp from Meta Ads",
        "description": "Scrape WhatsApp click-to-chat ad creatives from Meta Ad Library with publisher_platforms[0]=whatsapp filter. Search by keyword, Page ID, or URL. Returns ad body, CTA, wa.me links, spend/impression estimates, dates, countries. Built for fintech, real estate, travel DR campaigns.",
        "version": "1.0",
        "x-build-id": "eIU092rF3Tfh9miWp"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapeify~whatsapp-ad-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapeify-whatsapp-ad-scraper",
                "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/scrapeify~whatsapp-ad-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scrapeify-whatsapp-ad-scraper",
                "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/scrapeify~whatsapp-ad-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scrapeify-whatsapp-ad-scraper",
                "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",
                "required": [
                    "maxResults"
                ],
                "properties": {
                    "keyword": {
                        "title": "Keyword or Brand Name",
                        "type": "string",
                        "description": "Optional. Search term or brand name (e.g. 'nike', 'adidas'). Use this OR pageId OR url—only one needed.",
                        "default": "nike"
                    },
                    "pageId": {
                        "title": "Brand / Page ID",
                        "type": "string",
                        "description": "Optional. Facebook Page ID (brand ID). Use this OR keyword OR url—only one needed."
                    },
                    "url": {
                        "title": "Ad Library URL",
                        "type": "string",
                        "description": "Optional. Full Facebook/Meta Ad Library URL. Use this OR keyword OR pageId—only one needed."
                    },
                    "maxResults": {
                        "title": "Number of Results",
                        "minimum": 1,
                        "type": "integer",
                        "description": "How many ads you want. We scrape until we have this many or there are no more results. No upper limit. All returned ads are WhatsApp platform.",
                        "default": 50
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify Proxy configuration. RESIDENTIAL group is recommended for reliability. Defaults to Apify Proxy with RESIDENTIAL group if you don't customize.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
