# Google & Bing Rank Tracker — SERP Position Tracking (`memo23/google-rank-tracker`) Actor

Track where your domains rank on Google and Bing for any keywords. Get position, URL, and title for each match. Supports up to 100 results per keyword. JSON or CSV out.

- **URL**: https://apify.com/memo23/google-rank-tracker.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / keyword batch

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google & Bing Rank Tracker — SERP Position Tracking

<p align="center"><img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/rank-tracker-logo.png" width="140" alt="Rank Tracker"></p>

Track where your domains rank on **Google** and **Bing** for any keywords. Get the position, URL, and title for every match — with subdomain matching. Supports up to 100 results per keyword. One row per ranking, clean JSON out.

***

### Why use this rank tracker

- **Google + Bing.** Track rankings on both search engines from one actor. Run "both" to compare.
- **Subdomain matching.** Track `example.com` and it matches `shop.example.com`, `blog.example.com`, and any subdomain automatically.
- **Up to 100 positions.** Scan deep into the SERP — not just the top 10.
- **Full SERP export.** Optionally push every organic result (not just matches) for full SERP analysis.
- **Structured output.** Clean flat rows — keyword, engine, position, domain, URL, title — ready for spreadsheets or databases.

***

### Overview

This actor searches Google and/or Bing for your keywords, parses the organic results, and finds where your target domains rank. Each output row is a single ranking result: the keyword, the search engine, the position, the ranking domain/URL/title, and which target domain it matched.

***

### Use cases

- **SEO rank tracking** — monitor where your site ranks for target keywords over time.
- **Competitor analysis** — track competitor domains alongside your own.
- **SERP auditing** — export full SERPs to see who ranks for any keyword.
- **Multi-engine comparison** — compare Google vs Bing rankings side by side.
- **Local SEO** — use the `location` param to track geo-targeted Google results.

***

### How it works

<p align="center"><img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-rank-tracker.png" width="900" alt="How it works"></p>

1. You provide keywords and target domains.
2. The actor fetches the SERP for each keyword on each search engine.
3. It parses the organic results (position, title, URL, domain).
4. It matches each result against your target domains (with subdomain support).
5. Each match becomes one row in the dataset.

***

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `keywords` | array | — | Keywords to track. One SERP fetch per keyword per engine. |
| `targetDomains` | array | — | Domains to find. `example.com` matches all subdomains. |
| `searchEngine` | string | `google` | `google`, `bing`, or `both`. |
| `maxResults` | integer | 100 | How many organic results to scan per SERP (1-100). |
| `location` | string | `us` | Google country code (`us`, `uk`, `de`, ...). Google only. |
| `onlyMatching` | boolean | true | If false, push all organic results (full SERP export). |
| `proxy` | object | Apify proxy | Residential proxies recommended for Google. |

```json
{
  "keywords": ["coffee shop london", "best coffee nyc"],
  "targetDomains": ["example.com"],
  "searchEngine": "both",
  "maxResults": 50
}
```

***

### Output

One row per ranking result:

```json
{
  "type": "ranking",
  "keyword": "apple iphone",
  "searchEngine": "bing",
  "position": 1,
  "domain": "apple.com",
  "url": "https://www.apple.com/",
  "title": "Apple",
  "targetDomain": "apple.com",
  "isMatch": true,
  "serpUrl": "https://www.bing.com/search?q=apple+iphone&count=100",
  "scrapedAt": "2026-10-03T22:15:00.000Z"
}
```

#### Key output fields

- **`keyword`** — the keyword that was searched.
- **`searchEngine`** — which engine (`google` or `bing`).
- **`position`** — organic rank position (1 = first result).
- **`domain`** — the ranking domain.
- **`url`** — the ranking URL.
- **`title`** — the result title.
- **`targetDomain`** — which of your target domains matched (null if no match).
- **`isMatch`** — whether this result matched a target domain.

***

### FAQ

**Does Google work without residential proxies?**
Google may serve a JS challenge to datacenter IPs. Use Apify's residential proxy pool (the default) for reliable Google results. Bing works with datacenter IPs.

**How does subdomain matching work?**
If you track `example.com`, the actor matches `example.com`, `www.example.com`, `shop.example.com`, `blog.example.com`, and any other subdomain. You don't need to list every subdomain.

**Can I track competitors?**
Yes — pass multiple domains in `targetDomains`. Each result row shows which target domain it matched.

**Can I export the full SERP?**
Yes — set `onlyMatching: false` to push every organic result, not just matches.

**How many keywords can I track?**
As many as you need. The actor fetches one SERP per keyword per engine, with a polite delay between requests.

***

### ⚠️ Disclaimer

This Actor scrapes publicly available search engine results. It does not access authenticated or private content. You are responsible for using the output in line with Google's and Bing's terms of service and any applicable law in your jurisdiction. This Actor is not affiliated with, endorsed by, or sponsored by Google or Bing.

***

### SEO Keywords

rank tracker, serp position tracking, google rank checker, bing rank checker, keyword ranking tracker, seo rank monitor, serp scraper, search engine rank tracker, organic position tracker, keyword position checker, google ranking api, serp position api, rank tracking tool, seo position tracker, domain rank checker, serp monitoring, keyword rank tracker, google serp scraper, bing serp scraper, seo rank reporting

# Actor input Schema

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

Keywords to track rankings for. One SERP fetch per keyword per engine.

## `targetDomains` (type: `array`):

Domains to find in the SERP. e.g. \["example.com"] matches example.com and any subdomain like shop.example.com.

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

Which search engine to query. Google is read up to 'Max results per keyword'; Bing returns its first results page (about 10 results).

## `maxResults` (type: `integer`):

How many Google organic results to scan per keyword (10-100, read 10 per page). Deeper scans cost one more search request per 10 results.

## `location` (type: `string`):

Country code for geo-targeted results (e.g. 'us', 'gb', 'de'). Sets Google's gl and Bing's cc.

## `onlyMatching` (type: `boolean`):

Output only the results from your target domains (plus one 'not ranking' row per domain that did not appear). Turn off to get every organic result.

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

Maximum number of result rows to push.

## `proxy` (type: `object`):

Proxy for Bing requests. Google always goes through Apify's Google SERP proxy, so this setting does not affect it.

## Actor input object example

```json
{
  "keywords": [
    "pizza delivery",
    "best pizza near me"
  ],
  "targetDomains": [
    "dominos.com",
    "pizzahut.com"
  ],
  "searchEngine": "google",
  "maxResults": 100,
  "location": "us",
  "onlyMatching": true,
  "maxItems": 1000,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `results` (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 = {
    "keywords": [
        "pizza delivery",
        "best pizza near me"
    ],
    "targetDomains": [
        "dominos.com",
        "pizzahut.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/google-rank-tracker").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": [
        "pizza delivery",
        "best pizza near me",
    ],
    "targetDomains": [
        "dominos.com",
        "pizzahut.com",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/google-rank-tracker").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 '{
  "keywords": [
    "pizza delivery",
    "best pizza near me"
  ],
  "targetDomains": [
    "dominos.com",
    "pizzahut.com"
  ]
}' |
apify call memo23/google-rank-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/google-rank-tracker"
        }
    }
}
```

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/UvNNc71ZcJegPYYj4/builds/sEyTAGjZm8d9aHEPw/openapi.json
