# Microsoft Ads Library Scraper: Bing Ads Transparency (`crunchy_galaxy_qcr/microsoft-ads-library-scraper`) Actor

Scrape the Microsoft (Bing) Ads Library: ad copy, landing pages, images, first/last shown dates, EU impression ranges, country split and targeting. Search by keyword, advertiser name or ID. No login or API key.

- **URL**: https://apify.com/crunchy_galaxy_qcr/microsoft-ads-library-scraper.md
- **Developed by:** [Kendall Sorenson](https://apify.com/crunchy_galaxy_qcr) (community)
- **Categories:** Lead generation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 ad scrapeds

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

## Microsoft Ads Library Scraper: Bing Ads Transparency data

Scrape the **Microsoft Ads Library** (also called the Bing Ads Library or Microsoft Ad Transparency library) and get every ad an advertiser or keyword has run on **Bing search, Microsoft Advertising and partner sites in the EU/EEA**: the headline and ad text, display and landing page URLs, image creatives, **first and last shown dates**, **EU impression ranges**, the **country-by-country impression split** and the **targeting types** used.

Search by keyword (ad copy or brand), by advertiser name, or by Microsoft advertiser ID. No Microsoft account, login, developer token or API key needed.

- ✅ Full ad copy: title, description, display URL, destination URL and landing domain
- ✅ Image ad creatives (Bing image URLs) and ad format
- ✅ First shown, last shown and days running for every ad
- ✅ Total EU/EEA impressions range (e.g. `250K - 500K`) plus numeric min/max for sorting
- ✅ Impression share by country (France 44.2%, Germany 17.7%, ...) and targeting types (age, gender, location, Microsoft audiences, advertiser audiences)
- ✅ Advertiser country and verified status
- ✅ Filter by EU/EEA country and date range, deduplicated across all your queries
- ✅ Built-in rate-limit handling and retries, so big runs finish instead of failing

👉 Need Google ads too? Use the companion [Google Ads Transparency & Ad Library Scraper](https://apify.com/crunchy_galaxy_qcr/google-ads-transparency-scraper) to see the same competitors' Google Search, YouTube and Display ads.

### What can you use it for?

- **Competitor ad research:** see the exact Bing ad copy, offers and landing pages your competitors are testing, and how long each ad has been running (long-running ads are usually the winners).
- **PPC and SEM planning:** collect headline and description ideas for a keyword like `crm software` across every advertiser bidding on it.
- **Market and pricing intelligence:** track which brands push which products in which EU countries, and how much reach they get.
- **Brand protection and compliance:** find ads that bid on or mention your brand, check "paid for by" information, and see restricted ads.
- **Agency reporting and DSA research:** export clean, structured Digital Services Act transparency data to Sheets, Excel, BI tools or your own database.

### Example output (real run, Nov 2, 2026)

Search term `crm software`, 25 ads. Top rows:

| Advertiser | Headline | EU impressions | Targeting |
|---|---|---|---|
| monday.com | monday CRM (sehr gut bewertet) - Teste monday CRM kostenlos | 250K - 500K | Gender, Age, Location |
| monday.com | CRM Without the Frustration - No-Code CRM Software | 250K - 500K | Gender, Age, Location |

Advertiser `Booking.com`, shown in Germany or the Netherlands in the last 30 days: 25 ads, 21 of them image ads with creatives.

#### One dataset row (shortened)

```json
{
  "adId": "72224646372358",
  "advertiserName": "Booking.com B.V.",
  "advertiserId": "4294969411",
  "advertiserCountry": "Netherlands",
  "advertiserVerified": true,
  "title": "Thermen Berendonck",
  "description": "Hotels, Homes, And Everything In Between",
  "displayUrl": "www.booking.com",
  "destinationUrl": "https://www.booking.com/hotel/nl/thermen-berendonck.en-gb.html?aid=2276386&pagename=thermen-berendonck",
  "landingDomain": "booking.com",
  "adFormat": "image",
  "imageUrls": ["https://www.bing.com/th?id=OADD2.1285329232070183_1C03DXDIA5G4JVN&pid=21.2"],
  "firstShown": "2026-08-15",
  "lastShown": "2026-11-01",
  "daysRunning": 79,
  "impressionsRange": "500 - 1K",
  "impressionsMin": 500,
  "impressionsMax": 1000,
  "paidForBy": null,
  "restricted": false,
  "countries": ["BE", "DE", "NL", "PT"],
  "impressionsByCountry": [{ "country": "Netherlands", "countryCode": "NL", "share": "98.4%", "sharePct": 98.4 }],
  "targetingTypes": ["MicrosoftAudiences"],
  "exclusionTypes": ["Location"],
  "query": "Booking.com",
  "queryType": "advertiser",
  "adApiUrl": "https://adlibrary.api.bingads.microsoft.com/api/v1/Ads/72224646372358?expand=AdDetails(expand=ImpressionsByCountry,Targets)",
  "scrapedAt": "2026-11-02T18:20:11.000Z"
}
```

A `SUMMARY` record in the key-value store lists, for each search term and advertiser, how many matching ads the library reports and how many were saved.

### How to use it

1. Add **search terms** (words in the ad copy or a brand name) and/or **advertisers** (names like `Hubspot, Inc.` or numeric IDs like `4295007715`).
2. Optionally pick **countries** (EU/EEA only) and a date range, or use **Shown in the last N days**.
3. Set **Max ads per search term / advertiser** and **Max ads in total**, then click Start.
4. Download the results as JSON, CSV, Excel or HTML, or connect them to Google Sheets, Make, Zapier or the Apify API.

Advertiser names are matched against the library's advertiser list. Big brands often have several accounts with the same legal name (Booking.com has five); the Actor includes up to five exact matches and logs other close matches with their IDs, so you can pass the exact one next time.

### Input

| Field | What it does |
|---|---|
| `searchTerms` | Keywords in ad copy or advertiser names, one per line |
| `advertisers` | Advertiser names or numeric Microsoft advertiser IDs |
| `countries` | EU/EEA countries the ad was shown in (empty = all) |
| `lastDays` / `startDate` / `endDate` | Only ads that ran in this period (YYYY-MM-DD) |
| `maxAdsPerQuery` | Cap per search term or advertiser (default 100) |
| `maxAds` | Cap for the whole run (default 1,000) |
| `includeDetails` | Dates, impressions, paid-for-by, restrictions and targeting (default on) |
| `includeImpressionsByCountry` | Country impression split (default on) |
| `concurrency` | Parallel requests (default 3); the Actor slows down automatically if Microsoft rate-limits |

### FAQ

**Does this cover ads shown in the US or the rest of the world?** No. Microsoft publishes its Ad Library to meet the EU Digital Services Act, so it only contains ads that were **shown in the European Union or European Economic Area** (the 27 EU countries plus Iceland, Liechtenstein and Norway), recorded **since June 2023**. Global advertisers like HubSpot, monday.com or Booking.com usually run in the EU too, so you'll see their ads, but a US-only campaign won't appear. Impression numbers count EU/EEA impressions only.

**Is the data official?** Yes. It comes from Microsoft's public Ad Library API, the same data as [adlibrary.ads.microsoft.com](https://adlibrary.ads.microsoft.com/). The Actor does not log in or bypass anything.

**How fresh is it?** Microsoft says there can be a 1–3 day delay, so `lastShown` may lag for ads that are still running.

**Why are impressions a range?** Microsoft only publishes ranges (like `25K - 50K`). We add `impressionsMin` and `impressionsMax` numbers so you can sort and filter.

**Why do some ads have several possible titles?** For dynamic and responsive ads, Microsoft shows a recent, representative version of the copy.

**Does it include clicks, spend or keywords?** No. Microsoft doesn't publish those in the Ad Library.

**Why does a country filter sometimes run slower?** For very large advertisers, Microsoft's own country filter can time out. The Actor then automatically fetches the advertiser's ads and keeps the ones whose impression countries match, so you still get results.

**Can I monitor competitors?** Yes. Schedule the Actor weekly with `lastDays: 7` to catch new ads as they launch.

**How many ads can I get?** Microsoft returns up to about 1,000 ads per search, 24 at a time. Use several search terms, advertiser IDs or date ranges to go further.

### Related tools

- [Google Ads Transparency & Ad Library Scraper](https://apify.com/crunchy_galaxy_qcr/google-ads-transparency-scraper): your competitors' Google Search, YouTube and Display ads
- [AI Search Visibility Tracker](https://apify.com/crunchy_galaxy_qcr/ai-visibility-tracker): whether ChatGPT, Gemini and Perplexity recommend your brand, with rank and share of voice
- [AI Citation Tracker](https://apify.com/crunchy_galaxy_qcr/ai-citation-tracker): which websites ChatGPT and Perplexity cite for your market
- [Free AI visibility checker](https://ai-visibility-checker-lac.vercel.app): a 30-second check of whether ChatGPT recommends your brand

Built by Kendall Sorenson.

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords found in ad copy or advertiser names, e.g. <code>crm software</code> or a brand like <code>hubspot</code>. One per line.

## `advertisers` (type: `array`):

Advertiser names (e.g. <code>Hubspot, Inc.</code>) or numeric Microsoft advertiser IDs (e.g. <code>4295007715</code>). Names are matched to the library's advertiser list; the log shows other close matches you can pass by ID.

## `countries` (type: `array`):

Only return ads shown in these countries. Leave empty for all EU/EEA countries. The Microsoft Ad Library only covers the EU and EEA.

## `lastDays` (type: `integer`):

Shortcut for Start date: only ads that ran in the last N days. Ignored if Start date is set.

## `startDate` (type: `string`):

Only ads that ran on or after this date (YYYY-MM-DD). Library data starts in June 2023.

## `endDate` (type: `string`):

Only ads that ran on or before this date (YYYY-MM-DD).

## `maxAdsPerQuery` (type: `integer`):

Stop each search term or advertiser after this many ads.

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

Hard cap for the whole run.

## `includeDetails` (type: `boolean`):

Adds first/last shown dates, days running, EU impressions range, paid-for-by, restriction status and targeting types (one extra request per ad, included in the price).

## `includeImpressionsByCountry` (type: `boolean`):

Adds each EU/EEA country's share of the ad's impressions. Requires Include ad details.

## `concurrency` (type: `integer`):

Higher is faster but more likely to hit Microsoft's rate limits (the Actor retries automatically).

## Actor input object example

```json
{
  "searchTerms": [
    "hubspot"
  ],
  "advertisers": [
    "Hubspot, Inc."
  ],
  "maxAdsPerQuery": 100,
  "maxAds": 1000,
  "includeDetails": true,
  "includeImpressionsByCountry": true,
  "concurrency": 3
}
```

# Actor output Schema

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

No description

## `summary` (type: `string`):

No description

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {
    "searchTerms": [
        "hubspot"
    ],
    "advertisers": [
        "Hubspot, Inc."
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crunchy_galaxy_qcr/microsoft-ads-library-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 = {
    "searchTerms": ["hubspot"],
    "advertisers": ["Hubspot, Inc."],
}

# Run the Actor and wait for it to finish
run = client.actor("crunchy_galaxy_qcr/microsoft-ads-library-scraper").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 '{
  "searchTerms": [
    "hubspot"
  ],
  "advertisers": [
    "Hubspot, Inc."
  ]
}' |
apify call crunchy_galaxy_qcr/microsoft-ads-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crunchy_galaxy_qcr/microsoft-ads-library-scraper"
        }
    }
}
```

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/jGkBAuub2agLJOT4f/builds/wEQQansFuujPMt8MA/openapi.json
