# Apple App Store Review Alerts — New Reviews Only (`keratogenous_duty_n6g/app-store-new-reviews-monitor`) Actor

Monitor new or edited Apple App Store reviews without duplicates. Filter low ratings by app and country for Slack, email, n8n, or Make alerts.

- **URL**: https://apify.com/keratogenous\_duty\_n6g/app-store-new-reviews-monitor.md
- **Developed by:** [Leonhardt Tools](https://apify.com/keratogenous_duty_n6g) (community)
- **Categories:** Automation, Developer tools, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 app-country checks

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Apple App Store Review Alerts — New Reviews Only

**Catch new 1–2★ App Store complaints without reprocessing or re-alerting old reviews.**

Run once to build a silent baseline, schedule it daily, then connect the Dataset to Slack, email, n8n, Make, or your own workflow. Use an Apple bundle ID such as `com.spotify.client`, a numeric App ID, or an `apps.apple.com` URL. The Actor keeps independent state for each app × country and writes only new or edited reviews after the baseline.

> Apple controls review availability and pagination. This Actor provides best-effort incremental monitoring from Apple's public storefront feed; it does not promise complete history, real-time delivery, or zero missed reviews.

### Why this is not another review scraper

Raw review scrapers return the same recent pages every time a schedule runs. A production alert or reporting workflow then has to:

1. maintain bundle ID → numeric App ID mappings;
2. remember what each country returned last time;
3. remove duplicates before triggering email, Slack, n8n, Make, or an AI workflow;
4. avoid advancing a cursor when one target fails.

This Actor performs that recurring job. Exact identifier resolution and persistent state are the product; bulk historical scraping is not.

### Quick start

```json
{
  "apps": ["com.spotify.client"],
  "countries": ["us"],
  "mode": "delta",
  "firstRun": "baseline",
  "maxRating": 2,
  "maxPages": 1
}
````

With this alert-ready example:

- the first successful run remembers up to 50 recent reviews and sends no historical alerts;
- later runs stop after reaching reviews already present in state;
- only newly observed or edited 1–2★ reviews pass to the Dataset;
- a failed target records an error in `OUTPUT` and does not advance that target's state;
- other targets continue.

For an initial backfill instead, set `firstRun` to `emitAll` and choose the rating range you want.

### Accepted app identifiers

| Input | Example | Resolution behavior |
|---|---|---|
| Apple bundle ID | `com.spotify.client` | Exact Apple Lookup match only |
| Numeric App ID | `324684580` | Exact `trackId` match only |
| App Store URL | `https://apps.apple.com/us/app/spotify/id324684580` | Numeric ID extracted, then verified |

If an identifier is missing, unavailable in a requested storefront, ambiguous, or returns incomplete metadata, that target fails closed. The Actor never substitutes a sample app, a search result, or a default App ID.

### Inputs

| Field | Default | Meaning |
|---|---:|---|
| `apps` | required | Bundle IDs, numeric App IDs, or App Store URLs; maximum 25 |
| `countries` | `["us"]` | Two-letter Apple storefront codes; maximum 10 |
| `mode` | `delta` | `delta` reads/writes state; `snapshot` returns the current visible window without touching delta state |
| `firstRun` | `emitAll` | `emitAll` returns an initial backfill; `baseline` starts silently |
| `stateKey` | automatic | Saved Tasks use their Task ID; direct runs use a stable `direct` namespace plus resolved target keys. Set an explicit unique value for another direct workflow over the same targets |
| `resetState` | `false` | Rebuild this monitor's target state after successful scans; turn it off after the reset run |
| `maxPages` | `2` | 1–10 pages per target, up to 50 reviews per page |
| `minRating` / `maxRating` | `1` / `5` | Rating output range |
| `since` | unset | ISO 8601 output filter on Apple's `updated` timestamp |
| `versions` | unset | Exact reviewed app-version values |
| `includeKeywords` | unset | Output when title or body contains any value, case-insensitively |
| `excludeKeywords` | unset | Suppress output when title or body contains any value |

Filters affect output, not identity tracking. A review filtered out today is still remembered and does not unexpectedly become “new” when a filter changes. To intentionally backfill under a different filter, use another `stateKey` or a one-time `resetState` run.

The Actor accepts at most 25 app × country targets per run. This conservative V1 limit protects runtime and cost until larger cloud workloads are benchmarked.

### Review output

The default Dataset contains only review events. Errors and run statistics are never mixed into the review rows.

```json
{
  "schemaVersion": "1.0",
  "requestedIdentifier": "com.spotify.client",
  "bundleId": "com.spotify.client",
  "appId": "324684580",
  "appName": "Spotify: Music and Podcasts",
  "country": "us",
  "reviewId": "14289955980",
  "rating": 1,
  "title": "Example title",
  "body": "Example public review text",
  "author": "Public reviewer name",
  "appVersion": "9.1.62",
  "appleUpdatedAt": "2026-07-11T12:31:00.000Z",
  "firstSeenAt": "2026-07-13T00:10:00.000Z",
  "fetchedAt": "2026-07-13T00:10:00.000Z",
  "sourceUrl": "https://itunes.apple.com/us/review?id=324684580&type=Purple%20Software",
  "dedupeKey": "324684580:us:14289955980",
  "reviewHash": "sha256…",
  "eventKey": "324684580:us:14289955980:sha256…",
  "isNew": true,
  "isChanged": false,
  "changeType": "new"
}
```

`dedupeKey` is the stable identity of an app × country × review. `reviewHash` changes when the public author, title, body, rating, app version, or Apple `updated` value changes. `eventKey = dedupeKey + reviewHash` identifies one exact delivered version: retrying the same event keeps the same `eventKey`, while a legitimate review edit produces a new one.

Apple's public review feed exposes `updated`, but no distinct creation timestamp. The Actor therefore reports `appleUpdatedAt` and its own `firstSeenAt`; it does not invent a creation date.

Apple may return the same app-level `sourceUrl` for multiple reviews. Do not treat it as a unique review URL.

### Run summary

The default Key-Value Store record `OUTPUT` contains the machine-readable run summary and a result for every attempted target.

```json
{
  "schemaVersion": "1.0",
  "mode": "delta",
  "stateKey": "mobile-products",
  "targetsRequested": 2,
  "targetsAttempted": 2,
  "targetsSucceeded": 2,
  "targetsFailed": 0,
  "targetsSkippedDueToBudget": 0,
  "budgetLimitReached": false,
  "reviewsFetched": 100,
  "reviewsNew": 3,
  "reviewsChanged": 1,
  "reviewsFilteredOut": 2,
  "reviewsOutput": 2,
  "targets": [
    {
      "requestedIdentifier": "com.spotify.client",
      "appId": "324684580",
      "country": "us",
      "status": "succeeded",
      "pagesFetched": 1,
      "stoppedReason": "stateBoundary",
      "stateAdvanced": true
    }
  ]
}
```

Use `OUTPUT.targets[].error` for target-level failures and `warnings` for coverage conditions. The Actor does not log public review bodies.

### State and delivery semantics

- State is stored in the named Key-Value Store `app-store-review-delta-monitor-state`, separately from each run's output storage.
- Saved Tasks automatically include their Task ID in the state namespace when `stateKey` is blank. Direct runs use `direct`; the state record still includes resolved App ID + country, so changing from bundle ID to numeric ID does not reset the monitor. Use an explicit `stateKey` to isolate multiple direct workflows over the same targets.
- A target's state is written only after its scan succeeds and accepted review items have been written.
- If a spending limit accepts only part of a result batch, state is marked `pendingOutput`; the next run scans the configured window past already delivered rows so the remaining events can still be emitted.
- Dataset writes and Key-Value Store updates are not a cross-storage transaction. A platform interruption between them can produce a duplicate on retry. Delivery is therefore **at least once**. Use `eventKey` for retry-safe downstream idempotency; use `dedupeKey` only when grouping all versions of one review.
- Do not overlap two runs using the same `stateKey` and targets. Schedule the next run after the previous one can finish.

### Reliability safeguards

- Uses the fresher first-page URL without an explicit `page=1`, avoiding a stale CDN behavior reproduced during live testing.
- Constructs JSON page 2–10 URLs instead of following Apple's advertised `next` links, which can return XML or self-loop.
- Handles `feed.entry` as absent, a single object, or an array.
- Verifies exact app identity through Apple Lookup before reading reviews.
- Retries 429, 5xx, network, timeout, and malformed-JSON responses with bounded backoff.
- Rejects non-chronological pages and cross-page time reversal instead of publishing a potentially false delta.
- Rejects a whole review window—or one known review version—that moves backward relative to saved state.
- Deduplicates review IDs when pagination shifts during a run.
- Never advances a failed target's state.

### Active PPE launch pricing

PPE pricing became active at `2026-07-13T19:04:44.648Z` for build `1.0.4` (`HhOSUA2ui48AXpZtM`). It is designed around the monitoring job, not repeated historical rows:

- `apify-actor-start`: **$0.00005** per start (Apify synthetic event);
- `app-country-check`: **$0.005** per successfully fetched app × country target;
- `apify-default-dataset-item`: **$0.0001** per review event actually written.

`app-country-check` is the primary event. A run needs a maximum-charge allowance of at least **$0.00505** for one Actor start plus one successful check. Private pre-release tests verified a full 50-item run, a budget-limited 2-item run, one invalid plus one valid target, and two identifiers resolving to the same target; event counts and spending limits behaved as designed.

At the launch price, checking 5 apps across 3 countries once per day costs about **$2.25/month in successful-check events**, plus $0.0001 for each emitted new/changed review and the small start event. Invalid or inconsistent targets fail before the successful-check charge.

The user's maximum cost per run is respected. Event prices shown in the Apify Console at run time are authoritative.

Four publisher-operated cloud runs verified full output, budget-limited partial output, invalid-target isolation, and resolved-target deduplication before launch. The public Store page and anonymous Actor metadata expose the active PAY\_PER\_EVENT pricing.

### Important limits

- Apple's public storefront feed exposes at most 10 pages × 50 reviews—roughly the latest 500 reviews per app × country, not all history.
- If saved state is not reached within `maxPages`, the target fails without charging or advancing state and asks the user to raise `maxPages`. If the boundary is already outside Apple's 500-review window, the Actor cannot recover the missing history and requires an explicit reset/rebaseline.
- Reviews can appear late, move between pages, be edited, or disappear under Apple's control.
- This is scheduled polling, not real-time delivery.
- Developer replies are not available from this feed.
- iOS storefront reviews are the tested scope. macOS-only claims are intentionally not made.
- Storefront availability varies. A valid App can be unavailable in a particular country.
- The data source is a public Apple storefront endpoint, not a private App Store Connect API and not an Apple partnership.
- Public reviewer names and text are user-generated content. Apply your own privacy, retention, moderation, and downstream escaping rules.

### Local development

Requires Node.js 20+; the Actor image uses Node.js 24.

```powershell
npm install
npm test
npm run test:live
npm start
```

For a local Actor run, place input in `storage/key_value_stores/default/INPUT.json`. Do not commit real review fixtures or reviewer data.

# Actor input Schema

## `apps` (type: `array`):

Apple bundle IDs (com.company.app), numeric App IDs, or apps.apple.com URLs. Resolution is exact; unresolved identifiers fail instead of falling back to another app.

## `countries` (type: `array`):

Two-letter storefront codes. Each app × country keeps independent state.

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

Delta uses persistent state. Snapshot returns the current visible reviews without reading or changing delta state.

## `firstRun` (type: `string`):

Emit the initial backfill so the first run has useful data, or silently establish a baseline for alert-only workflows.

## `stateKey` (type: `string`):

Optional stable name for an independent monitor. Saved Tasks automatically use their Task ID when this is blank; direct runs use a stable direct namespace and resolved app-country record keys. Set a different explicit value for independent direct workflows over the same targets.

## `resetState` (type: `boolean`):

Ignore saved state for this run and replace it only after each target succeeds. Turn this off again after the reset run.

## `maxPages` (type: `integer`):

Apple exposes up to 50 reviews per page and at most 10 pages. Delta runs stop earlier after reaching saved state. If the selected window cannot reach state, the target fails without charging or advancing and asks you to increase this value.

## `minRating` (type: `integer`):

Only output reviews at or above this rating.

## `maxRating` (type: `integer`):

Set to 2 for a new low-rating alert feed.

## `since` (type: `string`):

Optional ISO 8601 date-time output filter. State still remembers filtered reviews to keep future runs idempotent.

## `versions` (type: `array`):

Optional exact version values such as 9.1.62.

## `includeKeywords` (type: `array`):

Output a review when its title or body contains any keyword, case-insensitively.

## `excludeKeywords` (type: `array`):

Do not output a review when its title or body contains any keyword, case-insensitively.

## Actor input object example

```json
{
  "apps": [
    "com.spotify.client"
  ],
  "countries": [
    "us"
  ],
  "mode": "snapshot",
  "firstRun": "emitAll",
  "resetState": false,
  "maxPages": 1,
  "minRating": 1,
  "maxRating": 5,
  "since": "2026-07-01T00:00:00Z"
}
```

# Actor output Schema

## `reviews` (type: `string`):

Versioned review event objects. In delta mode, unchanged reviews are omitted.

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

Counts, resolved targets, failures, warnings, coverage stops, and state advancement.

# 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 = {
    "apps": [
        "com.spotify.client"
    ],
    "countries": [
        "us"
    ],
    "mode": "snapshot",
    "maxPages": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("keratogenous_duty_n6g/app-store-new-reviews-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 = {
    "apps": ["com.spotify.client"],
    "countries": ["us"],
    "mode": "snapshot",
    "maxPages": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("keratogenous_duty_n6g/app-store-new-reviews-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "apps": [
    "com.spotify.client"
  ],
  "countries": [
    "us"
  ],
  "mode": "snapshot",
  "maxPages": 1
}' |
apify call keratogenous_duty_n6g/app-store-new-reviews-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=keratogenous_duty_n6g/app-store-new-reviews-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Apple App Store Review Alerts — New Reviews Only",
        "description": "Monitor new or edited Apple App Store reviews without duplicates. Filter low ratings by app and country for Slack, email, n8n, or Make alerts.",
        "version": "1.0",
        "x-build-id": "qCNXGoLUMCHNc36Wb"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/keratogenous_duty_n6g~app-store-new-reviews-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-keratogenous_duty_n6g-app-store-new-reviews-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/keratogenous_duty_n6g~app-store-new-reviews-monitor/runs": {
            "post": {
                "operationId": "runs-sync-keratogenous_duty_n6g-app-store-new-reviews-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/keratogenous_duty_n6g~app-store-new-reviews-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-keratogenous_duty_n6g-app-store-new-reviews-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "apps"
                ],
                "properties": {
                    "apps": {
                        "title": "Apps",
                        "minItems": 1,
                        "maxItems": 25,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Apple bundle IDs (com.company.app), numeric App IDs, or apps.apple.com URLs. Resolution is exact; unresolved identifiers fail instead of falling back to another app.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "countries": {
                        "title": "App Store countries",
                        "minItems": 1,
                        "maxItems": 10,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Two-letter storefront codes. Each app × country keeps independent state.",
                        "items": {
                            "type": "string",
                            "pattern": "^[A-Za-z]{2}$"
                        },
                        "default": [
                            "us"
                        ]
                    },
                    "mode": {
                        "title": "Run mode",
                        "enum": [
                            "delta",
                            "snapshot"
                        ],
                        "type": "string",
                        "description": "Delta uses persistent state. Snapshot returns the current visible reviews without reading or changing delta state.",
                        "default": "delta"
                    },
                    "firstRun": {
                        "title": "First delta run",
                        "enum": [
                            "emitAll",
                            "baseline"
                        ],
                        "type": "string",
                        "description": "Emit the initial backfill so the first run has useful data, or silently establish a baseline for alert-only workflows.",
                        "default": "emitAll"
                    },
                    "stateKey": {
                        "title": "Monitor state key",
                        "minLength": 1,
                        "maxLength": 100,
                        "type": "string",
                        "description": "Optional stable name for an independent monitor. Saved Tasks automatically use their Task ID when this is blank; direct runs use a stable direct namespace and resolved app-country record keys. Set a different explicit value for independent direct workflows over the same targets."
                    },
                    "resetState": {
                        "title": "Reset this monitor",
                        "type": "boolean",
                        "description": "Ignore saved state for this run and replace it only after each target succeeds. Turn this off again after the reset run.",
                        "default": false
                    },
                    "maxPages": {
                        "title": "Maximum pages per app × country",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Apple exposes up to 50 reviews per page and at most 10 pages. Delta runs stop earlier after reaching saved state. If the selected window cannot reach state, the target fails without charging or advancing and asks you to increase this value.",
                        "default": 2
                    },
                    "minRating": {
                        "title": "Minimum rating",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Only output reviews at or above this rating.",
                        "default": 1
                    },
                    "maxRating": {
                        "title": "Maximum rating",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Set to 2 for a new low-rating alert feed.",
                        "default": 5
                    },
                    "since": {
                        "title": "Only output reviews updated since",
                        "type": "string",
                        "description": "Optional ISO 8601 date-time output filter. State still remembers filtered reviews to keep future runs idempotent."
                    },
                    "versions": {
                        "title": "App versions",
                        "maxItems": 50,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Optional exact version values such as 9.1.62.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "includeKeywords": {
                        "title": "Include keywords",
                        "maxItems": 50,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Output a review when its title or body contains any keyword, case-insensitively.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "excludeKeywords": {
                        "title": "Exclude keywords",
                        "maxItems": 50,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Do not output a review when its title or body contains any keyword, case-insensitively.",
                        "items": {
                            "type": "string"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
