# SERP Rank Tracker Lite (`nexgendata/serp-rank-tracker-lite`) Actor

Track Google, Bing, and DuckDuckGo rankings for any keyword/domain with native AI Overview detection. Pay-per-keyword alternative to Ahrefs, SEMrush, and SE Ranking for SEO freelancers and agencies.

- **URL**: https://apify.com/nexgendata/serp-rank-tracker-lite.md
- **Developed by:** [Stephan Corbeil](https://apify.com/nexgendata) (community)
- **Categories:** SEO tools, Marketing, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.00 / 1,000 keyword rank checkeds

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

## SERP Rank Tracker Lite — with native AI Overview detection

**Track Google, Bing, and DuckDuckGo rankings for any keyword/domain with the one thing Ahrefs and SEMrush still get wrong: clean, native AI Overview (AIO) detection.**

Built for SEO freelancers, in-house content marketers, and small-to-mid agencies who want pay-as-you-go SERP tracking without the $59-$139/month subscriptions — and who refuse to fly blind on the SERP feature that now eats 30-50% of informational query clicks.

> Pay only for what you track. No seats. No monthly minimum. Around **$0.012 per keyword check** — roughly **5x to 25x cheaper** than Ahrefs Webmaster, SEMrush, or SE Ranking at equivalent volumes.

---

### Why AI Overview detection matters in 2026

Google's AI Overview (formerly SGE) now triggers on a substantial portion of informational queries — internal SEO industry tracking puts the figure between **30% and 50%** depending on vertical, with health, finance, and how-to content seeing the highest rates.

**This breaks classic rank tracking in three ways:**

1. **Position #1 organic no longer means top-of-fold.** When an AIO box renders, the first blue link gets pushed below 600-800px of generated answer + citations. Your "rank #1" report to the client looks great while their click-through halves.
2. **AIO citations are a separate optimization target.** Being cited inside the AIO is increasingly more valuable than ranking #1 below it. You need to track *citation presence*, not just rank.
3. **AIO triggers are volatile.** A keyword that triggered AIO last week may not today. Without continuous AIO tracking, you can't tell whether a CTR drop is your fault or the SERP's.

Most incumbents — Ahrefs, SEMrush, SE Ranking, Serpstat — added AIO detection late, mark it inconsistently, or hide it behind premium tiers. **This actor surfaces AIO presence, the summary text, and the citation count on every Google check, included in the base per-keyword price.** When detection is genuinely ambiguous, we return `null` rather than guessing `false` — so your reports stay honest.

---

### Use cases

1. **SEO freelancer client reporting.** Track 50-200 keywords per client on a weekly cron. Generate a CSV that shows rank, AIO presence, and competitor delta. No per-seat license fees per client.
2. **Marketing agency portfolio tracking.** Run nightly for every account, dump to BigQuery / Snowflake / S3 via Apify integrations. Pay only for keywords actually checked — no waste on inactive accounts.
3. **Content marketer competitive analysis.** Pull top-10 competitors for every target keyword. Spot which domains are eating your category and which pages are getting AIO-cited.
4. **Brand monitor for new content rollouts.** Drop in your domain + 20 target queries the day a new landing page ships. Re-run weekly. Watch rank climb (or not).
5. **AIO-citation tracking.** Pull the AIO summary + citation count on every check. If your domain disappears from the citations, you'll see it in the diff.
6. **Localized SERP tracking.** Same keyword set across `us`, `gb`, `de`, `ca`, `au`, etc. — no extra per-market license.
7. **Mobile vs desktop SERP delta.** Run the same keyword twice with `device: "desktop"` then `device: "mobile"`. Different AIO trigger rates, different competitors, different opportunities.

---

### How it works

1. **You submit** a list of keywords + your target domain + an engine choice.
2. **For Google**, we invoke Apify's official `apify/google-search-scraper` as an upstream actor. That actor handles all the rendering, anti-bot, and proxy heavy-lifting at Google. We parse its JSON output.
3. **For Bing and DuckDuckGo**, we scrape HTML directly through Apify residential proxy (BUYPROXIES94952) using `httpx` + `BeautifulSoup`. Bing and DDG are both permissive and stable; this is the cheap path.
4. **We parse** organic results, extract your domain's rank (1-100 or `null`), pull the top 10 competitors, detect featured snippets, scan for AI Overview presence, and pull People-Also-Ask + related searches when available.
5. **We emit** one structured dataset item per keyword with all the fields below. Stream them to your warehouse, your spreadsheet, or your dashboard.

We **never** hit Google directly — it's expensive, unreliable, and against Google's ToS. Bright Data is not used. Everything runs inside Apify's compliance perimeter.

---

### Input schema

| Field | Type | Default | Notes |
|---|---|---|---|
| `keywords` | array of strings | required | Max 100 keywords per run |
| `domain` | string | required | Without protocol. Example: `thenextgennexus.com` |
| `searchEngine` | enum | `google` | `google` \| `bing` \| `duckduckgo` |
| `country` | string | `us` | ISO 2-letter country code |
| `language` | string | `en` | 2-letter language code |
| `device` | enum | `desktop` | `desktop` \| `mobile` |
| `includeCompetitors` | boolean | `true` | Emit top-10 organic per keyword |
| `detectAIOverview` | boolean | `true` | Google only; ignored elsewhere |
| `maxKeywords` | integer | `100` | Hard safety cap (1-100) |

#### Minimal input

```json
{
  "keywords": ["best crm 2026", "ai writing tools"],
  "domain": "salesforce.com"
}
````

#### Full input

```json
{
  "keywords": ["best crm 2026", "ai writing tools", "headless cms 2026"],
  "domain": "salesforce.com",
  "searchEngine": "google",
  "country": "us",
  "language": "en",
  "device": "desktop",
  "includeCompetitors": true,
  "detectAIOverview": true,
  "maxKeywords": 100
}
```

***

### Output schema

Each dataset item:

| Field | Type | Description |
|---|---|---|
| `keyword` | string | Echo of the input keyword |
| `searchEngine` | string | `google` / `bing` / `duckduckgo` |
| `country` | string | ISO code |
| `language` | string | Language code |
| `device` | string | `desktop` / `mobile` |
| `domainRank` | int | null | Rank position 1-100, or `null` if not in top 100 |
| `domainUrl` | string | null | The matching URL on your domain, if found |
| `domainSnippet` | string | null | Search snippet preview for that URL |
| `hasAIOverview` | bool | null | Google only. `null` = ambiguous, don't guess |
| `aiOverviewSummary` | string | null | First ≤500 chars of AIO body text |
| `aiOverviewSourcesCount` | int | Number of citation chips in the AIO box |
| `featuredSnippet` | object | `{present, url, text}` |
| `peopleAlsoAsk` | array | Up to 10 PAA question strings |
| `relatedSearches` | array | Related query strings |
| `topCompetitors` | array | Top-10 organic, each `{rank, url, title, snippet, domain}` |
| `searchedAt` | ISO string | UTC timestamp |
| `error` | string | (Optional) Set only if fetch failed |

#### Sample item

```json
{
  "keyword": "best crm 2026",
  "searchEngine": "google",
  "country": "us",
  "language": "en",
  "device": "desktop",
  "domainRank": 4,
  "domainUrl": "https://www.salesforce.com/crm/",
  "domainSnippet": "Salesforce CRM helps sales teams close more deals…",
  "hasAIOverview": true,
  "aiOverviewSummary": "The best CRM in 2026 depends on company size and industry. For SMBs, HubSpot and Pipedrive offer strong free tiers…",
  "aiOverviewSourcesCount": 7,
  "featuredSnippet": {"present": false, "url": null, "text": null},
  "peopleAlsoAsk": [
    "What is the best CRM for small business?",
    "Is Salesforce worth it in 2026?"
  ],
  "relatedSearches": ["best free crm", "salesforce vs hubspot 2026"],
  "topCompetitors": [
    {"rank": 1, "url": "https://www.hubspot.com/products/crm", "title": "HubSpot CRM — Free…", "snippet": "…", "domain": "hubspot.com"},
    {"rank": 2, "url": "https://pipedrive.com/", "title": "Pipedrive…", "snippet": "…", "domain": "pipedrive.com"}
  ],
  "searchedAt": "2026-05-16T12:34:56Z"
}
```

***

### More JSON examples

#### Single-keyword smoke (Bing, no AIO)

```json
{
  "keywords": ["best crm 2026"],
  "domain": "salesforce.com",
  "searchEngine": "bing",
  "maxKeywords": 1
}
```

#### Batch (50 keywords, Google US desktop)

```json
{
  "keywords": ["keyword 1", "keyword 2", "...50 total"],
  "domain": "thenextgennexus.com",
  "searchEngine": "google",
  "country": "us",
  "device": "desktop",
  "detectAIOverview": true
}
```

#### Mobile vs desktop diff (run twice, same keywords)

```json
{
  "keywords": ["how to lose weight", "best mortgage rates"],
  "domain": "nerdwallet.com",
  "searchEngine": "google",
  "device": "mobile"
}
```

***

### Calling from your code

#### Python (Apify SDK)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("nexgendata/serp-rank-tracker-lite").call(run_input={
    "keywords": ["best crm 2026", "ai writing tools"],
    "domain": "salesforce.com",
    "searchEngine": "google",
    "detectAIOverview": True
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["keyword"], item["domainRank"], item["hasAIOverview"])
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/nexgendata~serp-rank-tracker-lite/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["best crm 2026"],
    "domain": "salesforce.com",
    "searchEngine": "google"
  }'
```

***

### FAQ

**1. How accurate is AI Overview detection?**
For Google queries via the upstream actor we use a defensive multi-field detection chain (current and legacy field names from `apify/google-search-scraper`) plus a fallback marker scan. When detection is genuinely ambiguous, `hasAIOverview` is `null` — we never guess `false`. Bing and DDG do not have AIO; the field is always `null` there.

**2. Why is `domainRank` sometimes `null`?**
Either (a) your domain is not in the top 100 results, (b) the SERP didn't return that many organic results, or (c) the upstream call failed and an `error` field is set on the item. Check `error` first.

**3. Does mobile actually give different results?**
Yes. Mobile SERPs have different AIO trigger rates (typically higher), different ad density, and often re-ordered organic results. For client reporting, run both.

**4. Which countries and languages do you support?**
Any ISO country code and 2-letter language code that the upstream scrapers accept. Google: ~190 countries via the upstream actor. Bing: most major markets. DuckDuckGo: region pairs like `us-en`, `de-de`.

**5. How often should I re-track?**
Weekly is the sweet spot for most agencies. Daily makes sense for high-volatility verticals (news, finance, e-commerce launches). With pay-per-keyword pricing, you decide.

**6. Why are you so much cheaper than Ahrefs / SEMrush?**
Three reasons: (1) you only pay for keywords you actually check, not a flat seat license; (2) we don't run a UI, dashboards, link index, or content team — just the SERP fetch; (3) we use Apify's existing compliance + proxy infrastructure so we don't carry that overhead.

**7. Do you scrape Google directly?**
No. We invoke Apify's official `apify/google-search-scraper` as an upstream actor — that actor handles all the rendering and anti-bot work inside Apify's compliance perimeter. We never bypass Google's protections.

**8. What if I need >100 keywords per run?**
Split into multiple runs or use the Apify scheduler to fan out batches. The 100-keyword cap is a safety guard against accidental cost blow-ups.

***

### Comparison vs incumbents

| | **SERP Rank Tracker Lite** | Ahrefs Webmaster | SEMrush | SE Ranking | Serpstat | AccuRanker |
|---|---|---|---|---|---|---|
| Monthly cost | **Pay-per-keyword** (~$0.012/check) | $7-$29/mo | $139/mo+ | $55/mo | $59/mo | $129/mo+ |
| Keywords included | **Unlimited** (you pay per check) | 10-100 | 500 | 250 | 500 | 1,000 |
| AIO detection | **Native, free, on every check** | Limited / lagging | Premium tier | Limited | Limited | Yes, premium |
| Mobile vs Desktop | **Yes** | Yes | Yes | Yes | Limited | Yes |
| Country coverage | **~190 (via upstream)** | ~170 | ~150 | ~190 | ~230 | ~170 |
| Top-10 competitor extraction | **Yes, every check** | Yes | Yes | Yes | Yes | Yes |
| Direct API / programmatic | **Yes, Apify API** | API in higher tiers | Yes (paid add-on) | Yes | Yes | Yes |
| Monthly commitment | **None** | Required | Required | Required | Required | Required |
| Multi-engine (Bing, DDG) | **Yes, all three** | Google only | Google primarily | Google + Yahoo | Google + Yandex | Google + Bing |
| Cost at 50 kw / week | **~$2.40/mo** | $7-$29/mo | $139/mo | $55/mo | $59/mo | $129/mo |
| Cost at 500 kw / week | **~$24/mo** | n/a (tier cap) | $139/mo (cap) | $55-99/mo | $59/mo | $129/mo |

**The break-even.** If you track fewer than ~2,400 keyword-checks per month (which covers most freelancers and a lot of agencies), this actor is dramatically cheaper. Above that, dedicated platforms with bundled link/content data may make sense — but you'll still want this for AIO sanity checks.

***

### Sister actors from NexGenData

Build a full SEO + analytics stack on Apify, no monthly subscriptions:

- **[nexgendata/google-cse-replacement](https://apify.com/nexgendata/google-cse-replacement)** — Programmable search results across the open web. Drop-in replacement for Google Custom Search.
- **[nexgendata/wappalyzer-replacement](https://apify.com/nexgendata/wappalyzer-replacement)** — Tech-stack fingerprinting for any URL. CRMs, analytics tools, frameworks, hosting.
- **[nexgendata/page-speed-analyzer](https://apify.com/nexgendata/page-speed-analyzer)** — Core Web Vitals + Lighthouse signals for any URL. Track competitor page speed.
- **[nexgendata/tranco-rank-lookup](https://apify.com/nexgendata/tranco-rank-lookup)** — Lookup any domain's Tranco global rank. Useful for filtering competitor lists.
- **[nexgendata/company-tech-stack-detector](https://apify.com/nexgendata/company-tech-stack-detector)** — Crawl a company domain and emit the full tech stack + vendor footprint.

***

### Pricing detail

| Event | Price | When |
|---|---|---|
| Run start | $0.02 | Once per run, covers init + aggregation |
| Keyword tracked | **$0.012** | Per keyword — SERP fetch, rank lookup, competitor extract, AIO detect |
| AI Overview detected | +$0.005 | Bonus only when AIO is genuinely present and parsed with sources |

**Example bills:**

- 50 keywords, 1 run, 10 trigger AIO: $0.02 + (50 × $0.012) + (10 × $0.005) = **$0.67**
- 200 keywords weekly = ~$10/month all-in for a freelancer's full client list

***

### Don't have an Apify account?

**[Sign up free](https://www.apify.com/sign-up?fpr=2ayu9b)** — $5 free credits to test. No card required.

# Actor input Schema

## `keywords` (type: `array`):

Keywords to track (max 100 per run). Each keyword consumes one billable event.

## `domain` (type: `string`):

Domain to look up in the SERP (without protocol, e.g. 'thenextgennexus.com'). Returns rank position if found in top 100 results.

## `searchEngine` (type: `string`):

Which engine to query. Google uses Apify's google-search-scraper upstream (paid). Bing & DuckDuckGo are scraped directly via Apify proxy (cheaper).

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

Two-letter ISO country code for localized results (e.g. 'us', 'gb', 'de', 'ca').

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

Two-letter language code (e.g. 'en', 'fr', 'de', 'es').

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

Device profile to emulate. Mobile SERPs differ significantly from desktop, including AIO trigger rates.

## `includeCompetitors` (type: `boolean`):

Emit the top-10 organic results per keyword for competitive analysis.

## `detectAIOverview` (type: `boolean`):

Detect Google AI Overview presence, extract summary text, and count citation sources. Google only — Bing and DuckDuckGo skip this step.

## `maxKeywords` (type: `integer`):

Hard cap on number of keywords processed in this run. Useful for cost control when feeding large lists from another actor.

## Actor input object example

```json
{
  "keywords": [
    "best crm software 2026",
    "ai writing tools"
  ],
  "domain": "salesforce.com",
  "searchEngine": "google",
  "country": "us",
  "language": "en",
  "device": "desktop",
  "includeCompetitors": true,
  "detectAIOverview": true,
  "maxKeywords": 100
}
```

# 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 = {
    "keywords": [
        "best crm software 2026",
        "ai writing tools"
    ],
    "domain": "salesforce.com",
    "searchEngine": "google",
    "country": "us",
    "language": "en",
    "device": "desktop",
    "includeCompetitors": true,
    "detectAIOverview": true,
    "maxKeywords": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgendata/serp-rank-tracker-lite").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 = {
    "keywords": [
        "best crm software 2026",
        "ai writing tools",
    ],
    "domain": "salesforce.com",
    "searchEngine": "google",
    "country": "us",
    "language": "en",
    "device": "desktop",
    "includeCompetitors": True,
    "detectAIOverview": True,
    "maxKeywords": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("nexgendata/serp-rank-tracker-lite").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 '{
  "keywords": [
    "best crm software 2026",
    "ai writing tools"
  ],
  "domain": "salesforce.com",
  "searchEngine": "google",
  "country": "us",
  "language": "en",
  "device": "desktop",
  "includeCompetitors": true,
  "detectAIOverview": true,
  "maxKeywords": 100
}' |
apify call nexgendata/serp-rank-tracker-lite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nexgendata/serp-rank-tracker-lite",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "SERP Rank Tracker Lite",
        "description": "Track Google, Bing, and DuckDuckGo rankings for any keyword/domain with native AI Overview detection. Pay-per-keyword alternative to Ahrefs, SEMrush, and SE Ranking for SEO freelancers and agencies.",
        "version": "0.0",
        "x-build-id": "7d4fW3FnXRGR0Zf5O"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/nexgendata~serp-rank-tracker-lite/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-nexgendata-serp-rank-tracker-lite",
                "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/nexgendata~serp-rank-tracker-lite/runs": {
            "post": {
                "operationId": "runs-sync-nexgendata-serp-rank-tracker-lite",
                "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/nexgendata~serp-rank-tracker-lite/run-sync": {
            "post": {
                "operationId": "run-sync-nexgendata-serp-rank-tracker-lite",
                "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": [
                    "keywords",
                    "domain"
                ],
                "properties": {
                    "keywords": {
                        "title": "Keywords",
                        "minItems": 1,
                        "maxItems": 100,
                        "type": "array",
                        "description": "Keywords to track (max 100 per run). Each keyword consumes one billable event.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "domain": {
                        "title": "Target domain",
                        "type": "string",
                        "description": "Domain to look up in the SERP (without protocol, e.g. 'thenextgennexus.com'). Returns rank position if found in top 100 results."
                    },
                    "searchEngine": {
                        "title": "Search engine",
                        "enum": [
                            "google",
                            "bing",
                            "duckduckgo"
                        ],
                        "type": "string",
                        "description": "Which engine to query. Google uses Apify's google-search-scraper upstream (paid). Bing & DuckDuckGo are scraped directly via Apify proxy (cheaper).",
                        "default": "google"
                    },
                    "country": {
                        "title": "Country (ISO code)",
                        "type": "string",
                        "description": "Two-letter ISO country code for localized results (e.g. 'us', 'gb', 'de', 'ca').",
                        "default": "us"
                    },
                    "language": {
                        "title": "Language",
                        "type": "string",
                        "description": "Two-letter language code (e.g. 'en', 'fr', 'de', 'es').",
                        "default": "en"
                    },
                    "device": {
                        "title": "Device",
                        "enum": [
                            "desktop",
                            "mobile"
                        ],
                        "type": "string",
                        "description": "Device profile to emulate. Mobile SERPs differ significantly from desktop, including AIO trigger rates.",
                        "default": "desktop"
                    },
                    "includeCompetitors": {
                        "title": "Include top-10 competitors",
                        "type": "boolean",
                        "description": "Emit the top-10 organic results per keyword for competitive analysis.",
                        "default": true
                    },
                    "detectAIOverview": {
                        "title": "Detect AI Overview (Google only)",
                        "type": "boolean",
                        "description": "Detect Google AI Overview presence, extract summary text, and count citation sources. Google only — Bing and DuckDuckGo skip this step.",
                        "default": true
                    },
                    "maxKeywords": {
                        "title": "Max keywords (safety cap)",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Hard cap on number of keywords processed in this run. Useful for cost control when feeding large lists from another actor.",
                        "default": 100
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
