# Bing Copilot Ads Scraper (`gytelio1/bing-copilot-ads-scraper`) Actor

Bing Copilot Ads Scraper collects the sponsored ads Bing shows in AI Mode (Copilot Search): the Related Products carousel, text ads, and image ads. See who wins AI Mode for your keywords: which stores and brands advertise, at what price and discount, in which position, and next to which answer.

- **URL**: https://apify.com/gytelio1/bing-copilot-ads-scraper.md
- **Developed by:** [Gytis Ščipokas](https://apify.com/gytelio1) (community)
- **Categories:** AI, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 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.

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

### What does Bing Copilot Ads Scraper do?

Bing Copilot Ads Scraper collects the sponsored ads Bing shows in AI Mode (Copilot Search): the **Related Products** carousel, text ads, and image ads shown with Copilot's answer. See who wins AI Mode for your keywords: which stores and brands advertise, at what price and discount, in which position, and next to which answer.

![Sponsored VPN products from McAfee, Bitdefender, and NordVPN in Bing AI Mode](https://api.apify.com/v2/key-value-stores/3GsE5ExeTPV3E8YoW/records/bing-copilot-ad-example-vpn-v2.png)

### Use cases

- **Competitor monitoring.** See which stores advertise for your keywords, which products they push, at what price and discount.
- **Market research before buying ads.** Find out how crowded a category is before you spend on Microsoft Ads.
- **Ad verification.** Check that your own shopping and search ads show up in AI Mode, for which queries, and with the right details.
- **Trend tracking.** Schedule daily runs over the same queries and build a history of the AI Mode ad market.

### How to use it

1. Open the **Input** tab.
2. Add queries to **Queries**: a product type, like "best vpn", or a brand name, like "dyson".
3. Click **Start**.
4. Open the **Output** tab when the run finishes.

### Input

| Field | Description |
|---|---|
| `queries` | What to ask Bing AI Mode. Every ad shown in the chat is saved. A product type ("best vpn", "best laptops for students") shows who advertises for it. A brand name ("nordvpn", "dyson") shows who advertises on it. |
| `depth` | How many chats each query gets: `quick` (8 chats, about $0.15 per query), `standard` (24, default, about $0.50), or `deep` (60, about $1.20). Prices include typical ads; the number of ads depends on what Bing shows. The run ends when every query has had its chats, so 3 queries at Standard means 72 chats. Bing rotates its ads, so more chats find more ads and advertisers. |
| `country` | Two-letter country code, like US, GB, or CZ, picked from a list. Chats run from this country, so you see the ads and currency shown there. Default US. |
| `saveScreenshots` | Saves proof of the ads: a screenshot of the message with the ads Bing showed for it, and the ads' HTML with every field Bing sent. Linked from `screenshotUrls` and `htmlUrl`. Default off. Adds a few seconds per turn with ads, no extra charge. |
| `includeOrganicLinks` | Advanced. Also saves the links Bing cited in its answer, as `organicLinks`. Default off. Waits for the whole answer, so each chat takes about twice as long, and each chat is also charged an Answer links event. |
| `followUpQueries` | Advanced. Optional, empty by default. Sent in order after each query, the same for every query. Bing shows its ads on the query itself, so follow-ups rarely bring more ads and add 30-40 seconds each. Each one sent is charged a Follow-up event. Up to 8. |

#### See which brands advertise for a topic

```json
{
    "queries": ["best vpn", "best laptops for students"]
}
```

#### See who advertises on a brand name

A brand name shows who bids on it: the brand's own ads, competitors trying to win its customers, and resellers selling its products. Use it to see who targets your brand, or a competitor's.

```json
{
    "queries": ["nordvpn", "dyson"]
}
```

#### See the ads in another country

```json
{
    "queries": ["best vpn"],
    "country": "GB"
}
```

#### Check that your own ads show up

Use the queries your customers ask and turn on **Save ad proof**. Filter the results by `landingDomain` to find your ads, with a screenshot of each.

```json
{
    "queries": ["dyson"],
    "saveScreenshots": true
}
```

### Output example

You get one dataset item per ad:

```json
{
    "query": "best running shoes",
    "turn": 1,
    "message": "best running shoes",
    "country": "US",
    "chatId": "f02e0a29-ffb8-40ae-b308-d31bb3b6ba48",
    "adId": "f3460e9f3b7cf67a",
    "format": "product",
    "position": 2,
    "advertiser": "Nike.com",
    "adLibraryAdvertiser": "NIKE, INC.",
    "adLibraryPaidBy": "PMG",
    "adLibraryCountry": "US",
    "adLibraryUrl": "https://adlibrary.ads.microsoft.com/advertiser/34001669",
    "title": "Nike Vomero 18 Women's Road Running Shoes In White, Size: 8.5 | HM6804-113",
    "body": null,
    "displayUrl": null,
    "price": 119.97,
    "currency": "USD",
    "priceText": "$119.97",
    "originalPrice": 155,
    "discountPercent": 23,
    "badge": "SALE",
    "extras": [],
    "shipping": "Free shipping",
    "condition": null,
    "rating": 5,
    "reviewCount": 10,
    "reviewsUrl": "https://www.bing.com/product/reviews?upid=NXw4NzI0N35CMEQyQlE4WTda",
    "bingProductId": "5|87247~B0D2BQ8Y7Z",
    "highlights": [],
    "callouts": [],
    "sitelinks": [],
    "cta": null,
    "imageUrl": "https://th.bing.com/th/id/OPHS.eJSoBaDjxm74Ug474C474?pid=21.1",
    "logoUrl": null,
    "url": "https://www.nike.com/t/vomero-18-womens-road-running-shoes-...",
    "landingDomain": "nike.com",
    "trackingParams": { "cp": "27985120320_search_--o-267670120-...", "msclkid": "9cd212b87e5e109825437859c6310c0c" },
    "organicLinks": [
        { "text": "1", "domain": "runnersworld.com", "url": "https://www.runnersworld.com/gear/a19663621/best-running-shoes/" }
    ],
    "screenshotUrls": [
        "https://api.apify.com/v2/key-value-stores/.../records/ad-...-1.png",
        "https://api.apify.com/v2/key-value-stores/.../records/ad-...-1-2.png",
        "https://api.apify.com/v2/key-value-stores/.../records/ad-...-1-3.png"
    ],
    "htmlUrl": "https://api.apify.com/v2/key-value-stores/.../records/ad-...-1.html",
    "scrapedAt": "2026-10-28T10:12:41.221Z"
}
```

`turn` and `message` tell you which message brought the ad. `screenshotUrls` is empty and `htmlUrl` `null` unless **Save ad proof** is on. The carousel scrolls sideways, so a turn takes several screenshots to show every product, and `screenshotUrls` lists them all.

- **`format`**: `product` is a card in the Related Products carousel, with price, crossed-out price, and badge. `text` is a search ad with a headline and copy. `image` is a search ad with a picture and button.
- **`adId`**: the same ad gets the same ID in every chat and run, so count unique ads by `adId`.
- **`landingDomain`**: group by this rather than `advertiser`. The advertiser name doesn't always match the site (a "Bing merchant" product can link to 4camping.cz).
- **`adLibraryAdvertiser`, `adLibraryPaidBy`, `adLibraryCountry`, `adLibraryUrl`**: who's behind the ad, from Microsoft's Ad Library: the advertiser's legal name, who paid for the ad (often an agency, like PMG for Nike), its country, and its Ad Library page.
- **`url`**: the real landing page, decoded from Bing's click link.
- **`rating`, `reviewCount`, `reviewsUrl`**: product ads only. Bing rounds big review counts down ("5K+"), so `reviewCount` is a lower bound for those.
- **`highlights`, `callouts`, `sitelinks`, `logoUrl`**: the extras of a search ad, like "Site visitors: Over 1M in the past month", short selling points, and extra links with their own landing pages and, on some ads, a line of text under them.
- **`imageUrl`**: the full-size image, not the thumbnail Bing shows.
- **`trackingParams`**: the landing page's query params. They often name the advertiser's campaign, like `sem:MICROSOFT:USA|Shopping|Performance Max|Footwear`, so you see campaign types, targeting, and seasonal pushes.
- **`bingProductId`**: Bing's catalog ID for the product, shared by every store selling it. Only for rated products.
- **`organicLinks`**: the links Bing put in the same answer for free, usually the stores and sites it cites. Compare their `domain` with `landingDomain` to see who pays for the spot and who Bing recommends anyway. `null` unless **Include answer links** is on.
- **`chatId`**: ads with the same `chatId` were shown in one chat. Use it with the `CHATS` record to get ads per chat.

You can download the dataset as JSON, CSV, Excel, or HTML, or get it through the Apify API.

#### Summary and chats

Chats without ads aren't in the dataset, so two more records in the **Output** tab show what happened:

- **Summary:** for each query, the chats run, `adRate` (share of chats that showed at least one ad), ads found, and each advertiser's share of voice:

```json
{ "name": "L.L.Bean", "ads": 21, "chats": 4, "shareOfVoice": 1, "avgPosition": 5.6, "minPrice": 99.99, "maxPrice": 280, "currency": "USD" }
```

`shareOfVoice` is the share of chats the advertiser showed up in, so 1 means every time. `avgPosition` is its average slot, 1 = first. Use `adRate` to compare queries and `shareOfVoice` to compare advertisers.

- **Chats:** one line per chat attempt, with how it ended:

| Status | Meaning |
|---|---|
| `done` | Ran the query and all its follow-ups. |
| `no-ads` | No ad on the query (or by turn 3 with follow-ups), so it was stopped. If its query already showed ads, it runs once more in a new browser, charged once. |
| `blocked` | AI Mode didn't load. Retried, not charged. |
| `failed` | Broke mid-chat. Retried, not charged. If it already found ads, they're kept and it isn't retried. |
| `cut` | Stopped because the run timeout was near. |
| `skipped` | Its query had no ads in 4 chats, so it didn't run. Not charged. |

### Tips

- **Pick product topics and brand names.** The Related Products carousel shows for product queries, like "best vpn", "dyson", "best laptops for students".
- **Give it memory for big runs.** The default 8 GB runs 4 chats at once. More memory runs more at once, so many queries or Deep finish sooner. Small Quick runs don't get faster.

### Limitations

- **Logged-out view.** You see the ads Bing shows to logged-out visitors.
- **Ads depend on the topic.** Product queries show ads in almost every chat, but travel, insurance, and most services show few or none. Bing also rotates its ads, so the scraper runs many chats to see them all. Each chat uses proxies and compute, so each one is charged.
- **Residential proxies only.** Bing refuses most datacenter IPs. Chats run through residential proxies in the chosen country, and a refused chat is retried on a new IP.

### Pricing

You pay per event, at the prices on the **Pricing** tab:

| Event | When |
|---|---|
| Ad | Each ad saved to the dataset |
| Chat | Each chat with Bing AI Mode, a small fee that covers running it, also when Bing shows no ads |
| Follow-up | Each follow-up sent, only with **Follow-up queries** |
| Answer links | Each chat, only with **Include answer links** on |

Platform usage and residential proxies are included. You don't pay extra for:

- **Retries.** A chat that gets blocked is run again in a new browser, charged once. So is a chat that shows no ads, once its query has shown ads in another chat.
- **Chats that break.** A chat that breaks after finding ads keeps them, and the chat isn't charged.
- **Topics with no ads.** Once a query has had no ads in 4 chats, its chats that haven't started are skipped and not charged. Chats run several at once, so on Quick most have usually started by then.

Set **Maximum cost per run** to cap a run. It stops there and keeps everything found.

### Related Actors

- **[ChatGPT Ads Scraper](https://apify.com/gytelio1/chatgpt-ads-scraper)**: collects the sponsored ads ChatGPT shows in its answers. Run both to compare who advertises on Copilot and on ChatGPT.

- **[Google AI Overview Ads Scraper](https://apify.com/gytelio1/google-ai-overview-ads-scraper)**: collects the sponsored ads Google shows in its AI Overviews. Run both to compare who advertises on Copilot and on Google.

### Feedback

This scraper is under active development. Found a bug, missing data, or have an idea? Open an issue in the **Issues** tab.

# Changelog

This Actor's version history is a separate document: https://apify.com/gytelio1/bing-copilot-ads-scraper/changelog.md

# Actor input Schema

## `queries` (type: `array`):

See which brands advertise for these queries in Bing AI Mode. A product type, like "best vpn" or "best laptops for students", shows who advertises for it. A brand alone, like "nordvpn" or "dyson", shows who advertises on its name: the brand itself, competitors, and resellers. Products and brands get the most ads; travel and insurance get few.

## `depth` (type: `string`):

How many chats each query gets. Deeper finds more ads and advertisers but costs more. About $0.15 per query for Quick, $0.50 for Standard, and $1.20 for Deep, with typical ads. The number of ads depends on what Bing shows.

## `country` (type: `string`):

Chats run from this country, so you see the ads shown there, in its currency.

## `saveScreenshots` (type: `boolean`):

Save a screenshot of each turn's ads with the message that brought them, and the ads' HTML with every field Bing sent. Proof the ads were shown and what they were shown for. Linked from screenshotUrls and htmlUrl in the results. Adds a few seconds per turn with ads, no extra charge.

## `followUpQueries` (type: `array`):

Optional. Sent in order after each query, the same for every query. Bing shows its ads on the query itself, so follow-ups rarely bring more and make each chat 30-40 seconds longer per follow-up. Each follow-up sent is charged as a Follow-up event. Up to 8.

## `includeOrganicLinks` (type: `boolean`):

Also save the links Bing cited in its answer, to compare who pays for the spot with who Bing recommends anyway. Waits for the whole answer, so each chat takes about twice as long, and is charged an extra Answer links event.

## Actor input object example

```json
{
  "queries": [
    "best vpn",
    "best laptops for students",
    "nordvpn",
    "dyson"
  ],
  "depth": "standard",
  "country": "US",
  "saveScreenshots": false,
  "followUpQueries": [
    "Which one is best for beginners?",
    "Is there a cheaper option?",
    "Where can I buy it at the best price?"
  ],
  "includeOrganicLinks": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing all scraped ads

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

Chats run, ad rate, ads found, and advertisers for each query. Explains a run with no ads.

## `chats` (type: `string`):

One line per chat: query, how it ended (done, no-ads, blocked, failed, cut, skipped), turns, and ads found.

# 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 = {
    "queries": [
        "best vpn"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("gytelio1/bing-copilot-ads-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 = { "queries": ["best vpn"] }

# Run the Actor and wait for it to finish
run = client.actor("gytelio1/bing-copilot-ads-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 '{
  "queries": [
    "best vpn"
  ]
}' |
apify call gytelio1/bing-copilot-ads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gytelio1/bing-copilot-ads-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/v6ccMA9ObRIyHfsEH/builds/itEtIScaUczbeghZ0/openapi.json
