# How do I search products and track price or assortment changes?

SKU search, product-idea saturation, price tracking, and assortment change feeds.

Same `nj_` key. REST on `https://mcp.neonjelly.io`. Composed MCP: `niche_research`, `product_search`, `product_intel`, `change_tracker`, `price_watch`, `assortment_watch`.

## Product ideas (semantic / saturation)

`GET /v1/products/search?q=` — rows are **ideas** (seller count, price band, verdict `UNTAPPED` → `SATURATED`), not one listing on one store.

| Query | What |
| --- | --- |
| `q` | Name or category (min 2 chars) |
| `market` | Comma verdicts: `UNTAPPED,LOW COMPETITION,COMPETITIVE,SATURATED` |
| `priceMin` `priceMax` | Idea price band |
| `trending` `countries` `region` | Extra filters |

Then `GET /v1/products/research/{id}` and `GET /v1/products/research/{id}/sellers`. Also `/v1/products/search/suggest` and `/trending`.

MCP: `search_product_ideas`, `get_product_research`, `list_product_sellers`. Prefer `niche_research` (search + top report + sellers).

## Product listings (keyword)

`GET /v1/products` — at least one filter required. This is title-contains listings, not idea saturation.

| Query | What |
| --- | --- |
| `q` | Title contains |
| `storeDomain` | One merchant |
| `vendor` `productType` `tag` | Catalog facets |
| `storeVertical` | Store vertical |
| `isBestSeller` | true / false |
| `priceMin` `priceMax` | Price band |
| `sort` | `price` \| `position` \| `scraped` |
| `order` `limit` `offset` | Page |

`GET /v1/stores/{domain}/products` — same filters, domain in the path.

`GET /v1/products/{domain}/{handle}` — one SKU.

MCP wrappers: `search_products`, `get_store_products`, `get_product`. Prefer `product_search` (adds vendor/type/store/price facets) then `product_intel`.

```bash
curl -H "Authorization: Bearer nj_…" \
  "https://mcp.neonjelly.io/v1/products?q=hoodie&isBestSeller=true&priceMax=80&limit=20"
curl -H "Authorization: Bearer nj_…" \
  "https://mcp.neonjelly.io/v1/products/gruntstyle.com/american-reaper-2-0"
```

## Change tracking

Three feeds. Persist `changeDate` as a cursor.

| Path | Entity | Types |
| --- | --- | --- |
| `GET /v1/changes` | product + store, pre-summarized | `entity=product\|store`, `domain`, `since` |
| `GET /v1/products/changes` | SKUs | `price_increase`, `price_decrease`, `new_product`, `removed_product`, `position_up`, `position_down`, `best_seller_entered`, `best_seller_exited` |
| `GET /v1/stores/{domain}/changes` | one store | `revenue_change`, `visits_change`, `products_change`, `rating_change`, `apps_change` |

Product-change query: `storeDomain`, `changeType`, `productType`, `since`, `minPriceChangePct`, `limit`, `offset`.

MCP: `get_changes`, `get_product_changes`, `get_store_changes`. Prefer `change_tracker` (all buckets + signal SKU changes if watched), `price_watch` (default ≥10%), `assortment_watch` (new/removed/bestseller enter/exit).

```bash
curl -H "Authorization: Bearer nj_…" \
  "https://mcp.neonjelly.io/v1/products/changes?changeType=price_decrease&minPriceChangePct=10&since=2026-08-01&limit=50"
curl -H "Authorization: Bearer nj_…" \
  "https://mcp.neonjelly.io/v1/changes?domain=gruntstyle.com&since=2026-08-01"
curl -H "Authorization: Bearer nj_…" \
  "https://mcp.neonjelly.io/v1/stores/gruntstyle.com/changes"
```

Watched stores only: `GET /v1/signals/{id}/products/changes` → MCP `get_signal_product_changes`.

## Related

- [Where is the Neonjelly documentation?](https://www.neonjelly.io/docs.md)
- [What is the Neonjelly catalog REST API?](https://www.neonjelly.io/docs/api.md)
- [What jobs can I run with Neonjelly playbooks?](https://www.neonjelly.io/docs/use-cases.md)
- [What MCP tools does Neonjelly expose?](https://www.neonjelly.io/docs/tools.md)
- [How do I start a Neonjelly trial?](https://www.neonjelly.io/start.md)

HTML: https://www.neonjelly.io/docs/products
Markdown: https://www.neonjelly.io/docs/products.md

Do not scrape. Do not probe. Missing store stays `not_found`. Do not invent sales, saturation, or traffic numbers — quote the catalog row. Signals (ads and daily units) are paid only. Trial keys get 403 on create_signal and signal reads. Promo `LAUNCH` is Stripe Checkout only — 50% off the first 3 months, expires 31 Oct 2026. Not MCP metadata.
