# Microsoft Store Scraper — App Details, Search & Reviews (`freshactors/microsoft-store-scraper`) Actor

Reliable, always-fresh Microsoft Store data: app details with 7/30-day rating windows, search, and customer reviews with helpful votes. Any country market. Monitored daily. By FreshActors.

- **URL**: https://apify.com/freshactors/microsoft-store-scraper.md
- **Developed by:** [Freshactors](https://apify.com/freshactors) (community)
- **Categories:** Developer tools, E-commerce
- **Features:** Limited permissions
- **Stats:** 11 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.62 / 1,000 app details fetcheds

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

## Microsoft Store Scraper — App Details, Search & Reviews (No API Key)

Scrape the **Microsoft Store** (Windows apps & games) into clean, structured JSON — app **details** with all-time *and* 7/30-day **rating windows**, keyword **search**, and customer **reviews with helpful votes and device info**. Any country market. No account, no login, no API key.

![Microsoft Store Scraper — app details, rating windows, search and reviews](https://raw.githubusercontent.com/Freshactors/freshactors-assets/main/msstore-screenshot.png)

> ✅ **Last verified working: 2026-11-11.** Monitored by an automated daily canary. When Microsoft changes the Store's endpoints, we patch fast and log it in the changelog below — so your pipeline doesn't silently break.

***

### Why this Microsoft Store scraper

Together with our [Apple App Store](https://apify.com/freshactors/app-store-scraper) and [Google Play](https://apify.com/freshactors/google-play-scraper) scrapers, this completes **all three major app stores in one consistent toolset** — same modes, same pricing model, same reliability standard. And the Microsoft Store data has fields the other stores don't expose:

- **Rating windows** — every details record carries the average + count for **all-time, last 7 days, and last 30 days**. That's a momentum signal: a 4.6 all-time / 3.8-last-30-days app is in trouble; the reverse is a turnaround.
- **Reviews with helpful votes + device family** — each review includes `helpfulPositive`/`helpfulNegative` (community-validated complaints!) plus the reviewer's `deviceFamily` and `osVersion`.
- **Any country market** — `market`/`language` inputs localize availability, prices, descriptions, ratings, and review pools (e.g. `DE`/`de-de`).
- **Batched details** — up to 20 apps per request under the hood: fast and cheap.
- **Per-item isolation + retries** — a bad ID or transient error is skipped and logged, never fatal.
- **Stable, versioned output** (`_schemaVersion`) + a **daily canary** — that "last verified working" date is real.

### What data you get

**Details rows** (one per app):

| Field | Type | Description |
|---|---|---|
| `productId` | string | Microsoft Store product ID (12 chars, starts with `9`). |
| `title` / `publisher` | string | App name and publisher. |
| `description` / `shortDescription` | string | null | Full and short listing text (localized per `language`). |
| `category` | string | null | Store category (e.g. `Social`). |
| `rating` | object | `{average, count}` — all-time. |
| `rating7Days` / `rating30Days` | object | `{average, count}` for the recent windows — the momentum signal. |
| `price` | object | `{amount, currency, isFree}` for the selected market. |
| `imageUrl` / `imagesCount` | string | null, number | Primary logo + total image count. |
| `releaseDate` / `lastModified` | string | null | ISO timestamps. |
| `storeUrl` | string | Public listing URL. |

**Search rows:** `productId`, `title`, `publisher`, `averageRating`, `ratingCountText` (the Store's humanized count, e.g. `"332K"`) + `ratingCountApprox` (parsed number), `displayPrice`, `isFree`, `categories`, `productType` (Apps/Games), `hasIAPs`, `minimumAge`, `releaseDate`, `lastModified`, `storeUrl`, `_searchTerm`.

**Review rows:** `productId`, `reviewId`, `reviewerName`, `rating` (1–5), `title`, `text`, **`helpfulPositive`**, **`helpfulNegative`**, `market`, `locale`, `osVersion`, **`deviceFamily`**, `submittedAt`, `isRevised`.

### Use cases

- **App competitive intelligence.** Track competitors' rating windows (is their last update tanking?), review complaints ranked by helpful votes, and price/IAP changes — across any country market.
- **Cross-store ASO research.** Combine with our Apple and Google Play scrapers for the full three-store picture of an app brand or category, in one normalized pipeline.
- **Review mining.** The helpful-vote counts surface the complaints *users themselves* validated — gold for product teams and reviewers. `deviceFamily` splits desktop vs Xbox vs mobile feedback.
- **Market research.** Search any keyword per market and compare which apps win the same query in the US, Germany, or Japan.

### Input

| Field | Type | Required | Notes |
|---|---|---|---|
| `mode` | string | ✅ | `details` (default) / `search` / `reviews`. A mismatched mode is handled — see FAQ. |
| `productIds` | string\[] | for details/reviews | 12-char Store IDs starting with `9` (e.g. `9NKSQGP7F2NH`) or `apps.microsoft.com/detail/...` URLs. `XP...` winget IDs are desktop installers, not Store products — they're skipped with a warning. |
| `searchTerms` | string\[] | for search | Free-text queries; one result set per term. |
| `maxSearchResults` | integer | — | Cap per term (1–20). Default `10`. The Store's search endpoint returns ~20 results per query. |
| `maxReviewsPerApp` | integer | — | Cap per app (1–500), newest first. Default `50`. Deep pagination supported. |
| `market` | string | — | 2-letter country (default `US`). |
| `language` | string | — | Language tag, lowercase (default `en-us`). |

```json
{
  "mode": "details",
  "productIds": ["9NKSQGP7F2NH", "9NCBCSZSJRSB", "9WZDNCRFJ3TJ"]
}
```

### Output sample

A real record from the default run:

```json
{
  "_type": "app",
  "_schemaVersion": "1.0",
  "_source": "microsoft-store",
  "productId": "9NKSQGP7F2NH",
  "title": "WhatsApp",
  "publisher": "WhatsApp Inc.",
  "description": "WhatsApp from Meta is a 100% free messaging app. It's used by over 2B people in more than 180 countries. ...",
  "shortDescription": null,
  "category": "Social",
  "rating": { "average": 4.4, "count": 2294755 },
  "rating7Days": { "average": 4.4, "count": 15549 },
  "rating30Days": { "average": 4.4, "count": 68880 },
  "price": { "amount": 0, "currency": "USD", "isFree": true },
  "imageUrl": "https://store-images.s-microsoft.com/image/apps.39936.13655054093851568.04a4d8fc-dd15-4e4e-bd00-4bbe4247c42e.5fccebf1-7bd7-4999-87f1-863ef313827f",
  "imagesCount": 24,
  "releaseDate": "2017-02-01T01:35:55.265Z",
  "lastModified": "2026-05-27T20:49:24.181Z",
  "storeUrl": "https://apps.microsoft.com/detail/9NKSQGP7F2NH",
  "_scrapedAt": "2026-06-11T12:19:16.266Z"
}
```

### Use with AI agents (MCP)

This scraper is callable as a tool by AI agents via the **[Apify MCP server](https://mcp.apify.com)** — so assistants like **Claude, Cursor, and VS Code** can run it and use the structured results mid-conversation, with no glue code.

Simplest path: in a recent **Claude Desktop**, add the hosted server `https://mcp.apify.com` under **Settings → Connectors** and authorize with OAuth. For any config-file client:

```json
{
  "mcpServers": {
    "apify": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server"],
      "env": { "APIFY_TOKEN": "YOUR_APIFY_TOKEN" }
    }
  }
}
```

Then ask in plain language, e.g. *"Pull the Microsoft Store ratings and the 20 most helpful recent reviews for WhatsApp."* — the agent calls **`freshactors/microsoft-store-scraper`** with the right input and reads back the JSON. Full setup: [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp).

**No Apify account?** x402-enabled AI agents can also run this actor autonomously and **pay per use via the x402 payment protocol** — no signup, subscription, or API token required.

### Pricing

**Volume discounts — applied automatically.** Running at scale on a paid Apify plan? The app-details and search prices drop with your plan tier — up to **35% off at Gold** and more on Platinum/Diamond, with no start fee and nothing to apply for. Free and Bronze keep the standard price shown below.

Pay-per-event — **no subscription**, no per-run start fee. You pay only for the rows you receive:

| Event | Price (USD) | When it fires |
|---|---|---|
| **App details fetched** | **$0.0025** | Once per app details record returned. |
| **Search result fetched** | **$0.001** | Once per search result row returned. |
| **Review fetched** | **$0.0001** | Once per review returned. |

**Worked examples:**

- Full details on **100 apps**: 100 × $0.0025 = **$0.25**
- **10 search queries** × 10 results: 100 × $0.001 = **$0.10**
- **500 reviews** of one app: 500 × $0.0001 = **$0.05**

(Apify platform usage is billed separately per their standard rates.)

### FAQ

**Is scraping the Microsoft Store legal?**
This actor reads **public, non-personal** listing data from the Store's own public endpoints — the same data the Store app shows any user. Review records contain only the public display name a reviewer chose to publish. Use responsibly and in line with applicable terms and laws.

**Do I need an API key or login?**
No. No Microsoft account, token, or key is involved.

**How do I find an app's product ID?**
Open the app on `apps.microsoft.com` — the ID is the last path segment: `apps.microsoft.com/detail/`**`9NKSQGP7F2NH`**. You can paste the whole URL too. Or just type the app's name (e.g. `WhatsApp`) — it is matched to the Microsoft Store search result whose title contains that name (never just the first hit), and the run status names the app it picked; a name nothing matches is listed as not included.

**Why was my `XP...` ID skipped?**
IDs starting with `XP` come from the winget package index — they're classic desktop installers, not Store catalog products, and the Store's catalog has no data for them. Only `9...` Store product IDs resolve.

**What are the rating windows?**
The Store tracks the rating average and count for **all-time, the last 7 days, and the last 30 days**. Comparing them shows momentum — e.g. an app whose last-30-days average is far below all-time is regressing.

**Can I get reviews in other languages/markets?**
Yes — set `market` + `language` (e.g. `DE` + `de-de`); the review pool, descriptions, and prices follow the market.

**Why is the search result count capped at 20?**
The Store's search endpoint returns about 20 results per query with no pagination cursor — so we cap honestly rather than promise more. Use more specific terms to surface different slices.

**Is `ratingCountApprox` exact?**
No — search results carry the Store's humanized count (`"332K"`); we parse it to an approximate number *and* keep the original text. For exact counts, run details mode (e.g. WhatsApp: `2294755`).

**How often is the data updated?**
It's live — every run queries the Store's current data. The actor itself is monitored by a daily canary so parsing stays correct as the endpoints evolve.

**What if the mode I picked doesn't match what I entered?**
The run follows the data you actually supplied instead of failing — and says exactly what it did in the run status message and the `RUN_SUMMARY` record (`modeNote`). `details` with only `searchTerms` runs a `search`; `search` with only `productIds` runs `details`; `reviews` with only `searchTerms` pulls the reviews of the **top search result** for each term (e.g. "whatsapp") and names the app it picked. If you fill in both, the mode you chose runs and the unused field is named, never silently dropped. This matters most for API and AI-agent (MCP) calls, where `mode` is easy to leave at its default.

### Other FreshActors tools

| FreshActors actor | What it scrapes |
|---|---|
| [App Store Scraper](https://apify.com/freshactors/app-store-scraper) | Apple App Store — app details, search, reviews |
| [Google Play Scraper](https://apify.com/freshactors/google-play-scraper) | Google Play — app details + reviews |
| [VS Code Marketplace Scraper](https://apify.com/freshactors/vscode-marketplace-scraper) | VS Code extensions — install/trending stats, search, reviews |
| [Shopify App Store Scraper](https://apify.com/freshactors/shopify-app-store-scraper) | Shopify App Store — app details, reviews, discovery |
| [Redfin Scraper](https://apify.com/freshactors/redfin-scraper) | Redfin — US real-estate listings |
| [Greenhouse & Lever Jobs Scraper](https://apify.com/freshactors/greenhouse-lever-jobs-scraper) | Greenhouse + Lever — normalized job postings |
| [Workable Jobs Scraper](https://apify.com/freshactors/workable-jobs-scraper) | Workable — normalized job postings, full descriptions |
| [SmartRecruiters Jobs Scraper](https://apify.com/freshactors/smartrecruiters-jobs-scraper) | SmartRecruiters — normalized job postings, full descriptions |
| [Recruitee Jobs Scraper](https://apify.com/freshactors/recruitee-jobs-scraper) | Recruitee — normalized job postings, full descriptions + salary |
| [Teamtailor Jobs Scraper](https://apify.com/freshactors/teamtailor-jobs-scraper) | Teamtailor — normalized job postings, full descriptions |
| [Personio Jobs Scraper](https://apify.com/freshactors/personio-jobs-scraper) | Personio — normalized job postings, departments + seniority |

### Reliability

A scheduled **daily canary** fetches known apps, validates the normalized schema (rating windows numeric, search IDs valid, review pagination advancing, helpful votes present), and alerts the moment a parse changes. The Store's endpoints serve Microsoft's own Store client and can change without notice — when they do, we patch fast and record it below. Every record carries `_schemaVersion` and `_scrapedAt`.

**Changelog**

- **2026-11-11** — **When the Microsoft Store is busy, the run says so — not "check your input".** If the Microsoft Store rate-limits us or is briefly down while a product is being fetched, that product is now named as "the Microsoft Store was not serving data — nothing is wrong with the productId; retry later". Only products that really don't exist get the "check the productId" hint.
- **2026-10-26** — **A name never turns into a different app.** An app name in `productIds` is matched only to a Microsoft Store search result whose title contains that name; if none does, the name is listed as not included. Before, the first search hit was used, so a typo could return — and bill — an unrelated app.
- **2026-10-15** — **Type an app's name where an id goes — it just works.** An app name in `productIds` (e.g. "WhatsApp") is matched to the top Microsoft Store search result and named in the run status. Entries that can't be used (winget ids, id-less URLs) are now named in the run status too, not only in the log.
- **2026-10-12** — **Runs finish within your timeout, and say exactly what is missing.** A run now knows its own timeout and stops making requests shortly before it, so it ends with the data it already collected and a clear “Stopped early” note — instead of being killed as TIMED-OUT, which looked like a failure even though your data was there. If the source stops answering partway through a multi-page pull, that item is now listed as **INCOMPLETE** in the status message and `RUN_SUMMARY` (it used to end with a plain “Done”). And when a run fails because the source was rate-limiting or not responding, the message now says so first, instead of suggesting your input was wrong.
- **2026-10-08** — **No more hung runs.** Every request now has a 30-second deadline: if the source accepts a connection but never answers, that request is retried like any other network error instead of stalling the run until its timeout (and billing compute for the wait). No change to output fields or pricing.
- **2026-09-28** — **The mode follows what you enter.** A run whose `mode` didn't match its input (most often `searchTerms` with `mode` left at the default `details` — typical of API and AI-agent calls) used to fail with "details mode requires …". It now runs what you supplied and states it in the status message and `RUN_SUMMARY.modeNote`; `reviews` by search term is new (top result per term, never charged for the lookup).
- **2026-09-23** — **Every Microsoft Store URL shape now works in *Product IDs*:** `apps.microsoft.com/detail/…`, the older `/store/detail/<name>/<id>`, `microsoft.com/store/productId/<id>`, `microsoft.com/<locale>/p/<name>/<id>` and `ms-windows-store://` links — previously only the first was recognised and the others were skipped. Apify `{ "url": "…" }` objects are accepted too.
- **2026-08-03** — Volume discounts added: app details and search results now scale down with your Apify plan tier — about **35% off at Gold** and **60% off at Diamond**, applied automatically with nothing to apply for. **Free and Bronze pay exactly what they did before — no price went up**, and the per-review price is unchanged.
- **2026-08-03** — Honest-failure fix: if none of the requested products could be fetched, the run now fails loudly and names them, instead of reporting success with zero results (a wrong answer stated confidently). Partial runs are unaffected — they keep every delivered record and list exactly what was unreachable in the run summary, so you can re-run just that slice. No change to pricing, output schema, or the behaviour of runs that return data.
- **2026-07-08** — Freshness pass: re-verified working across every mode via the daily monitoring battery; documented **x402** support (AI agents can run this actor pay-per-use with no Apify account). No change to scraping behavior, output, or pricing.
- **2026-06-11** — v1.0 launch. Details (batched, rating windows, any market) / search (full consumer coverage) / reviews (helpful votes, device family, deep offset pagination); `9*` ID validation with clear winget-ID warnings; per-item isolation; daily canary monitoring.

**Legal note:** Reads public, non-personal listing data from the Store's public endpoints (the same data the Store client serves any user). No login, no private data. Use responsibly and in line with applicable terms and laws.

*Found a problem? Open an issue on the actor — issues are answered fast.*

# Actor input Schema

## `mode` (type: `string`):

What to scrape: details (full record per app, batched), search (query the Store), or reviews (customer reviews per app).

## `productIds` (type: `array`):

Microsoft Store product IDs — 12 characters starting with 9 (e.g. 9NKSQGP7F2NH for WhatsApp) — or any Microsoft Store app URL (apps.microsoft.com or microsoft.com/store). You can also just type the app's name (e.g. WhatsApp): it is matched to the Microsoft Store search result with that name (never a guess) and named in the run status. Used by details and reviews modes. Note: XP... IDs from winget are desktop installers, not Store products, and are skipped.

## `searchTerms` (type: `array`):

Free-text queries for search mode (e.g. netflix, pdf editor, photo). One result set per term.

## `maxSearchResults` (type: `integer`):

Cap on search results returned per term (1–20). The Store's search endpoint returns about 20 results per query.

## `maxReviewsPerApp` (type: `integer`):

Cap on customer reviews returned per app (1–500), newest first.

## `market` (type: `string`):

Two-letter country code for the Store market (e.g. US, DE, GB, JP). Affects availability, prices, ratings and review pools.

## `language` (type: `string`):

Language tag for localized titles/descriptions, lowercase (e.g. en-us, de-de, fr-fr).

## Actor input object example

```json
{
  "mode": "details",
  "productIds": [
    "9NKSQGP7F2NH",
    "9NCBCSZSJRSB",
    "9WZDNCRFJ3TJ"
  ],
  "maxSearchResults": 10,
  "maxReviewsPerApp": 50,
  "market": "US",
  "language": "en-us"
}
```

# Actor output Schema

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

App details / search results / reviews, depending on the selected mode.

# 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 = {
    "productIds": [
        "9NKSQGP7F2NH",
        "9NCBCSZSJRSB",
        "9WZDNCRFJ3TJ"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("freshactors/microsoft-store-scraper").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 = { "productIds": [
        "9NKSQGP7F2NH",
        "9NCBCSZSJRSB",
        "9WZDNCRFJ3TJ",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("freshactors/microsoft-store-scraper").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 '{
  "productIds": [
    "9NKSQGP7F2NH",
    "9NCBCSZSJRSB",
    "9WZDNCRFJ3TJ"
  ]
}' |
apify call freshactors/microsoft-store-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,freshactors/microsoft-store-scraper"
        }
    }
}
```

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/yYsk8s7xOb5hwKPwV/builds/5lO6u1PWYhclhveIA/openapi.json
