# Ecommerce Ozon Product Report Search

> Search and filter Ozon marketplace product reports by category, brand, seller, sales, revenue, price, rating, stock, and related metrics. Use for product research, competitor analysis, assortment planning, or opportunity screening.

- Skill: `nexscope-ai/ecommerce-ozon-product-report-search` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add nexscope-ai/ecommerce-ozon-product-report-search`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nexscope-ai/ecommerce-ozon-product-report-search/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: nexscope-ai (https://skillmd.com/u/nexscope-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/nexscope-ai/ecommerce-ozon-product-report-search

---


# Seerfar Ozon Product Report Search

This skill searches the Seerfar Ozon product database and filters products by rich performance metrics — monthly sales, revenue, growth, cart/order conversion, price, rating, reviews, brand, seller, fulfillment model, listing age, gross margin, and more. Each returned row is a full product-report record, making this the starting point for Ozon product selection (product selection), competitor product analysis, best-seller mining, and price/conversion-band screening.

## Core Concepts

**Unit of data is the product, not the keyword**: this endpoint returns product-level rows (one per SKU), each enriched with full report metrics. You discover *which products* match your criteria — unlike the market-keyword endpoint, which returns search terms.

**This is a product screener / product report**: filter the Ozon product database by metric ranges (`{min, max}`), not only by keyword/brand/seller. Stack a high `monthlySales` floor with a low `price` ceiling to surface affordable high-volume products, or qualify conversion quality with a high `convToCartPdp` floor and a low `returnCancellationRate` ceiling; sort by `sales` DESC to mine best-sellers.

**Unified vs raw duplicate fields**: the response carries six alias pairs that hold the same value under two keys — `sku`/`productId`, `sales`/`monthlySalesUnits`, `revenue`/`monthlySalesRevenue`, `reviewRating`/`rating`, `brandName`/`brand`, `productUrl`/`productPageUrl`. Read either; do not expect them to differ.

**Date semantics**: `searchDate` selects the data month. Pass `2026-04-01` for March 2026 data; omit it for the last 30 days. Sales/revenue figures are relative to the selected period.

**`data` and `products` are identical**: both top-level arrays carry the same product rows. `total` is the total matching count (e.g. ~27.8M with no filter, 1 when filtering to a single SKU).

**Ozon only**: `sourceType` is fixed to `ozon`. `fulfillment` values are `OZON`, `FBO`, `FBS`, `RFBS`, `FBP`.

## Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| page | object | yes | Pagination + sort: `{page, pageSize, orders[]}`. `page` from 1 (default 1), `pageSize` default 20. `orders[]` = `{field, direction}` with `direction` `DESC`/`ASC`. |
| skus | array<int> | no | SKU list to restrict to (max 10). |
| keywords | array<string> | no | Keyword list to filter product titles. |
| categoryIds | array<string> | no | Seerfar category ID list. |
| sellerName | array<string> | no | Seller name list. |
| brand | object | no | `{brandName: array<string>, type: int}`. `type`: `0` include, `1` exclude, `2` no brand. |
| fulfillment | array<string> | no | Fulfillment filter: `OZON`/`FBO`/`FBS`/`RFBS`/`FBP`. |
| labels | array<int> | no | Badge filter: `0` new, `1` authentic, `2` best-seller. |
| creationDate | integer | no | Listing-age filter (months): `1`/`3`/`6`/`12`/`24`. |
| variationsMerge | integer | no | Merge variants: `0` no, `1` yes. |
| searchDate | string | no | Data date `yyyy-MM-dd`; default last 30 days. `2026-04-01` → March 2026. |
| tag | string | no | Tag word. |
| monthlySales | {min,max} | no | Monthly sales range. |
| monthlySalesRate | {min,max} | no | Sales growth-rate range (filters `salesRate`). |
| monthlyRevenue | {min,max} | no | Monthly revenue range. |
| price | {min,max} | no | Price range (RUB). |
| convToCartPdp | {min,max} | no | Cart conversion rate range. |
| reviewRating | {min,max} | no | Rating range. |
| reviewCount | {min,max} | no | Review count range. |
| questionsAndAnswers | {min,max} | no | Q&A count range. |
| variants | {min,max} | no | Variant count range. |
| drr | {min,max} | no | Ad-cost share range. |
| grossMargin | {min,max} | no | Gross margin range. |
| returnCancellationRate | {min,max} | no | Return/cancellation rate range. |
| weight | {min,max} | no | Weight range (g). |
| volume | {min,max} | no | Volume range (L). |
| uId / memberId | string | no | User / member ID (data attribution). |

All range filters are `{min, max}` objects; supply either or both bounds. Only `page` is required.

## Calling the Tool

- **API Endpoint**: `/seerfar/ozon/productReportSearch` (full parameters/responses/error codes in `references/api.md`)
- **Python Script**: `python scripts/ozon_product_report_search.py '<JSON params>' [--inline]`
- **Cost constraint**: This tool consumes credits. Within the same session and same parameter combination, it defaults to a single call with a 24-hour local cache. Do not automatically retry with different keywords, pagination, or parameters on failure/empty results. Inform the user of additional credit consumption before continuing retrieval.

**Output strategy (script default behavior)**:
- **Always** write the full response to `<cwd>/nexscope/<YYYY-MM-DD>/<session>/data/ecommerce-ozon-product-report-search-<timestamp>.json` (`<cwd>` is the working directory when the script executes, which in Claude Code is the current project directory; `<session>` is taken from the `SESSION_ID` environment variable, automatically grouped by user task; **do not write to /tmp**; error if the current directory is not writable)
- Response body <= 8 KB: write to disk then print full JSON to stdout
- Response body > 8 KB: write to disk then print only a summary to stdout (top-level fields, common counts like `total`/`costToken`, length of the largest list field + first 3 samples)
- Add `--inline` to force full output to stdout (still writes to disk)

**Reading data**: Check the summary first to determine if it is sufficient. When specific fields are needed, use `jq` or `ConvertFrom-Json` to extract from the saved JSON file as needed, avoiding loading the entire JSON into context.
## Authentication & Credits

If you encounter authentication or credit issues:

### Error conditions
- **API Key not configured**: The `NEXSCOPE_API_KEY` environment variable is not set.
- **HTTP 401 or 402 status code**
- **Insufficient credits/balance**: Response message indicates credit balance exhausted, quota exceeded, subscription expired, or recharge required.

### Resolution steps
1. Set the `NEXSCOPE_API_KEY` environment variable with a valid API key.
2. If credits are insufficient, visit https://www.nexscope.ai/pricing?co-from=skillNS to top up your balance.
3. For onboarding and setup guidance, refer to https://www.nexscope.ai/help/skills-external-access?co-from=skillNS
## Usage Examples

**1. Top sellers right now (sort by sales)**
```json
{"page": {"page": 1, "pageSize": 10, "orders": [{"field": "sales", "direction": "DESC"}]}}
```

**2. Blue-ocean products — high sales, low price band**
```json
{"page": {"page": 1, "pageSize": 20, "orders": [{"field": "sales", "direction": "DESC"}]}, "monthlySales": {"min": 5000}, "price": {"max": 500}}
```

**3. Best-sellers in a category, FBO fulfillment**
```json
{"page": {"page": 1, "pageSize": 20, "orders": [{"field": "revenue", "direction": "DESC"}]}, "categoryIds": ["15621031_200000933_93182"], "fulfillment": ["FBO"], "labels": [2]}
```

**4. New listings from the last 30 days, sorted by growth**
```json
{"page": {"page": 1, "pageSize": 20, "orders": [{"field": "salesRate", "direction": "DESC"}]}, "creationDate": 1}
```

**5. Look up specific SKUs**
```json
{"page": {"page": 1, "pageSize": 10}, "skus": [2107989735]}
```

## How to Build Queries

1. **Lead with `page.orders`**: the dataset is huge (tens of millions of products) — always sort by the metric you care about (`sales` DESC for best-sellers, `salesRate` DESC for rising products, `price` ASC for cheap volume, `reviewRating` DESC for well-reviewed).
2. **Stack range filters to find opportunities**: combine a `monthlySales` floor with a `price` ceiling, or a `convToCartPdp` floor with a low `returnCancellationRate`, to qualify demand-vs-risk.
3. **Scope with `categoryIds` / `brand` / `sellerName`**: narrow to a niche before sorting, so the top rows are relevant.
4. **Use `creationDate` + `labels` for fresh demand**: `creationDate: 1` (new listings) paired with `labels: [2]` (best-seller badge) finds breakout products.
5. **Pick the right `searchDate`**: omit for current trends (last 30 days); pass an explicit date for month-over-month comparison.

## Display Rules

1. **Present data only**: show product metrics in a clear table without subjective advice.
2. **Lead with product columns**: `title`, `sku`, `price` (₽), `sales`, `revenue`, `rating`, `reviewCount`, then `brand` / `sellerName` / `fulfillment`.
3. **Currency**: `price`/`revenue`/`missedRevenue` are in Russian rubles (₽); show the currency so scale is not misread.
4. **Unified/raw aliases**: prefer the unified fields (`productId`, `monthlySalesUnits`, `monthlySalesRevenue`, `rating`, `brand`, `productPageUrl`) or note they equal the raw ones — do not present both as if independent.
5. **Large result sets**: when `total` is large, show the top rows and remind the user they can persist the full response via the large-response pattern below, or page further with `page.page`.
6. **Error handling**: when `code` is not `200` (or `errcode` is not `200`), explain the reason from `msg` / `errmsg` and suggest adjusting filters or retrying (rate-limit `1003`).

## Important Limitations

- **`page` is required**: a payload without `page` is rejected.
- **`skus` cap**: at most 10 SKUs per request.
- **Category IDs are opaque**: `categoryIds` requires Seerfar category IDs (from a category search), not human-readable names.
- **Duplicate alias pairs**: six fields are duplicated under raw + unified keys (see Core Concepts) — same value, two keys.
- **`total` is the full match count**: with no filter it can reach tens of millions; always sort and page rather than iterating blindly.
- **Rate limiting**: `errcode 1003` ("request too frequent, please retry later") means throttle — wait and retry rather than lowering `pageSize`.
- **Sort fields**: valid `orders[].field` values are the response metric fields (e.g. `sales`, `revenue`, `price`, `reviewRating`, `reviewCount`, `salesRate`); the `columns` array marks which are sortable.

## User Expression & Scenario Quick Reference

**Applicable** — Ozon product-level screening:

| User Says | Scenario |
|-----------|----------|
| "Ozon product selection / filter by sales & revenue" | Product screener (range filters + sort) |
| "Ozon best-selling / hot products" | Best-seller mining (`labels:[2]` or sort `sales` DESC) |
| "Ozon rising products / new bestsellers" | Rising/new products (`creationDate:1`, sort `salesRate` DESC) |
| "Ozon high-conversion, low-return products" | Conversion-quality screen (`convToCartPdp` min, `returnCancellationRate` max) |
| "Ozon brand/seller product performance" | Brand/seller filter + sort |
| "Check report for these SKUs" | `skus` lookup |

**Not applicable** — Needs beyond product-level reports:
- Keyword market data (search terms, search volume) → market-keyword-search.
- Keyword expansion around a seed term → keyword-mining.
- A specific shop's full catalog → shop-search.
- A category's products with category-level aggregates → category-search.
- Reverse keyword lookup for a product → keyword-back-search.
- Non-Ozon marketplaces → not covered here.

**Boundary judgment**: if the user wants to **screen Ozon products by metrics and read product-level report rows**, start here. If they want keyword-level market data, a single shop's catalog, or a category aggregate, route to the corresponding Seerfar Ozon data source.

