# Amazon KDP Niche Analyzer - BSR, Competition & Niche Score (`fabrikit/kdp-niche-analyzer`) Actor

Check Amazon KDP book niches before you publish: searches Books or Kindle for each keyword, reads Best Sellers Rank, reviews, price and age of the top books, adds Amazon autocomplete ideas and returns a transparent 0-100 niche score.

- **URL**: https://apify.com/fabrikit/kdp-niche-analyzer.md
- **Developed by:** [Fabrikit](https://apify.com/fabrikit) (community)
- **Categories:** E-commerce, SEO tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 book analyseds

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

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

**KDP Niche Analyzer scores book niches on amazon.com before you write a single page.** For every keyword it searches the Books (print) or Kindle Store department, opens the top organic results to read their **Best Sellers Rank (BSR)**, ratings, price, page count, publisher and publication date, asks **Amazon autocomplete** what buyers type next, and returns a **0-100 niche score** whose formula is written out below. No login, no browser extension, no API key.

It is built on two of our own actors: the Amazon parsers and proxy ladder of [Amazon Product Scraper](https://apify.com/fabrikit/amazon-product-scraper) and the completion client of [Google Autocomplete Scraper](https://apify.com/fabrikit/google-autocomplete-scraper).

### What you get

**One niche row per keyword** (and per format if you choose both):

- `nicheScore` (0-100) and `verdict`: promising / mixed / tough
- The four components: `demandScore`, `competitionScore`, `freshnessScore`, `priceScore`
- The raw numbers behind them: `totalResults`, `medianBsr`, `bestBsr`, `shareBsrUnder100k`, `medianReviews`, `booksOver1000Reviews`, `booksUnder50Reviews`, `medianPrice`, `medianAgeMonths`, `shareNewLast12Months`, `independentlyPublishedShare` (how many top books are self-published), `kindleUnlimitedShare` (Kindle)
- `inAutocomplete` (does Amazon suggest the phrase while it is typed?) and `autocompleteSuggestions`

**One book row per sampled book**: organic position, ASIN, title, authors, binding, other formats, series, price, Kindle Unlimited flag, rating, ratings count, BSR in Books / Kindle Store, sub-category ranks, free-list rank for free Kindle books, publication date and age in days, pages, publisher, `independentlyPublished`, ISBN-13, category breadcrumb, cover image.

### Use cases

- **Pick your next KDP book**: run 20-50 keyword ideas at once and sort by score.
- **Low-content and journal niches**: see whether the top journals are years old and indie-published (a gap) or fresh and run by big publishers.
- **Kindle vs print**: `format: both` shows whether a niche sells better as an eBook or as a paperback.
- **Long-tail discovery**: switch on `analyzeSuggestions` and the actor scores the autocomplete phrases too.

### How to use

1. Type your niche keywords, one per line, the way a buyer would search Amazon.
2. Pick `paperback` (print books, including low-content), `kindle` or `both`.
3. Keep `booksPerNiche` at 10 for a quick read or raise it (up to 48) for a steadier median.
4. Run it, then open the **Niches** view of the dataset; the **Books** view lists the sampled books.

```json
{
  "keywords": ["gratitude journal for women", "cozy mystery", "coloring book for adults"],
  "format": "paperback",
  "booksPerNiche": 10,
  "autocompleteExpansion": "basic",
  "analyzeSuggestions": false,
  "maxItems": 100
}
```

### Example output

Niche row (real run, 25 Oct 2026, shortened):

```json
{
  "recordType": "niche",
  "nicheKeyword": "gratitude journal for women",
  "format": "paperback",
  "nicheScore": 38,
  "verdict": "tough",
  "demandScore": 67,
  "competitionScore": 86,
  "freshnessScore": 0,
  "priceScore": 45,
  "totalResults": 58812,
  "sampleSize": 10,
  "medianBsr": 41398,
  "bestBsr": 1232,
  "shareBsrUnder100k": 0.9,
  "medianReviews": 2676,
  "booksOver1000Reviews": 8,
  "medianPrice": 9.49,
  "medianAgeMonths": 71.8,
  "shareNewLast12Months": 0,
  "independentlyPublishedShare": 0.3,
  "inAutocomplete": true,
  "autocompleteSuggestions": ["gratitude journal for women and men"]
}
```

Book row (shortened):

```json
{
  "recordType": "book",
  "nicheKeyword": "gratitude journal for women",
  "position": 1,
  "asin": "1952842050",
  "title": "Gratitude Journal for Women: A Daily 5 Minute Guide for Mindfulness, Positivity, Affirmation and Self Care (Premium Keepsake Edition)",
  "authors": ["Paper Peony Press"],
  "bookFormat": "Hardcover",
  "price": 11.79,
  "currency": "USD",
  "rating": 4.7,
  "reviewsCount": 2150,
  "bsr": 13879,
  "bsrCategory": "Books",
  "categoryRanks": [{ "rank": 27, "category": "Guided Journals" }],
  "publicationDate": "2020-09-15",
  "printLength": 128,
  "publisher": "Paper Peony Press",
  "independentlyPublished": false,
  "detailsStatus": "ok"
}
```

### How the niche score works

Every component is 0-100 and computed only from what Amazon shows on the pages read in the run. "Log score" means a straight line on a log10 scale between two anchor values, capped at 0 and 100.

| Component | Formula | Meaning |
|---|---|---|
| **Demand** | 60 % log score of the median BSR (BSR 1,000 = 100, BSR 2,000,000 = 0) + 40 % share of sampled books with BSR ≤ 100,000 | Are the books buyers see actually selling? |
| **Competition** | 50 % log score of total results (500 = 0, 200,000 = 100) + 50 % log score of the median ratings count (0 = 0, 5,000 = 100) | How crowded and entrenched is page 1? Higher = harder. |
| **Freshness** | 50 % share of sampled books published in the last 365 days + 50 % age score (0 months = 100, 60+ months = 0) | Do recent books make it to the top? |
| **Price** | Median price mapped onto a band: print US$5 = 0 to US$15 = 100; Kindle US$0.99 = 0 to US$7.99 = 100 | Room for royalties at the prices that rank. |

**nicheScore = 0.40 × demand + 0.30 × (100 − competition) + 0.15 × freshness + 0.15 × price** (change the weights with `scoreWeights`). 65+ is "promising", 45-64 "mixed", below 45 "tough". Worked example: median BSR 50,000 with 3 of 5 books under 100k gives demand 53; 20,000 results and a median of 100 ratings give competition 58; 2 of 5 books new and a median age of 24 months give freshness 50; a median price of US$9.99 gives price 50. The score is 0.40 × 53 + 0.30 × 42 + 0.15 × 50 + 0.15 × 50 = **49 (mixed)**.

There is no score when fewer than 5 books were sampled or fewer than 3 have a paid BSR (`scoreNote` says why). Free Kindle books are ranked on Amazon's free list, so they get `freeKindleRank` instead of `bsr`.

**What the score is not:** it does not estimate sales, royalties or search volume, and it promises nothing about how a new book will sell. BSR changes every hour and depends on the category; treat the score as a way to rank your own keyword list, then look at the books yourself.

### Pricing

Pay per event: each book row is charged once its product page was read, plus Apify's standard actor-start event per run. Niche summary rows are free, and book rows whose product page could not be loaded are saved without charge (`detailsStatus` is not "ok"). See the Pricing tab for current prices; paid Apify plans get lower rates.

- 10 niches × 10 books = 100 book rows
- 50 niches × 20 books = 1,000 book rows
- 200 niches × 10 books = 2,000 book rows

`maxItems` caps the billed rows, and the run also stops at the maximum charge you set for the run.

### Compared with other options

- **Other KDP niche actors on Apify:** this one bills only book rows, gives the niche rows for free, covers print books and Kindle, and documents every number in the score.
- **Desktop or subscription KDP tools** often turn BSR into estimated sales. This actor does not estimate sales; it gives you the raw BSR, ratings and dates plus a transparent score, as structured data you can sort, chart or feed into your own model.

### Integrations

Use the dataset from the Apify API (JSON, CSV, Excel), schedule runs, or connect it to Make, Zapier, n8n or Google Sheets. AI agents can call it through the Apify MCP server and read the niche rows directly.

### FAQ

**Is it legal?** It reads public Amazon search and product pages without logging in. Author and publisher names are publication data printed on the book. It does not collect reviews or anything about reviewers or buyers. Check Amazon's terms for your own use case.

**Do I need a proxy?** Keep the default. Runs start on Apify datacenter proxies; if Amazon answers with bot checks three times in a row, the run moves to US residential proxies on its own, rotating browser fingerprints (Chrome, Safari, Firefox) on every blocked session. The `SUMMARY` record shows the proxy used and the megabytes transferred.

**Which Amazon stores?** amazon.com (US). Other storefronts showed bot checks during our tests and are not offered yet.

**Limits?** Up to 48 books per niche (2-3 search pages) and 10,000 book rows per run. The sample is the organic ranking as Amazon shows it to a US visitor at run time.

**Why is BSR empty for a book?** Free books, pre-orders and some new titles have no paid rank. They still count for reviews, price and age.

### Changelog

- **0.1 (25 Oct 2026)**: first release. Print and Kindle search, product-page BSR, Amazon autocomplete, niche score with adjustable weights.

### En español

KDP Niche Analyzer revisa nichos de libros en amazon.com: por cada palabra clave busca en Libros o Kindle, lee el BSR, las reseñas, el precio y la fecha de publicación de los primeros libros, agrega sugerencias del autocompletar de Amazon y calcula un puntaje de nicho de 0 a 100 con la fórmula de arriba. No estima ventas. Consulta la pestaña Pricing para ver los precios actuales; los planes de pago de Apify tienen tarifas más bajas. Las filas de nicho son gratis.

# Actor input Schema

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

One niche per line, written the way a buyer would search Amazon, e.g. 'coloring book for adults', 'gratitude journal for women', 'cozy mystery'. Each keyword becomes one niche row with its score plus one row per sampled book.

## `format` (type: `string`):

Which Amazon department is searched: print books (Books, i=stripbooks: paperback, hardcover, spiral-bound...), Kindle eBooks (Kindle Store, i=digital-text) or both (two niche rows per keyword).

## `booksPerNiche` (type: `integer`):

How many top organic search results are opened per niche to read Best Sellers Rank, publication date, pages and publisher. The score needs at least 5 books (3 of them with a BSR). Page 1 of a print search holds 24 organic books, a Kindle page 16.

## `autocompleteExpansion` (type: `string`):

Ask Amazon's search box (books or Kindle department) for suggestions. 'basic' sends the keyword and the keyword followed by a space (2 tiny requests); 'alphabet' also sends keyword + a...z (28 requests) for long-tail ideas. The niche row shows the suggestions and whether Amazon suggests the keyword itself.

## `analyzeSuggestions` (type: `boolean`):

Run the full niche analysis (search + top books + score) on the autocomplete suggestions too. Each analysed suggestion adds its own niche row and book rows.

## `maxSuggestionsPerKeyword` (type: `integer`):

Cap on how many suggestions per keyword are analysed when the option above is on (in Amazon's order).

## `includeSponsored` (type: `boolean`):

Sponsored (ad) cards are skipped by default, so the sample reflects the organic ranking that a new book competes for.

## `scoreWeights` (type: `object`):

Weights of the four score components (any positive numbers, they are converted to percentages). Default: demand 40, competition 30, freshness 15, price 15. Set a component to 0 to ignore it.

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

Stop after this many book rows with product data in total (the billed rows). Niche summary rows are free and do not count.

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

Apify datacenter proxies are used first; after repeated bot checks the run switches to US residential proxies on its own.

## Actor input object example

```json
{
  "keywords": [
    "coloring book for adults"
  ],
  "format": "paperback",
  "booksPerNiche": 10,
  "autocompleteExpansion": "basic",
  "analyzeSuggestions": false,
  "maxSuggestionsPerKeyword": 5,
  "includeSponsored": false,
  "scoreWeights": {
    "demand": 40,
    "competition": 30,
    "freshness": 15,
    "price": 15
  },
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One 'niche' row per keyword and format with its score, followed by one 'book' row per sampled book

## `summary` (type: `string`):

Counts, proxy rung, transferred megabytes and errors of the run

# 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": [
        "coloring book for adults"
    ],
    "booksPerNiche": 10,
    "maxItems": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("fabrikit/kdp-niche-analyzer").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": ["coloring book for adults"],
    "booksPerNiche": 10,
    "maxItems": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("fabrikit/kdp-niche-analyzer").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": [
    "coloring book for adults"
  ],
  "booksPerNiche": 10,
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call fabrikit/kdp-niche-analyzer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fabrikit/kdp-niche-analyzer"
        }
    }
}
```

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/VLwOWSlNm19czX72G/builds/HLhpAiBk7YRmSKhl0/openapi.json
