# Amazon Keyword Rank Tracker - ASIN & Brand Search Rank (`steadyscrape/amazon-keyword-rank-tracker`) Actor

Amazon keyword rank tracker: where your ASINs (or a brand) rank in Amazon search for each keyword: organic rank, page and position, results count, top competitors above you, and sponsored (ad) rank when Amazon shows ads. 21 marketplaces, no login. Export rank data to CSV, JSON or Excel, or via API.

- **URL**: https://apify.com/steadyscrape/amazon-keyword-rank-tracker.md
- **Developed by:** [Steady Scrape](https://apify.com/steadyscrape) (community)
- **Categories:** E-commerce, SEO tools, Marketing
- **Stats:** 3 total users, 2 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 keyword checks

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

## Amazon Keyword Rank Tracker

**Amazon keyword rank tracker** for sellers, brands and agencies: give it your **ASINs** (or a **brand**) and your **keywords**, and it tells you where each product ranks in Amazon search for each keyword: **organic rank**, the page and the position a shopper scrolls to, how many results the keyword has, the **top competitors** ranked above you, and the **sponsored (ad) rank** whenever Amazon shows ads to the IP that reads the page (see Limits: cloud IPs see few ads on amazon.com). One check per keyword ranks every ASIN and brand you track from the same pages, on amazon.com and 20 other marketplaces. Schedule it daily and you have a keyword rank history; export the rank data to CSV, JSON or Excel, or read it via API.

No login, no browser, no API key: it reads the search results pages Amazon serves to a desktop visitor, page after page, and moves to another IP (datacenter, then residential in the marketplace's country) when Amazon's bot check shows up. It never solves a CAPTCHA or a challenge.

### What the Amazon rank tracker returns

One row per keyword and tracked ASIN or brand. Ranks count across pages, the way a shopper scrolls.

| field | what it is |
|---|---|
| `status`, `reason` | `ok` (measured; a product not in the pages scanned is `found: false`, which is a rank too: "not in the top N"), `no_results` (Amazon shows nothing, or only ads), `blocked` (every IP route was refused), `invalid` (a line that is not an ASIN, a brand or a keyword), `not_checked` (the run's spending limit could not pay for another check). `reason` says why, or what the check left out. Only `ok` checks are charged. |
| `keyword`, `marketplace`, `department`, `searchUrl` | The search, and the link to its first page. |
| `target`, `targetType` | The ASIN or brand as you gave it; `asin` or `brand`. |
| `found` | The target is among the organic results of the pages scanned. |
| `organicRank` | 1 = the first result that is not an ad. |
| `organicPosition`, `organicPage`, `organicPositionOnPage` | Its place among every product card (ads included), its page, its place on that page. |
| `sponsoredRank` | 1 = the first ad: the target's first sponsored placement. |
| `sponsoredPosition`, `sponsoredPage` | Where that ad sits among every product card, and its page. |
| `organicCards`, `sponsoredCards` | How many of the target's cards the pages showed, organic and sponsored (for a brand, its share of the shelf). |
| `asin`, `title`, `brand`, `url`, `image` | The product found (for a brand, its best-ranked product). `brand` is the line fashion and beauty cards print above the title. |
| `price`, `priceText`, `currency` | 13.96, "$13.96", "USD". |
| `rating`, `reviewCount`, `boughtPastMonth` | 4.3, 118288, and 10000 for "10K+ bought in past month". |
| `badges`, `amazonsChoice`, `bestSeller` | The badges as printed ("Best Seller", "Amazon's Choice", "Overall Pick"). |
| `maxPages`, `pagesScanned`, `scanEnd` | Pages this check could scan, pages read, and why it stopped: `all_found`, `max_pages`, `last_page` or `blocked`. |
| `resultsScanned`, `organicResultsScanned`, `sponsoredResultsScanned` | Product cards on the pages scanned, organic and ads. |
| `routes` | The IP class each page was read through: `direct`, `datacenter` or `residential`. |
| `totalResultsText`, `totalResults` | "over 20,000" and 20000, as Amazon words the result count. |
| `topCompetitors` | The first organic results that are not yours: `organicRank`, `position`, `asin`, `title`, `brand`, `price`, `currency`, `rating`, `reviewCount`, `amazonsChoice`, `bestSeller`, `url`. |
| `checkedAt` | When the keyword was checked (UTC). |

### How to track Amazon keyword rankings

| field | what it does |
|---|---|
| `asins` | Your products, or a competitor's: an ASIN (`B09FT58QQP`) or a product link (`amazon.com/dp/B09FT58QQP`) per line. Up to 50. |
| `brands` | Optional brand names (`Soundcore`, `JBL`). A product counts for a brand when its title starts with the brand, as Amazon titles do, or when the card prints the brand on its own line (fashion, beauty). Case and accents are ignored. Up to 10. |
| `keywords` | What shoppers type, one per line. A link to an Amazon search results page is taken as it is, with its own marketplace, department and filters. Up to 1,000. |
| `marketplace` | `com` (default), `ca`, `com.mx`, `com.br`, `co.uk`, `de`, `it`, `es`, `nl`, `com.be`, `ie`, `se`, `pl`, `com.tr`, `co.jp`, `in`, `com.au`, `sg`, `ae`, `sa`, `eg`. |
| `department` | Optional: the alias after `i=` in a search link (`electronics`, `stripbooks`, `fashion`, `beauty`, `garden`…), to rank inside one department. |
| `maxPages` | How deep to look, 1 to 7 pages (default 3). The scan stops sooner once every ASIN has its organic rank, or at Amazon's last page. |
| `route` | `auto` (default): the cheapest IP that answers. `residential`: every page from a residential IP in the marketplace's country, a local visitor's view. `no-residential`: never residential; refused keywords come back as free `blocked` rows. |
| `competitors` | How many top organic competitors each row lists (default 10, up to 20, 0 for none). |

```json
{
    "asins": ["B09FT58QQP", "B0BQPNMXQV"],
    "brands": ["Soundcore"],
    "keywords": ["wireless earbuds", "bluetooth earbuds", "earbuds for running"],
    "marketplace": "com",
    "maxPages": 3,
    "competitors": 10
}
```

### Output example

```json
{
    "status": "ok",
    "reason": null,
    "keyword": "wireless earbuds",
    "marketplace": "com",
    "department": null,
    "searchUrl": "https://www.amazon.com/s?k=wireless+earbuds",
    "target": "B09FT58QQP",
    "targetType": "asin",
    "found": true,
    "organicRank": 9,
    "organicPosition": 9,
    "organicPage": 1,
    "organicPositionOnPage": 9,
    "sponsoredRank": null,
    "sponsoredPosition": null,
    "sponsoredPage": null,
    "organicCards": 1,
    "sponsoredCards": 0,
    "asin": "B09FT58QQP",
    "title": "TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones",
    "brand": null,
    "url": "https://www.amazon.com/dp/B09FT58QQP",
    "image": "https://m.media-amazon.com/images/I/81+4jNKVFgL.jpg",
    "price": 13.96,
    "priceText": "$13.96",
    "currency": "USD",
    "rating": 4.3,
    "reviewCount": 118288,
    "boughtPastMonth": 10000,
    "badges": ["Best Seller"],
    "amazonsChoice": false,
    "bestSeller": true,
    "maxPages": 3,
    "pagesScanned": 1,
    "scanEnd": "all_found",
    "resultsScanned": 16,
    "organicResultsScanned": 16,
    "sponsoredResultsScanned": 0,
    "routes": ["direct"],
    "totalResultsText": "over 20,000",
    "totalResults": 20000,
    "topCompetitors": [
        { "organicRank": 1, "position": 1, "asin": "B0HDB173YV", "title": "Wireless Earbuds, Bluetooth 6.0 Headphones HiFi Stereo 50H Playback LED Digital Display Ear Buds…", "brand": null, "price": 19.97, "currency": "USD", "rating": 4.8, "reviewCount": 169, "amazonsChoice": true, "bestSeller": false, "url": "https://www.amazon.com/dp/B0HDB173YV" },
        { "organicRank": 2, "position": 2, "asin": "B0FQFB8FMG", "title": "Apple AirPods Pro 3 Wireless Earbuds with Active Noise Cancellation", "brand": null, "price": 199, "currency": "USD", "rating": 4.4, "reviewCount": 16708, "amazonsChoice": false, "bestSeller": true, "url": "https://www.amazon.com/dp/B0FQFB8FMG" }
    ],
    "checkedAt": "2026-10-24T06:00:00.000Z"
}
```

An ASIN that is not in the pages scanned is still a measured row: `"found": false`, the ranks `null`, and `pagesScanned` and `organicResultsScanned` tell you how deep it is not ("not in the top 48 organic results").

### Use cases

- **Daily keyword rank tracking**: schedule a run over your main keywords and chart `organicRank` per ASIN over time; launches, price changes and reviews show up as rank moves.
- **PPC and organic side by side**: see whether an ASIN that ranks organically on page 2 is also bought onto page 1 as a sponsored product, and how many ads the keyword carries. This works where the reading IP is shown ads: amazon.co.uk, .de, .it, .es and .in (read through residential IPs), or `route: residential` on amazon.com; through the default route amazon.com shows few ads.
- **Competitor tracking**: put a competitor's ASINs next to yours, or track whole brands, and read `topCompetitors` to see who holds the places above you.
- **Agency reporting**: one run per client, one row per keyword and ASIN, straight into a spreadsheet or BI tool through the API.
- **Every product of the keyword, not just yours**: our [Amazon Search Scraper](https://apify.com/steadyscrape/amazon-search-scraper) returns every card of a search; the [Amazon Product Details Scraper](https://apify.com/steadyscrape/amazon-product-scraper) opens the product page (buy box, seller, stock, best seller rank).

### Pricing

Pay per event, no start fee:

| event | price | when |
|---|---|---|
| `keyword-check` | **US$0.005** | one keyword on one marketplace: up to 3 pages, every ASIN and brand you track ranked from them (US$5 per 1,000 keywords) |
| `extra-page` | US$0.0015 | each page past the third, only when you ask for more and the scan has not found every ASIN yet |
| `residential-page` | US$0.005 | each page read through a residential IP: amazon.co.uk, .de, .it, .es and .in refuse cloud IPs, so their pages always are; with `route: residential`, every page is |

Tracking 5 ASINs on 50 amazon.com keywords costs US$0.25 a run. The same on amazon.co.uk, found on the first page, costs US$0.50. `no_results`, `blocked`, `invalid` and `not_checked` rows are free. With a spending limit on the run, a keyword check starts only when the limit can pay for its worst case; once residential pages no longer fit, checks are made without them (their rows say so), and the keywords left over come back as free `not_checked` rows.

### Limits and honesty

- **Marketplaces**: measured from Apify's cloud on 2026-10-19, amazon.com, .ca, .com.mx, .com.br, .co.jp and .com.au answered through datacenter IPs; amazon.co.uk, .de, .it, .es and .in answered Amazon's bot check to cloud IPs and were read through residential IPs of their own country. **amazon.fr answered a challenge on every route and is not offered.** Amazon changes its mind about IPs from one hour to the next; a keyword every route refuses is a free `blocked` row and the run still finishes.
- **Ranks depend on who asks**: Amazon personalizes and localizes results by IP, so two runs minutes apart, or this Actor and your own browser, can differ by a few places. Datacenter IPs are in the US: amazon.co.jp read from them shows US-dollar prices and a foreign visitor's results; `route: residential` reads as a visitor in the marketplace's country.
- **Sponsored ranks are the ads the reading IP was shown**, and Amazon shows proxy IPs fewer ads than shoppers at home. Measured on 2026-10-24 on amazon.com: datacenter IPs (the default route there) were shown no ads on "wireless earbuds", and earlier datacenter runs saw about 2 ads per 100 product cards; through US residential IPs 1 search of 3 showed ads ("phone charger", 6 of 22 cards; "wireless earbuds" and "laptop stand" none), against 6 of 22 cards to a home connection. amazon.co.uk showed 6 of 22 through a UK residential IP. So on amazon.com, expect `sponsoredRank` mostly `null` on the default route, and some ads with `route: residential`. Every row says how many ads its pages held (`sponsoredResultsScanned`): read a missing sponsored rank against that number.
- **One variation per product family**: Amazon's search shows one ASIN for a family of sizes or colors, not always the one you sell most. An ASIN is matched exactly, so track the ASIN the search result links to.
- **Brands are matched by name**, from the title's start or the brand line some departments print. A title that only mentions the brand ("Case for Apple AirPods") does not count, and a brand sold under a sub-brand ("Soundcore by Anker") is tracked by the name that starts its titles.
- **Positions are product cards**: video ads, brand banners and carousels between the results are not counted. A keyword Amazon answers with ads alone is a free `no_results` row.
- Pages are read until every tracked ASIN has an organic rank, so an ad of yours on a later page than your organic result is not looked for. With brands in the input, every page asked is read.
- Search results pages only: no product page is opened, so no seller, stock or best seller rank beyond what the card shows.

### Legal

This Actor is not affiliated with, endorsed by or sponsored by Amazon. It reads publicly available search results pages that Amazon shows to anyone, without logging in, and stores no personal data. It does not solve CAPTCHAs or bypass challenges. Use the data in line with Amazon's terms and your local law.

# Actor input Schema

## `asins` (type: `array`):

Your products (or a competitor's), one per line: the ASIN (<code>B09FT58QQP</code>) or the product link (<code>https://www.amazon.com/dp/B09FT58QQP</code>). Each one gets a row per keyword with its organic rank and its sponsored (ad) rank. Matched by the ASIN on the search result card: Amazon shows one variation per product family, so track the ASIN its search results link to. Up to 50.

## `brands` (type: `array`):

Brand names, one per line (<code>Soundcore</code>, <code>JBL</code>): the rank of the brand's best product and how many of its products show, organic and sponsored. A product counts for a brand when its title starts with the brand name, as Amazon titles do, or when the card prints the brand on its own line (fashion, beauty). Case and accents are ignored. Up to 10. A brand is counted over every page, so with brands the scan always reads the pages you ask for.

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

What shoppers type in Amazon's search box, one per line (<code>wireless earbuds</code>). A link to an Amazon search results page (<code>https://www.amazon.co.uk/s?k=desk+lamp\&i=kitchen</code>) is taken as it is, with its own marketplace, department and filters. One keyword is one check: every ASIN and brand above is ranked from the same pages.

## `marketplace` (type: `string`):

Where keywords are searched (links carry their own). Measured from Apify's cloud: amazon.com, .ca, .com.mx, .com.br, .co.jp and .com.au answer through datacenter IPs; .co.uk, .de, .it, .es and .in only through residential IPs of their own country, so their pages add a residential-page charge. amazon.fr answers a challenge on every route and is not offered.

## `department` (type: `string`):

Rank inside one department, by the alias Amazon puts after <code>i=</code> in a search link: on amazon.com <code>electronics</code>, <code>stripbooks</code> (Books), <code>fashion</code>, <code>beauty</code>, <code>garden</code> (Home & Kitchen), <code>hpc</code> (Health & Household), <code>sporting</code>, <code>toys-and-games</code>, <code>pets</code>. Empty: all departments, as the search box does by default.

## `maxPages` (type: `integer`):

How deep to look: Amazon shows 16 to 60 products a page and ends most searches at 7 pages. The scan stops sooner once every ASIN has been found among the organic results, or at Amazon's last page. A keyword check includes 3 pages; each page past the third is an extra-page charge.

## `route` (type: `string`):

Which IPs Amazon is read from. <b>Cheapest that answers</b>: the run's own IP, then datacenter, then residential in the marketplace's country. <b>Residential in the marketplace's country</b>: every page from a residential IP there, the view of a local visitor (Amazon localizes results and prices by IP); each page is a residential-page charge. <b>Never residential</b>: a keyword only residential would answer comes back as a free <code>blocked</code> row. Sponsored ranks are the ads the reading IP was shown, and Amazon shows proxy IPs fewer ads than shoppers at home: each row says how many ads its pages held (<code>sponsoredResultsScanned</code>).

## `competitors` (type: `integer`):

How many of the first organic results that are not your ASINs or brands to list in each row (title, price, rating, reviews), so you see who holds the places above you. 0 leaves them out.

## Actor input object example

```json
{
  "asins": [
    "B09FT58QQP",
    "B0BQPNMXQV"
  ],
  "keywords": [
    "wireless earbuds"
  ],
  "marketplace": "com",
  "maxPages": 3,
  "route": "auto",
  "competitors": 10
}
```

# Actor output Schema

## `ranks` (type: `string`):

No description

## `summary` (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 = {
    "asins": [
        "B09FT58QQP",
        "B0BQPNMXQV"
    ],
    "keywords": [
        "wireless earbuds"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyscrape/amazon-keyword-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 = {
    "asins": [
        "B09FT58QQP",
        "B0BQPNMXQV",
    ],
    "keywords": ["wireless earbuds"],
}

# Run the Actor and wait for it to finish
run = client.actor("steadyscrape/amazon-keyword-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 '{
  "asins": [
    "B09FT58QQP",
    "B0BQPNMXQV"
  ],
  "keywords": [
    "wireless earbuds"
  ]
}' |
apify call steadyscrape/amazon-keyword-rank-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyscrape/amazon-keyword-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/4Hf0J4tbTbGZSlx31/builds/cF7l8PSyIWvOdmLBI/openapi.json
