# Multi-Engine SERP Scraper — Google, Bing, Yahoo, Yandex, Baidu (`nomad-agent/serp-multi-engine-scraper`) Actor

Multi-engine SERP scraper: Google, Bing, Yahoo, DuckDuckGo, Ecosia, Yandex and Baidu in one run. Built for rank tracking and SERP comparison. Flat JSON row per result: title, URL, snippet, rank, page, engine, total results. Per-engine language/region and pagination. No API keys, no login.

- **URL**: https://apify.com/nomad-agent/serp-multi-engine-scraper.md
- **Developed by:** [Nomad.Dev](https://apify.com/nomad-agent) (community)
- **Categories:** SEO tools, Automation
- **Stats:** 3 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.40 / 1,000 serp results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/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

## SERP Scraper — Google, Bing, Yahoo, DuckDuckGo, Yandex, Baidu, Ecosia

Scrape organic search results from **7 search engines in one run**. Pass your queries, pick engines, get clean structured JSON: title, URL, snippet, rank, page, engine tag and the engine's estimated total-results count per result. Per-engine language/region parameters, native pagination, optional desktop/mobile device targeting, best-effort related-searches extraction on the engines that expose it, and best-effort Yandex AI-answer / entity-card extraction. No API keys, no login, no browser.

Engine parsers ported from the MIT-licensed [openserp](https://github.com/karust/openserp) project (see `NOTICE`).

### What SERP data does this scraper extract?

Each result is one flat JSON record per organic (or ad, if enabled) result:

| Field | Meaning |
|---|---|
| `query` | The search query this result came from |
| `engine` | Engine that returned it: `google`, `bing`, `yahoo`, `duckduckgo`, `ecosia`, `yandex`, `baidu` |
| `rank` | 1-based organic rank within (query, engine), across pages |
| `page` | 1-based SERP page number |
| `title` | Result title as shown on the SERP |
| `url` | Target URL (redirect wrappers unwrapped where possible) |
| `snippet` | Description / snippet text |
| `ad` | `true` when the result is a sponsored/ad slot |
| `serpUrl` | The exact SERP URL that was fetched (for reproducibility) |
| `device` | Device profile used for the request: `desktop` or `mobile` (echoes the `device` input; see [Device targeting](#device-targeting) below) |
| `resultsTotal` | The engine's own estimated total number of matches for the query (e.g. Bing's "About 1,230,000 results"). Best-effort — populated for `google`, `bing`, `baidu`, `yandex` when the SERP shows a count header; `null` for `duckduckgo` / `ecosia` / `yahoo` (no count header) and whenever the header wasn't present |
| `relatedQueries` | Best-effort list of related-search strings found on that SERP page. `[]` when the engine doesn't expose this or the run used `desktop`/`mobile` markup the parser didn't recognize — never guessed/fabricated. Currently populated for Google only; see [Related searches & People Also Ask](#related-searches--people-also-ask) below |
| `answer` | Best-effort text of the engine's AI answer. Only ever populated for `yandex` (its "neuro" answer); `null` on every other engine. Yandex needs residential proxy from datacenter IPs, so it's `null` on unproxied runs |
| `entityCard` | Best-effort Yandex entity/fact card (`{title, description, url}`) — the Wikipedia-style knowledge panel. Only ever populated for `yandex`; `null` elsewhere and when absent |

Every field above is present on every row (flat schema, no nested objects) — this keeps CSV/Excel exports clean.

### How to scrape search engine results with this Actor

1. Click **Try for free** / **Run** — no login to any search engine, no cookies.
2. Enter one or more `queries`, tick the `engines` you want, optionally set `languageCode` / `region` / `maxPagesPerQuery`.
3. Run it and export the dataset as JSON, CSV or Excel, or read it over the [API](https://docs.apify.com/api/v2).

Run it from your own code:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nomad-agent/serp-multi-engine-scraper").call(run_input={
    "queries": ["best python web framework"],
    "engines": ["bing", "duckduckgo", "baidu"],
    "maxPagesPerQuery": 2,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["engine"], item["rank"], item["title"], item["url"])
````

Or a single HTTP call that runs the Actor and returns items in one response:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/nomad-agent~serp-multi-engine-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"queries": ["best python web framework"], "engines": ["bing", "duckduckgo"]}'
```

**Integrations:** export the dataset as JSON, CSV or XLSX from the Console; call it synchronously with [`run-sync-get-dataset-items`](https://docs.apify.com/api/v2#/reference/actor-tasks/run-collection/run-task-synchronously) as shown above; wire it into Make, Zapier or n8n via their Apify connector; or drive it from any AI agent through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp).

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `queries` | array | — | Search queries, one per entry. Inline operators like `site:` and `filetype:` work. **Required.** |
| `engines` | array | `["bing","duckduckgo"]` | Any of `google`, `bing`, `yahoo`, `duckduckgo`, `ecosia`, `yandex`, `baidu`. |
| `device` | string | `"desktop"` | `desktop` or `mobile`. Only changes behavior on Google and Bing — see [Device targeting](#device-targeting). Other engines accept and ignore it. |
| `languageCode` | string | `""` | BCP-47 code (`en`, `de`, `pt-BR`). Mapped per engine: Google `hl/gl/lr`, Bing `mkt/setlang/cc`, DuckDuckGo `kl`, Yandex `lang:` operator, Yahoo `vl`. |
| `region` | string | `""` | Country hint: two-letter code for Google (`gl`) / Bing (`cc`); numeric `lr` id for Yandex (e.g. `213` = Moscow). |
| `maxPagesPerQuery` | integer | `1` | SERP pages per query per engine, via each engine's native offset param. Stops early on empty/blocked pages. Max `10`. |
| `resultsPerPage` | integer | `0` | Results per page where supported (Google `num`, Bing `count`, Baidu `rn`, Yahoo `n`). `0` = engine default. Max `50`. |
| `maxItems` | integer | `100` | Hard cap on total results pushed across all queries and engines. **Each result returned is billed as one dataset item** — see Pricing below. `0` = no cap (costs then scale with queries × engines × pages — use with care). Max `1000`. |
| `includeAds` | boolean | `false` | Include sponsored results (tagged `"ad": true`). |
| `proxyConfiguration` | object | off | Optional. Google/Ecosia/Yandex generally need residential proxy; Bing/DuckDuckGo/Baidu usually work without. |
| `concurrency` | integer | `4` | *(Advanced)* How many searches run at the same time. Higher is faster but more likely to get rate-limited. Extra pages within one search are always fetched one at a time with a short delay, regardless of this setting. Max `8`. |

### Output example

Real `push_data` shape, captured from a live run:

```json
{
  "query": "open source search engine",
  "engine": "duckduckgo",
  "rank": 1,
  "page": 1,
  "title": "Home - OpenSearch",
  "url": "https://opensearch.org/",
  "snippet": "OpenSearch is an open-source search and analytics suite…",
  "ad": false,
  "serpUrl": "https://html.duckduckgo.com/html/?q=open+source+search+engine&kl=us-en",
  "device": "desktop",
  "resultsTotal": null,
  "relatedQueries": [],
  "answer": null,
  "entityCard": null
}
```

`relatedQueries` is only ever non-empty on Google rows (see below) — it's `[]` on every other engine's rows, always, by design (not a bug). `resultsTotal` is `null` on DuckDuckGo/Ecosia (no count header on their endpoints); `answer` and `entityCard` are only ever populated on Yandex rows.

### Pricing

Pay per event: **$0.05 per Actor start** and **$0.004 per result returned**.
100 results ≈ $0.45. No subscription, no rental — you pay only for what you fetch.

### Use cases

- Rank tracking / SEO monitoring across engines, not just Google
- Comparing result overlap between Google, Bing, Yahoo, DuckDuckGo, Yandex, Baidu, Ecosia
- Regional / language SERP snapshots (`languageCode` + `region`)
- Feeding organic results into research, lead-gen or LLM pipelines
- Cheap keyword-to-URL discovery without a paid SERP API

### Engines & reliability

| Engine | Direct (no proxy) | Notes |
|---|---|---|
| Bing | ✅ | HTML first, automatic RSS-output fallback when Bing serves its JS bot-wall |
| DuckDuckGo | ✅ | Uses the JS-free `html.duckduckgo.com` endpoint |
| Baidu | ✅ | Real target URLs taken from the result `mu` attribute where present |
| Yahoo | ✅ | `r.search.yahoo.com` redirect wrappers unwrapped to the real target URL |
| Google | ⚠️ needs residential proxy | Serves a JS interstitial / captcha to datacenter IPs |
| Ecosia | ⚠️ needs residential proxy | Cloudflare Turnstile on datacenter IPs |
| Yandex | ⚠️ needs residential proxy | SmartCaptcha on datacenter IPs; when reachable, best-effort `answer` (AI) and `entityCard` extraction |

Blocked engines are logged and skipped — they never fail the run or charge you for results they didn't return.

### Device targeting

The `device` input (`desktop` / `mobile`) is real, not a cosmetic toggle — but it only does something on the engines that actually respond differently to it:

| Engine | `device: mobile` effect |
|---|---|
| Bing | **Real, verified.** Switches to a mobile browser User-Agent. This also happens to help get past Bing's JS bot-wall page that otherwise blocks datacenter IPs (mobile UA returned real results directly in testing; desktop UA needed the RSS fallback). |
| Google | Switches to a mobile browser User-Agent — the documented way to request Google's mobile SERP. Google blocks this Actor's requests at the interstitial stage from non-residential IPs regardless of device, so the effect on a real (proxied) run isn't independently verified here — use a residential proxy and compare. |
| DuckDuckGo | **No-op.** The `html.duckduckgo.com` endpoint this Actor uses is a single, JS-free layout with no separate mobile version. The field is accepted but ignored. |
| Yahoo / Ecosia / Yandex / Baidu | **No-op.** Not implemented — out of scope for this pass. The field is accepted but ignored; it never causes an error. |

### Related searches & People Also Ask

| Engine | `relatedQueries` | `peopleAlsoAsk` |
|---|---|---|
| Google | Best-effort extraction of the "related searches" links at the bottom of the page. Not independently verified live (Google blocks this Actor's requests before parsing gets that far — see above), built on the structural pattern (internal `/search?q=...` links outside the organic results) that has stayed stable across Google's redesigns. Returns `[]`, never errors, if the page layout doesn't match. | **Not implemented.** Google's "People also ask" box is populated by JavaScript after the page loads; a plain HTTP request (what this Actor uses) never receives it. |
| Bing | **Not implemented.** Verified live: Bing's related-searches/PAA widgets are lazy-loaded via JavaScript after the initial response — the static HTML this Actor fetches only ever contains the organic results. | **Not implemented** — same reason. |
| DuckDuckGo | **Not implemented.** The JS-free `html.duckduckgo.com` endpoint never renders a related-searches section — that's a `duckduckgo.com` JS-app-only feature. | **Not implemented** — same reason (no PAA on the JS-free endpoint). |
| Yahoo | **Not implemented.** Yahoo's "Also Try" / related widgets are JavaScript-lazy-loaded like Bing's — absent from the static HTML this Actor fetches. | **Not implemented** — same reason. |
| Ecosia / Yandex / Baidu | **Not implemented** — out of scope for this pass. Yandex `answer` (AI) and `entityCard` are extracted separately, see the [output fields](#what-serp-data-does-this-scraper-extract). | **Not implemented** — out of scope for this pass. |

`peopleAlsoAsk` is intentionally not a dataset field: since it isn't populated on any engine, adding it would just be a permanently-empty column. `relatedQueries` is a real field (`[]` by default, populated on Google when the block is present).

### FAQ

**Is it legal to scrape search engine results?**
This Actor reads only publicly available SERP data — what any visitor sees without logging in. No personal data behind authentication is touched. Review the target engines' terms and your local regulations for your specific use case.

**Do I need an account or API key?**
No. Results are fetched from public SERP pages — no login, no API keys, no cookies.

**Why does Google return no results?**
Google (and Ecosia, Yandex) aggressively challenge datacenter IPs. Enable Apify **residential** proxy in `proxyConfiguration`. Bing, DuckDuckGo, Baidu and Yahoo normally work without any proxy.

**How many results can I get?**
Up to `maxPagesPerQuery` pages per engine per query (~10 results/page, ~25 for DuckDuckGo), capped by `maxItems` (default `100`, max `1000`). Each result is billed as one dataset item — see Pricing above.

**Are ads included?**
Only when `includeAds` is on; ad rows are tagged `"ad": true` and never consume organic ranks.

**Can I get mobile search results?**
Yes for Bing (and best-effort for Google): set `device` to `mobile`. It's a no-op on Yahoo, DuckDuckGo, Ecosia, Yandex and Baidu — see [Device targeting](#device-targeting).

**Does this Actor extract related searches or People Also Ask?**
`relatedQueries` is populated on Google rows on a best-effort basis. `peopleAlsoAsk` isn't implemented on any engine — it's rendered by JavaScript after the page loads, which a plain HTTP fetch (what this Actor uses) never receives. See [Related searches & People Also Ask](#related-searches--people-also-ask).

**Something broken or missing?**
Search engines change their markup often. Open an issue on the Actor's **Issues** tab — it is monitored and reliability fixes ship fast.

### Attribution

SERP URL construction and CSS selectors are a Python port of [openserp](https://github.com/karust/openserp) by Rustem Kamalov, MIT License. See `LICENSE` and `NOTICE`.

### Related Actors

- [AI Job Search Agent — Web Job Finder (BYOK)](https://apify.com/nomad-agent/web-search-scraper)
- [LinkedIn Jobs Scraper — No Login, No Cookies](https://apify.com/nomad-agent/linkedin-scraper)
- [Hacker News Who's Hiring Scraper](https://apify.com/nomad-agent/hackernews-scraper)

# Actor input Schema

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

Search queries to run, one per entry. Search operators like site: and filetype: work inline (e.g. <code>annual report filetype:pdf site:example.com</code>).

## `engines` (type: `array`):

Engines to query. Each result row is tagged with its engine. Bing, DuckDuckGo, Baidu and Yahoo are the most reliable from datacenter IPs; Google, Ecosia and Yandex may serve captchas without residential proxies (blocked engines are logged and skipped, never fail the run).

## `device` (type: `string`):

Search as a desktop or mobile browser. Only Google and Bing actually change their response based on this (Bing: a mobile signal also helps avoid its bot-block page). Other engines accept the field but ignore it — see the <code>Device support</code> table in the README.

## `languageCode` (type: `string`):

BCP-47 language code, e.g. <code>en</code>, <code>de</code>, <code>pt-BR</code>. Mapped per engine: Google hl/gl/lr, Bing mkt/setlang/cc, DuckDuckGo kl, Yandex lang: operator, Yahoo vl. Baidu and Ecosia do not take a language param.

## `region` (type: `string`):

Country hint. Two-letter code for Google (gl) and Bing (cc), e.g. <code>de</code>, <code>gb</code>. For Yandex pass a numeric lr region id (e.g. 213 = Moscow). Ignored by engines without a region param.

## `maxPagesPerQuery` (type: `integer`):

SERP pages to fetch per query per engine. Pagination uses each engine's native offset param (Google start, Bing first, DuckDuckGo s, Ecosia p, Yandex p, Baidu pn, Yahoo b). Stops early when a page is empty or blocked.

## `resultsPerPage` (type: `integer`):

Results requested per page where the engine supports it (Google num, Bing count, Baidu rn, Yahoo n). 0 = engine default (~10, DuckDuckGo ~25).

## `maxItems` (type: `integer`):

Hard cap on total results pushed across all queries and engines. Each result returned is billed as one dataset item — see Pricing in the README. 0 = no cap (costs then scale with queries × engines × pages; use with care).

## `includeAds` (type: `boolean`):

Include sponsored/ad results (marked with <code>ad</code>: true). Off = organic results only.

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

Optional proxy. Bing, DuckDuckGo, Baidu and Yahoo usually work without one. Google, Ecosia and Yandex serve captchas to datacenter IPs — use Apify residential proxy to unlock them.

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

How many searches to run at the same time. Higher is faster but more likely to get rate-limited or blocked by a search engine. Extra pages within a single search are always fetched one at a time with a short delay between them, regardless of this setting.

## Actor input object example

```json
{
  "queries": [
    "best python web framework",
    "rust async runtime comparison"
  ],
  "engines": [
    "bing",
    "duckduckgo"
  ],
  "device": "desktop",
  "languageCode": "en",
  "region": "de",
  "maxPagesPerQuery": 1,
  "resultsPerPage": 0,
  "maxItems": 100,
  "includeAds": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "concurrency": 4
}
```

# Actor output Schema

## `dataset` (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 = {
    "queries": [
        "open source search engine"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nomad-agent/serp-multi-engine-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": ["open source search engine"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("nomad-agent/serp-multi-engine-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 '{
  "queries": [
    "open source search engine"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call nomad-agent/serp-multi-engine-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nomad-agent/serp-multi-engine-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Multi-Engine SERP Scraper — Google, Bing, Yahoo, Yandex, Baidu",
        "description": "Multi-engine SERP scraper: Google, Bing, Yahoo, DuckDuckGo, Ecosia, Yandex and Baidu in one run. Built for rank tracking and SERP comparison. Flat JSON row per result: title, URL, snippet, rank, page, engine, total results. Per-engine language/region and pagination. No API keys, no login.",
        "version": "0.1",
        "x-build-id": "76TqPrhVHZwaKKbN9"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/nomad-agent~serp-multi-engine-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-nomad-agent-serp-multi-engine-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/nomad-agent~serp-multi-engine-scraper/runs": {
            "post": {
                "operationId": "runs-sync-nomad-agent-serp-multi-engine-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/nomad-agent~serp-multi-engine-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-nomad-agent-serp-multi-engine-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": [
                    "queries"
                ],
                "properties": {
                    "queries": {
                        "title": "Search queries",
                        "type": "array",
                        "description": "Search queries to run, one per entry. Search operators like site: and filetype: work inline (e.g. <code>annual report filetype:pdf site:example.com</code>).",
                        "items": {
                            "type": "string"
                        }
                    },
                    "engines": {
                        "title": "Search engines",
                        "type": "array",
                        "description": "Engines to query. Each result row is tagged with its engine. Bing, DuckDuckGo, Baidu and Yahoo are the most reliable from datacenter IPs; Google, Ecosia and Yandex may serve captchas without residential proxies (blocked engines are logged and skipped, never fail the run).",
                        "items": {
                            "type": "string",
                            "enum": [
                                "google",
                                "bing",
                                "yahoo",
                                "duckduckgo",
                                "ecosia",
                                "yandex",
                                "baidu"
                            ],
                            "enumTitles": [
                                "Google",
                                "Bing",
                                "Yahoo",
                                "DuckDuckGo",
                                "Ecosia",
                                "Yandex",
                                "Baidu"
                            ]
                        },
                        "default": [
                            "bing",
                            "duckduckgo"
                        ]
                    },
                    "device": {
                        "title": "Device",
                        "enum": [
                            "desktop",
                            "mobile"
                        ],
                        "type": "string",
                        "description": "Search as a desktop or mobile browser. Only Google and Bing actually change their response based on this (Bing: a mobile signal also helps avoid its bot-block page). Other engines accept the field but ignore it — see the <code>Device support</code> table in the README.",
                        "default": "desktop"
                    },
                    "languageCode": {
                        "title": "Language code",
                        "type": "string",
                        "description": "BCP-47 language code, e.g. <code>en</code>, <code>de</code>, <code>pt-BR</code>. Mapped per engine: Google hl/gl/lr, Bing mkt/setlang/cc, DuckDuckGo kl, Yandex lang: operator, Yahoo vl. Baidu and Ecosia do not take a language param."
                    },
                    "region": {
                        "title": "Region / country",
                        "type": "string",
                        "description": "Country hint. Two-letter code for Google (gl) and Bing (cc), e.g. <code>de</code>, <code>gb</code>. For Yandex pass a numeric lr region id (e.g. 213 = Moscow). Ignored by engines without a region param."
                    },
                    "maxPagesPerQuery": {
                        "title": "Max pages per query",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "SERP pages to fetch per query per engine. Pagination uses each engine's native offset param (Google start, Bing first, DuckDuckGo s, Ecosia p, Yandex p, Baidu pn, Yahoo b). Stops early when a page is empty or blocked.",
                        "default": 1
                    },
                    "resultsPerPage": {
                        "title": "Results per page",
                        "minimum": 0,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Results requested per page where the engine supports it (Google num, Bing count, Baidu rn, Yahoo n). 0 = engine default (~10, DuckDuckGo ~25).",
                        "default": 0
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Hard cap on total results pushed across all queries and engines. Each result returned is billed as one dataset item — see Pricing in the README. 0 = no cap (costs then scale with queries × engines × pages; use with care).",
                        "default": 100
                    },
                    "includeAds": {
                        "title": "Include ads",
                        "type": "boolean",
                        "description": "Include sponsored/ad results (marked with <code>ad</code>: true). Off = organic results only.",
                        "default": false
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional proxy. Bing, DuckDuckGo, Baidu and Yahoo usually work without one. Google, Ecosia and Yandex serve captchas to datacenter IPs — use Apify residential proxy to unlock them."
                    },
                    "concurrency": {
                        "title": "Concurrency",
                        "minimum": 1,
                        "maximum": 8,
                        "type": "integer",
                        "description": "How many searches to run at the same time. Higher is faster but more likely to get rate-limited or blocked by a search engine. Extra pages within a single search are always fetched one at a time with a short delay between them, regardless of this setting.",
                        "default": 4
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
