# Judge.me Review Monitor - Ratings & Merchant Replies (`maydit/judgeme-review-monitor`) Actor

Monitor published Judge.me product reviews through the public widget. Capture ratings, text and merchant replies, flag unanswered low ratings, and compare saved observations. No merchant API key.

- **URL**: https://apify.com/maydit/judgeme-review-monitor.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 review observations

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

![Reviews that need a closer look — illustrative workflow](https://api.apify.com/v2/key-value-stores/YGxD9JRpduom8Q5Zd/records/judgeme-review-monitor-54f6fd1df885.png?signature=dMLmwAAcgbJdJfqpfiIY)

### Reviews that need a closer look

For teams reviewing product feedback: collect published Judge.me ratings, review text and merchant replies from supported public product widgets. Low-rating flags help you inspect unanswered feedback without collecting reviewer contact or order data.

[Open this Actor in Console](https://console.apify.com/actors/auy4jeVd5tzHnNEJO/input) · [First run](#try-this-actor) · [Results](#result-preview) · [Cost](#usage-and-pricing) · [Full guide](#full-guide)

### Try this Actor

- **First run:** Use the existing **Owala FreeSip - Public Review Sample** below: one product, up to 10 reviews and 10 saved rows. Keep comparison off while you inspect the first result.
- **Read the results:** Open the default Dataset for review rows and the **SUMMARY** record in the default key-value store for source coverage. The review text and merchant reply columns provide the evidence behind each flag.
- **Keep in mind:** This is the widget's visible review window, not a complete review archive. A review missing from a later window does not prove deletion; comparison covers saved observations.

**Owala FreeSip - Public Review Sample** — copy this input into the JSON editor in Console.

```json
{
  "productUrls": [
    "https://owalalife.com/products/freesip"
  ],
  "maxReviewsPerProduct": 10,
  "maxResults": 10
}
```

### Result preview

The dataset view highlights these columns:

- **Product** · `productTitle`
- **Product URL** · `productUrl`
- **Review ID** · `reviewId`
- **Stars** · `stars`
- **Review title** · `title`
- **Review text** · `body`

Use the original source links and the field definitions below when interpreting the results. CSV works well for flat columns; JSON preserves nested values.

### Usage and pricing

Base result rate on the FREE tier: **$3 per 1,000 review observations**. The [Pricing tab](https://apify.com/maydit/judgeme-review-monitor/pricing) shows your plan's result rate and any Actor Start charge. Set a small result limit for the first run; the requested limit is not a guarantee of that many results.

***

### Full guide

Turn published product reviews into a repeatable feedback and reply-triage feed. The Actor reads the documented Judge.me public widget using configuration already exposed in product HTML. No merchant API key or login is required. Empty input `{}` reads up to ten public Owala FreeSip reviews.

#### What each row contains

One published review: stable `reviewId`, supplied `productUrl`, widget product ID/title, stars, review title/body, published date when provided, public merchant reply and date when provided, verified-buyer flag when exposed, observation time and optional comparison details. `isLowRating` uses your threshold; `needsMerchantReply` requires both a low rating and no visible reply. These are flags, not filters.

Reviewer names, contacts, location, avatar, and order/customer information are omitted. The storefront's public widget token is used only in a request header and is never included in output, history or logs. The Actor does not request private review APIs, unpublished reviews, customer records or merchant credentials.

The product page must expose `jdgm.SHOP_DOMAIN`, `jdgm.PUBLIC_TOKEN` and one unambiguous `.jdgm-review-widget` product ID in its HTML. Browser-only or customized integrations that hide those values are unsupported. Public review text is source content, not verified evidence that a purchase or event occurred.

#### Inputs and historical coverage

- `productUrls`: up to 30 public product page URLs. Empty input uses the Owala example.
- `maxReviewsPerProduct`: 10 by default, up to 1,000 inspected identities, including unchanged ones.
- `maxPagesPerProduct`: 10 by default, up to 100 public widget pages.
- `maxResults`: 100 saved reviews by default, up to 10,000.
- `lowRatingThreshold`: 3 by default, from 1 to 5. All inspected reviews are returned unless onlyChanges suppresses unchanged ones.
- `comparePrevious`, `onlyChanges`, `snapshotName`, `maxRunSeconds`: described below.

Coverage is the **published review window exposed by the widget**. The source controls ordering and visibility. `reportedReviewCount` is source metadata, not a promise that this run retrieved that many reviews. Pagination can shift as reviews are published. Replies or edits to reviews outside the selected window are not detected; increase the window for broader checks. A disappearing review is not treated as deleted. Dates or reply dates absent from widget markup remain null.

#### Three example inputs

##### Owala FreeSip - Public Review Sample

Read up to ten published widget reviews with ratings, text and merchant reply status.

Use the [copyable first-run input](#try-this-actor) above.

##### Owala FreeSip - Low Rating Reply Triage

Inspect a 50-review window and flag ratings of one or two stars that lack a visible merchant reply. All inspected reviews are returned.

```json
{
  "productUrls": [
    "https://owalalife.com/products/freesip"
  ],
  "maxReviewsPerProduct": 50,
  "maxResults": 50,
  "lowRatingThreshold": 2
}
```

##### Owala FreeSip - Merchant Reply History

Compare a 20-review window against saved observations and identify visible review edits and merchant reply changes. First run establishes a baseline.

```json
{
  "productUrls": [
    "https://owalalife.com/products/freesip"
  ],
  "maxReviewsPerProduct": 20,
  "maxResults": 20,
  "comparePrevious": true,
  "snapshotName": "owala-replies"
}
```

#### Saved observations and change detection

`comparePrevious: true` enables persistent, named comparison history. `onlyChanges: true` also enables comparison and suppresses unchanged rows. The first observation emits `comparisonStatus: "baseline"`; later rows are `new`, `changed`, or `unchanged`. Without comparison they are `not_requested`. `changedFields`, `changeTypes` and `previous` explain each comparison.

Only confirmed saved rows update history. Existing records outside the selected window are retained. A partial run never establishes removals, and neither Actor emits deletion events. Comparison means **last successfully saved observation**, not an uninterrupted history of every change between runs. The state limit is 50,000 identities per source and snapshot name.

Run a given snapshot name sequentially. A reread detects an already changed snapshot before writing and reports a conflict, but this is not a transactional lock. Dataset and history writes are separate: a storage failure can leave saved rows without a new baseline; retrying may repeat observations. Use distinct names for independent workflows.

#### Coverage, limits and failures

`maxResults` caps saved rows across sources. Source/product/page limits select a bounded sample and are reported through `SUMMARY.sourceCoverage`, including `hasMore`; reaching a selected cap is not itself an operational failure. Always inspect SUMMARY before interpreting an empty or partial dataset. The output tab links to both results and SUMMARY.

Requests honor robots.txt, reject nonpublic network destinations and unsafe redirects, and stay within `maxRunSeconds` (default 240, range 30–3600) and 25 seconds before the platform deadline. HTTP 429, server errors and transient connection failures receive at most two bounded retries, honoring Retry-After. No browser rendering, login, proxy or anti-bot bypass is used.

Failures appear in `failedSources`, never as data rows. If all sources fail before usable output, the run fails. Genuine empty results or no changes produce a warning and succeed. Spending limits stop output cleanly, preserve existing rows, and prevent unsaved observations from advancing history. A source outage, robots restriction or time limit can produce partial coverage.

#### Development

Node 20 Docker image; exact Apify SDK 3.7.2 and Cheerio 1.1.2 lockfile. `npm ci` installs dependencies and `npm test` runs offline regression tests. `npm start` reads the normal Apify INPUT record. Public storefronts may change independently of this Actor.

#### Pricing

Planned pay-per-result rate: **$3.00 per 1,000 saved review observations**, plus the configured Actor-start event. The current Apify pricing tab is authoritative. An unchanged row is billable when saved; `onlyChanges` avoids saving unchanged rows. Errors are not dataset results.

#### Source documentation

[Judge.me API help](https://judge.me/help/en/articles/8409180-using-judge-me-api) · [Official OpenAPI definition](https://judge.me/api/docs.yaml)

### Help with your run

Open the **Issues** tab on this Actor with the run URL, the input field that caused trouble and what you expected to receive. Remove API keys and private information before posting.

[Explore more Mayd-It Actors](https://apify.com/maydit)

### Understand your run

Open **Run report** in the run’s Output tab for saved-record counts, reported source issues and limits, and suggested next steps. Use **CSV export** to take the saved results into a spreadsheet. The existing JSON results and detailed machine-readable summary remain available.

The report reflects this run’s recorded coverage. A successful run or a saved result does not establish that every possible source record was collected.

# Actor input Schema

## `productUrls` (type: `array`):

Up to 30 public product pages exposing Judge.me SHOP_DOMAIN, PUBLIC_TOKEN and a review widget product ID. Empty input uses Owala FreeSip. Browser-only widgets are unsupported.

## `maxReviewsPerProduct` (type: `integer`):

Maximum distinct reviews inspected per product, including unchanged reviews. This is a visible widget window, not a guarantee of full historical coverage.

## `maxPagesPerProduct` (type: `integer`):

Maximum documented public widget pages requested. Reviews outside the selected window cannot have edits or replies detected.

## `lowRatingThreshold` (type: `integer`):

Ratings at or below this value are flagged isLowRating. needsMerchantReply additionally requires no visible merchant reply. This flags rows; it does not filter them.

## `maxResults` (type: `integer`):

Stop after this many saved rows across all sources. This is a selected sample limit, not proof of complete source coverage.

## `comparePrevious` (type: `boolean`):

Compare against this snapshot name. First observation emits baseline rows; only successfully saved rows advance history. Run the same snapshot name sequentially.

## `onlyChanges` (type: `boolean`):

Also enables comparison. First run emits baseline rows. Later unchanged observations produce no rows; this can legitimately return an empty dataset.

## `snapshotName` (type: `string`):

Named persistent history, isolated by source. Use 1–40 letters, digits, hyphens or underscores. Do not run the same name concurrently.

## `maxRunSeconds` (type: `integer`):

Own deadline, also shortened to 25 seconds before the platform timeout. Requests and retry delays stay within the remaining time.

## Actor input object example

```json
{
  "maxReviewsPerProduct": 10,
  "maxPagesPerProduct": 10,
  "lowRatingThreshold": 3,
  "maxResults": 100,
  "comparePrevious": false,
  "onlyChanges": false,
  "snapshotName": "default",
  "maxRunSeconds": 240
}
```

# Actor output Schema

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

One confirmed public observation per dataset row. Failures are recorded in SUMMARY, never as paid error rows.

## `runReport` (type: `string`):

Readable summary of saved records, reported source coverage, limits and next steps. Available when this run saves its SUMMARY.

## `csvExport` (type: `string`):

Download saved dataset records as a CSV file for spreadsheets and other tools.

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

Saved counts, selected scope, pagination coverage, failed sources, and time or spending limits.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/judgeme-review-monitor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("maydit/judgeme-review-monitor").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 '{}' |
apify call maydit/judgeme-review-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/judgeme-review-monitor"
        }
    }
}
```

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/auy4jeVd5tzHnNEJO/builds/jk7J4QGyGyfDEadql/openapi.json
