# Puzzle Book Niche Radar – Amazon.fr & .de (KDP) (`jet_mythology/puzzle-book-niche-radar-fr-de`) Actor

KDP niche research for puzzle & activity books (word search, sudoku, crosswords, logic, coloring) on Amazon.fr and Amazon.de: real BSR, reviews, EUR prices, launch waves, large-print share and a transparent opportunity score per keyword.

- **URL**: https://apify.com/jet_mythology/puzzle-book-niche-radar-fr-de.md
- **Developed by:** [jet_mythology](https://apify.com/jet_mythology) (community)
- **Categories:** E-commerce, SEO tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$150.00 / 1,000 niche reports

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

## Puzzle & Activity Book Niche Radar — Amazon.fr & Amazon.de

Niche research for **puzzle and activity books** (word search / mots mêlés / Wortsuche, sudoku, crosswords / mots fléchés / Schwedenrätsel, logic grids / logigrammes / Logicals, coloring, mazes, brain training, nostalgia quizzes, kids' activity books) on **Amazon.fr and Amazon.de**, built for KDP publishers who sell in French and German.

For every keyword you get **one niche report**: how many results Amazon shows, the real Best Sellers Rank (BSR) of the top organic books, review counts, EUR prices, publication dates, and a **transparent opportunity score** whose formula is documented below — no black box.

### Why this Actor (vs. generic KDP analyzers)

- **FR/DE first.** French and German result-count strings, BSR lines ("Nr. 4.469 in Bücher", "3 247 en Livres"), German/French publication dates and EUR prices are parsed natively.
- **Puzzle-book specific signals** that generic analyzers don't compute:
  - `puzzleTypeMix` — which puzzle formats dominate the top results (FR/DE/EN vocabulary).
  - `shareLargePrint` — share of large-print titles (gros caractères / Großdruck / XXL).
  - **Launch-wave detection** — `shareLaunchesLastNDays` and `newestLaunches`: spots seasonal gold rushes (e.g. a flood of new Christmas word-search books with zero reviews) before you join them.
  - `shareNearDuplicateTitles` — share of top titles that are near-copies of each other, a hint of mass-produced low-content saturation.
  - `shareIndependentlyPublished` — how much of the top is self-published vs. traditional publishers.
- **Keyword batch mode with per-keyword store routing:** `fr: logigrammes`, `de: logicals` in one run.
- **One clean row per niche**, with the top books nested as evidence.

### Input

| Field | Description |
|---|---|
| `keywords` | List of keywords. Prefix `fr:` / `de:` to force the store per keyword. |
| `marketplace` | `amazon.fr`, `amazon.de` or `both` (for keywords without prefix). |
| `category` | `books` (default), `kindle`, `all`. |
| `maxResultsPerKeyword` | Organic results opened per keyword (3–30, default 10). Sponsored results are excluded. |
| `fetchProductDetails` | Open product pages for BSR, publication date, publisher, pages (default `true`). |
| `recentLaunchDays` | Window for "recent launch" detection (default 90). |
| `delaySeconds` | Polite randomized delay between page loads (default 3 s). |
| `proxyConfiguration` | Residential proxy in the store's country recommended (also gives local delivery address + local-VAT prices). |

Example:

```json
{
  "keywords": ["fr: logigrammes", "fr: nés en 1956", "de: rätselbuch jahrgang 1956", "de: sudoku großdruck"],
  "category": "books",
  "maxResultsPerKeyword": 10
}
```

### Output (one item per keyword × store)

Key fields: `keyword`, `marketplace`, `searchUrl`, `resultCount`, `resultCountIsLowerBound` (Amazon shows "over 1,000" style counts), `medianBsr`, `top3MedianBsr`, `bestBsr`, `medianReviews`, `shareUnder20Reviews`, `shareZeroReviews`, `medianPriceEur`, `medianAgeDays`, `shareLaunchesLast90Days`, `newestLaunches`, `shareLargePrint`, `puzzleTypeMix`, `shareNearDuplicateTitles`, `demandScore`, `competitionEaseScore`, `floodPenalty`, `opportunityScore`, `verdict`, `scoreConfidence`, and `topProducts[]` (title, ASIN, URL, price, currency, BSR, category and sub-category ranks, rating, review count, publication date, publisher, pages, language, puzzle types, large-print flag).

### Opportunity score (0–100) — formula

```
Demand (0-100)   = 100 × clamp( (log10(500000) − log10(top3MedianBsr)) / (log10(500000) − log10(5000)) )
                   → median BSR of the 3 best-ranked top books: 5,000 or better = 100, 500,000 or worse = 0

ReviewEase       = 100 × clamp( 1 − log10(1 + medianReviews) / log10(501) )     (500+ median reviews = 0)
LowReviewShare   = 100 × share of top organic books with < 20 reviews
ResultCountEase  = 100 × clamp( 1 − (log10(resultCount) − 2) / (log10(50000) − 2) )   (100 results = 100, 50,000 = 0;
                   neutral 50 if Amazon's count is missing or smaller than the results shown → resultCountSuspect)
CompetitionEase  = 0.5 × ReviewEase + 0.3 × LowReviewShare + 0.2 × ResultCountEase

FloodPenalty     = if shareZeroReviews ≥ 0.30 : min(20, 20 × shareLaunchesLastNDays) else 0
                   (pre-orders with a future date are counted in `preorders`, not as launches)

Opportunity      = clamp( 0.4 × Demand + 0.6 × CompetitionEase − FloodPenalty , 0, 100 )
Verdict          = "low demand" if Demand < 25; "opportunity" if ≥ 60 and CompetitionEase ≥ 45; "possible - needs a strong angle" ≥ 45; else "saturated"
Confidence       = high (≥5 BSRs read), medium (3–4), low (<3)
```

BSR is a sales-velocity proxy, not a sales figure; this Actor does **not** invent sales estimates. Thresholds are constants at the top of `src/metrics.py`.

### Pricing

**Pay per event: $0.15 per niche report** — one report = one keyword on one Amazon store, with up to `maxResultsPerKeyword` books analyzed (BSR, reviews, price, publication date). Reports that end as `blocked` or `empty` are **not charged**. Example: 4 keywords on one store = 4 reports = $0.60.

Tip: set a maximum cost per run in the run options if you want a hard budget cap.

### Limits & good practice

- Data is read from public Amazon pages; Amazon may show CAPTCHAs. The Actor runs sequentially with delays and retries, and reports `status: "blocked"` instead of guessing.
- Without a proxy in the store's country, Amazon may show a non-EU delivery address; prices are still forced to EUR via the store currency setting but may differ slightly from local-VAT prices. Check `priceCurrencies`.
- Use the results as research evidence, not as a guarantee of sales. Respect Amazon's terms of use and KDP content guidelines.

### En bref (FR)

Analyse de niches KDP pour livres de jeux et d'activités sur **Amazon.fr et Amazon.de** : nombre de résultats, BSR réel des meilleurs livres, avis, prix en euros, dates de parution, vagues de lancements récents, part de gros caractères et **score d'opportunité transparent** (formule ci-dessus). Préfixez un mot-clé par `fr:` ou `de:` pour choisir la boutique.

### Kurz (DE)

KDP-Nischenanalyse für Rätsel- und Beschäftigungsbücher auf **Amazon.de und Amazon.fr**: Trefferanzahl, echter Bestseller-Rang der Top-Bücher, Bewertungen, Euro-Preise, Erscheinungsdaten, Erkennung von Veröffentlichungswellen, Großdruck-Anteil und ein **transparenter Opportunity-Score** (Formel oben). Mit `de:` oder `fr:` vor dem Suchbegriff wählen Sie den Marktplatz.

# Actor input Schema

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

One niche keyword per line, in the language of the store. Prefix with "fr:" or "de:" to force a marketplace for that keyword (e.g. "de: rätselbuch jahrgang 1956").

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

Store used for keywords without a fr:/de: prefix.

## `category` (type: `string`):

Amazon department to search in.

## `maxResultsPerKeyword` (type: `integer`):

Organic (non-sponsored) results opened per keyword to read BSR and publication date. Higher = slower and costlier.

## `fetchProductDetails` (type: `boolean`):

Without it you only get search-page data (no BSR, so no demand score).

## `recentLaunchDays` (type: `integer`):

Books published within this window count as recent launches (launch-wave detection).

## `delaySeconds` (type: `number`):

Polite delay between requests (randomized ±30%).

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

Residential proxies in the store's country are strongly recommended: they also make Amazon show the local delivery address and EUR prices with local VAT.

## `proxyCountryPerMarketplace` (type: `boolean`):

With Apify Proxy, use a French exit IP for Amazon.fr and a German one for Amazon.de (overrides the country selected above).

## Actor input object example

```json
{
  "keywords": [
    "fr: logigrammes",
    "fr: nés en 1956",
    "de: rätselbuch jahrgang 1956",
    "de: sudoku großdruck"
  ],
  "marketplace": "amazon.fr",
  "category": "books",
  "maxResultsPerKeyword": 10,
  "fetchProductDetails": true,
  "recentLaunchDays": 90,
  "delaySeconds": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "proxyCountryPerMarketplace": true
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `reports` (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": [
        "fr: logigrammes",
        "fr: nés en 1956",
        "de: rätselbuch jahrgang 1956",
        "de: sudoku großdruck"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("jet_mythology/puzzle-book-niche-radar-fr-de").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": [
        "fr: logigrammes",
        "fr: nés en 1956",
        "de: rätselbuch jahrgang 1956",
        "de: sudoku großdruck",
    ],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("jet_mythology/puzzle-book-niche-radar-fr-de").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": [
    "fr: logigrammes",
    "fr: nés en 1956",
    "de: rätselbuch jahrgang 1956",
    "de: sudoku großdruck"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call jet_mythology/puzzle-book-niche-radar-fr-de --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jet_mythology/puzzle-book-niche-radar-fr-de"
        }
    }
}
```

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/YMeqWFaUi7Se8XhIA/builds/58FZUHZ0ubBicMYJX/openapi.json
