# Google Keyword Rank Tracker — Serpstat Alternative (`khadinakbar/serpstat-alternative`) Actor

Track current Google keyword rankings and compare target domains in the same SERP. Export positions, top domains, related queries, and source evidence; optionally cluster keywords by shared ranking domains.

- **URL**: https://apify.com/khadinakbar/serpstat-alternative.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** SEO tools, Automation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $40.00 / 1,000 seo observations

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Google Keyword Rank Tracker — Serpstat Alternative

Track current Google keyword rankings and compare target domains in the same SERP. Export positions, top domains, related queries, and source evidence; optionally cluster keywords by shared ranking domains. For search marketers, each dataset row represents one observed keyword, with optional domain ranks and clustering evidence.

### Workflow: put the results to work

Submit the keyword campaign and optional target and competitor domains. Use rank mode for a position snapshot or clustering mode to group terms by shared top-ranking domains. Review the source evidence before assigning clusters to separate content pages.

### Best fit for this Actor

- Start with a bounded keyword campaign when you need a current Google position check for one domain and a few direct competitors.
- Use keyword clustering when a content team needs evidence from shared top-ranking domains instead of a generic keyword list.
- Use the target-domain workflow for an exportable campaign observation, not a persistent SEO project.

For broader SEO data, use the related SEMRush Alternative — Domain Overview, Keywords & Backlinks workflow before this Actor to discover domain metrics, organic keywords, and backlinks.

### When to use this Actor — and when not to

Use this Actor when a current, bounded Google rank observation or a SERP-overlap keyword cluster is the decision you need to make. Do not use it when you need persistent project history, a backlink database, site crawling, paid-keyword research, team workspaces, or an agency reporting dashboard; those jobs are outside this Actor's contract.

### How this workflow compares with Serpstat

This Actor is a focused alternative for the current Google rank-check and SERP-overlap clustering step. It accepts a bounded keyword list and returns structured keyword observations. Serpstat remains the broader choice for persistent projects, historical reporting, backlink analysis, site audits, and team workflows.

| Decision | This Actor | Serpstat | Best fit |
|---|---|---|---|
| Scope | One current rank-and-cluster workflow | Broader SEO platform | Use this Actor for a bounded campaign observation |
| Billing | Pay per persisted observation plus Apify platform usage | Plan tiers with bundled project and position-check allowances | Choose based on your run frequency and workspace needs |
| Effective efficiency | One structured row per processed keyword in a bounded one-off run | Broader dashboard and project workflow | Use this Actor when a machine-readable campaign snapshot is the actual job |
| One-off output | One structured row per processed keyword | Dashboard, export, and applicable API surfaces | Use this Actor for dataset readback in a pipeline |
| Starting point | Keyword list, target domain, location, and device | Ongoing project setup for continuous monitoring | Start here for a discrete current snapshot |
| Freshness | Source search URL and collection time per row | Persistent tracking and history | Choose Serpstat when durable project history is required |

Serpstat is a trademark of its owner. This independent Actor is not affiliated, associated, or endorsed by Serpstat.

### From keyword campaign to a reviewable SEO decision

An SEO operator starts with a campaign's target phrases and a domain. In rank snapshot mode, the Actor checks the same current Google SERP for the target and optional competitors, then returns `targetRank`, `competitorRanks`, `topDomains`, and `sourceUrl`. In keyword clustering mode, the same bounded SERP observations are grouped by shared top domains, giving the operator an evidence-backed first pass at which phrases likely serve a similar search intent.

### Quick start input

```json
{
  "mode": "rank_snapshot",
  "keywords": ["technical seo audit", "seo audit checklist"],
  "targetDomain": "example.com",
  "competitorDomains": ["moz.com", "semrush.com"],
  "locationName": "United States",
  "languageCode": "en",
  "device": "desktop",
  "maxKeywords": 2
}
```

For keyword clustering, supply at least two distinct phrases and switch the mode:

```json
{
  "mode": "keyword_clustering",
  "keywords": ["technical seo audit", "seo audit checklist", "website seo audit"],
  "locationName": "United States",
  "languageCode": "en",
  "device": "desktop",
  "maxKeywords": 3,
  "clusterSimilarityThreshold": 0.3
}
```

### Input reference

| Field | Type | What it controls |
|---|---|---|
| `mode` | enum | Chooses a current `rank_snapshot` or SERP-overlap `keyword_clustering` workflow. |
| `keywords` | string array | Bounded Google phrases; blank and duplicate entries are removed. |
| `targetDomain` | string | Required for rank snapshots and ignored for keyword clustering. |
| `competitorDomains` | string array | Up to five domains compared in the already retrieved SERP. |
| `locationName` / `languageCode` / `device` | string | Fix the geographic, language, and device context of every observation. |
| `maxKeywords` | integer | Caps processed phrases from 1 to 20 and therefore caps the billable observation count. |
| `clusterSimilarityThreshold` | number | Sets the shared-top-domain overlap needed to group phrases in clustering mode. |

### What data you receive

One dataset item is one current Google keyword observation. A target domain can be absent from the inspected top results; in that case, rank fields remain `null` while the row still preserves the SERP evidence.

| Field | Meaning |
|---|---|
| `targetRank`, `targetUrl`, `competitorRanks` | Current domain matches from the same Google result set. |
| `clusterId`, `clusterKeywords`, `maxClusterOverlap` | SERP-overlap cluster evidence in keyword clustering mode. |
| `topDomains`, `relatedQueries`, `peopleAlsoAsk` | Compact intent and competitor context from the observed SERP. |
| `sourceUrl`, `collectedAt` | Source search URL when returned and the time the observation was collected. |
| `warnings` | Non-fatal row notes; terminal outcome details remain in `OUTPUT` and `RUN_SUMMARY`. |

```json
{
  "operation": "rank_snapshot",
  "keyword": "technical seo audit",
  "targetDomain": "example.com",
  "targetFound": true,
  "targetRank": 3,
  "competitorRanks": [
    {
      "domain": "moz.com",
      "rank": 1,
      "url": "https://moz.com/example"
    }
  ],
  "topDomains": ["moz.com", "example.com"],
  "relatedQueries": ["seo audit checklist"],
  "peopleAlsoAsk": ["What is a technical SEO audit?"],
  "sourceUrl": "https://www.google.com/search?q=technical+seo+audit",
  "collectedAt": "2026-09-07T12:00:00.000Z",
  "warnings": []
}
```

### Use through the API

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~serpstat-alternative/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "rank_snapshot",
    "keywords": ["technical seo audit"],
    "targetDomain": "example.com",
    "locationName": "United States",
    "languageCode": "en",
    "device": "desktop",
    "maxKeywords": 1
  }'
```

After the run finishes, read the default dataset for the observations and the `OUTPUT` plus `RUN_SUMMARY` records for the terminal outcome, warning list, and event-count diagnostics.

### Use with AI agents through Apify MCP

> Check `example.com` and two direct competitors for these five SEO campaign keywords in the United States on desktop. Return the current target and competitor ranks, top domains, related queries, source URLs, and collection times. Stop at five observations and report whether the terminal outcome was complete or partial.

Use the current Apify MCP configurator to connect an approved client. This is a read-only data workflow: it starts a bounded run, writes SEO observations to the run dataset, and does not modify Google, Serpstat, or the target domains.

### Best results

- Use a stable campaign keyword list and the same location, language, and device when comparing runs over time.
- Use rank snapshots when the decision is about one target domain; use keyword clustering when the decision is about shared SERP intent across phrases.
- Keep the initial run small, inspect `topDomains` and `relatedQueries`, then expand only the phrases that are useful for the campaign.

### Limitations and recovery

The Actor inspects the first ten current Google organic results returned by its managed provider; it does not calculate historical visibility, crawl a site, or produce a backlink index. A `PARTIAL` outcome means that some useful rows were persisted but a provider failure or spend cap interrupted the rest; retain the dataset, inspect `RUN_SUMMARY`, then retry only the unprocessed keywords. A `VALID_EMPTY` outcome is not an error: it means the provider accepted the input but returned no result items. A `CONFIG_ERROR` indicates that the owner-managed provider account needs attention, while `INVALID_INPUT` tells you what to correct without charging an observation event.

### Evidence and freshness

Each rank observation retains its source context and collection time. Compare only observations with consistent location, language, and device settings; inspect terminal outcomes before treating a campaign snapshot as complete.

### Builder's note

The Actor keeps one dataset row per keyword rather than mixing campaign summaries and error controls into the result set. That makes the rank evidence easy to join, export, and compare, while `OUTPUT` and `RUN_SUMMARY` preserve the provider and cost-cap diagnostics needed for an honest retry decision.

### Responsible use

Use this workflow for public or otherwise authorized search research, and comply with applicable laws, provider terms, and your organization's data-handling policies. Google results can vary by time, location, language, device, and user context; this Actor records the selected context and collection time rather than claiming a universal rank.

### Pricing and run costs

This Actor uses **Pay per event plus Apify platform usage**. The [Pricing tab](https://apify.com/khadinakbar/serpstat-alternative/pricing) lists the current event rates and billing terms.

| Event | Billing unit | When it applies |
|---|---|---|
| `apify-actor-start` | Actor Start | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). |
| `rank-observation` | SEO observation | Charged once for each validated current Google rank snapshot or SERP-overlap keyword observation persisted to the dataset. |

Run cost combines the charged events and Apify platform usage. Review the run charge limit and requested result count before starting.

### Connect an AI agent

Use the [Apify MCP configurator](https://mcp.apify.com) to choose an available client connection. Inspect this Actor’s current input schema and required credentials before running it.

# Actor input Schema

## `mode` (type: `string`):

Choose the SEO workflow to run. Use rank\_snapshot to check one target domain and optional competitors for each keyword, for example a campaign review. Use keyword\_clustering to group two or more phrases by shared top Google domains. This is not a persistent project, backlink lookup, or whole-site crawler.

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

Enter the Google search phrases to observe, for example \["technical seo audit", "seo audit tool"]. Duplicate and blank phrases are removed, then the list is capped by Max keywords. Rank snapshots accept one or more phrases; keyword clustering needs at least two. This is not a list of domains or URLs.

## `targetDomain` (type: `string`):

Enter the domain whose organic Google position should be checked in rank\_snapshot mode, for example example.com. Required only for rank\_snapshot and ignored for keyword\_clustering. Protocols and www are normalized before matching. This is not a Serpstat project URL or a competitor list.

## `competitorDomains` (type: `array`):

Optionally add up to five domains to compare in the same Google SERP, for example \["moz.com", "semrush.com"]. Each domain is matched against the results already collected for the keyword, so it does not add separate provider requests. Ignored for keyword\_clustering. This is not a keyword list or a source of historical rankings.

## `locationName` (type: `string`):

Choose the Google location used for this observation, for example United States, London, England, or Austin, Texas. Defaults to United States and is sent with every keyword in the run. Use a geographic location rather than a domain or an ISO country code. The returned row records the provider-resolved location when available.

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

Use the two-to-five-letter Google language code for the result set, for example en, de, or es. Defaults to en and should match the chosen search location. This is a language code, not a country code or a full language name. Invalid codes return an actionable input outcome.

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

Choose the Google device profile used for each current SERP observation. desktop uses a Windows profile and mobile uses an Android profile. Defaults to desktop for campaign comparability. This is not a request to crawl a mobile website.

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

Set the maximum unique phrases processed from Keywords, from 1 to 20. Defaults to 5 so a first run stays bounded; duplicate phrases do not consume the limit. Each processed phrase can create one billable SEO observation, plus Apify platform usage. This is not a result-depth control.

## `clusterSimilarityThreshold` (type: `number`):

Set the minimum shared-top-domain Jaccard similarity for keyword\_clustering, from 0.1 to 0.9. Defaults to 0.3, which groups phrases with meaningful SERP overlap while leaving distinct intents separate. Ignored for rank\_snapshot. This is not a keyword-difficulty score or a Google ranking threshold.

## Actor input object example

```json
{
  "mode": "rank_snapshot",
  "keywords": [
    "technical seo audit",
    "seo audit checklist"
  ],
  "targetDomain": "example.com",
  "competitorDomains": [
    "moz.com",
    "semrush.com"
  ],
  "locationName": "United States",
  "languageCode": "en",
  "device": "desktop",
  "maxKeywords": 5,
  "clusterSimilarityThreshold": 0.3
}
```

# Actor output Schema

## `results` (type: `string`):

Current rank-snapshot or keyword-cluster rows in the default dataset.

## `output` (type: `string`):

Compact terminal outcome, item count, billable-event count, and warnings.

## `runSummary` (type: `string`):

Detailed provider, cost-cap, input, and terminal diagnostics without credentials.

# 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 = {
    "mode": "rank_snapshot",
    "keywords": [
        "technical seo audit"
    ],
    "targetDomain": "example.com",
    "competitorDomains": [
        "moz.com"
    ],
    "locationName": "United States",
    "languageCode": "en",
    "device": "desktop",
    "maxKeywords": 5,
    "clusterSimilarityThreshold": 0.3
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/serpstat-alternative").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 = {
    "mode": "rank_snapshot",
    "keywords": ["technical seo audit"],
    "targetDomain": "example.com",
    "competitorDomains": ["moz.com"],
    "locationName": "United States",
    "languageCode": "en",
    "device": "desktop",
    "maxKeywords": 5,
    "clusterSimilarityThreshold": 0.3,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/serpstat-alternative").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 '{
  "mode": "rank_snapshot",
  "keywords": [
    "technical seo audit"
  ],
  "targetDomain": "example.com",
  "competitorDomains": [
    "moz.com"
  ],
  "locationName": "United States",
  "languageCode": "en",
  "device": "desktop",
  "maxKeywords": 5,
  "clusterSimilarityThreshold": 0.3
}' |
apify call khadinakbar/serpstat-alternative --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/serpstat-alternative"
        }
    }
}
```

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/SCY2MAP5CoWT6aD7D/builds/eiZiCkPrruHMhDR5w/openapi.json
