# PissedConsumer Reviews Scraper — complaints & new reviews (`northbell/pissedconsumer-reviews-scraper`) Actor

Reviews and complaints about any company on PissedConsumer: title, full text, stars, date, location, preferred solution, plus the company rating. Many companies in one run, and only the new reviews since the last run for monitoring. No login.

- **URL**: https://apify.com/northbell/pissedconsumer-reviews-scraper.md
- **Developed by:** [Northbell](https://apify.com/northbell) (community)
- **Categories:** Marketing, Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 1,000 reviews

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

## PissedConsumer Reviews Scraper — complaints & new reviews

Read the reviews and complaints about any company on **PissedConsumer**: **title, full text, stars, date, the reviewer's city and state, the solution they asked for and their recommendation**, plus the company's average rating and number of reviews. Many companies in one run. **$0.50 per 1,000 reviews**, no login, no API key.

Built for watching complaints: switch on *Only new reviews since the last run* and every run returns just the reviews you have not seen yet, for your own company or your competitors. A run that finds nothing new costs only the $0.0005 start fee.

### What you get

| Field | What it is |
|---|---|
| `reviewId`, `company`, `companyName` | the review's number on PissedConsumer, the company's PissedConsumer name (`comcast`) and its display name |
| `title`, `text` | the review's headline and its full text (paragraphs kept) |
| `rating` | the stars, 1 to 5 (empty when the reviewer gave none) |
| `userName` | the reviewer's display name as shown (empty with *Leave out people's names*) |
| `publishedAt` | when it was posted (UTC) |
| `location` | the reviewer's city and state, when shown (`Vancouver, Washington`) |
| `preferredSolution`, `recommendation` | the solution the reviewer asked for (`Full refund`) and their advice to others, when given |
| `isVerifiedReviewer` | whether PissedConsumer marks the reviewer as verified |
| `reviewUrl`, `pageUrl` | the review's own page (longer reviews have one) and the list page it was read from |
| `isNewSinceLastRun`, `firstSeenAt` | the change since your previous run for the same company: empty on the first run |
| `observedAt` | when this row was read |

Every company also gets one free `summary` row: `name`, `averageRating`, `ratedReviews`, `totalReviewsShown` (as the site shows it, `7.2K`), `website`, `pagesOnSite`, `reviewsRead`, `reviewsReturned`, `newSinceLastRun`, `filteredOut`, `pagesFetched`, `firstRun` and `stoppedBecause` (`limit`, `end-of-list`, `reached-last-run`, `reached-since`, `time-limit`, `charge-limit` or `error`). A company that cannot be read gives a free `error` row.

Shape of a row (shortened):

```json
{
  "type": "review", "reviewId": "7503153", "company": "comcast", "companyName": "Comcast",
  "title": "Horrible Customer service and resolution of problems",
  "text": "Moved 5 months ago, contacted Comcast, and told them I needed to switch my service to my new address …",
  "rating": 1, "publishedAt": "2026-09-18T22:08:25.000Z", "location": null,
  "preferredSolution": "Full refund", "recommendation": "Do not use this company", "isVerifiedReviewer": true,
  "reviewUrl": "https://comcast.pissedconsumer.com/horrible-customer-service-and-resolution-of-problems-202609187503153.html",
  "pageUrl": "https://comcast.pissedconsumer.com/review.html",
  "isNewSinceLastRun": true, "firstSeenAt": "2026-10-19T06:26:02.631Z", "observedAt": "2026-10-19T06:26:02.631Z"
}
```

### Run it again and again

- **On a schedule**: save your input as a task and add a **Schedule**: every hour or every morning. Send each run to Slack, Discord, Telegram, Google Sheets or email with an integration on the task.
- **Watch for changes**: Turn on **Only new reviews since the last run**.
- **In bulk**: Put your company and all your competitors in **Companies** in one run.

### Use it for

- **Customer care and reputation teams**: every new complaint about your company the day it is posted, with the solution the customer asks for
- **Competitor research**: what customers of your competitors complain about, and how angry they are
- **Product and service teams**: recurring problems in the customers' own words, by star rating and date
- **Market research and analysts**: complaint volume and ratings across a whole industry

### Input

```json
{
  "companies": ["Comcast", "AT&T", "https://xfinity.pissedconsumer.com/review.html"],
  "maxReviewsPerCompany": 100,
  "onlyNew": true,
  "since": "2026-09-01",
  "maxRating": 2,
  "includeUnrated": true
}
```

- **companies**: company names as on PissedConsumer, or the address of the company's reviews page.
- **maxReviewsPerCompany**: how many reviews to read per company, 15 per page (default 100, up to 10,000).
- **onlyNew**: return only reviews you have not seen in an earlier run for the same company.
- **since**: leave out reviews posted before this day.
- **minRating**, **maxRating** — keep only reviews in this star range. **includeUnrated** — keep reviews without stars (default on).

The memory behind *since the last run* is kept per company in a named key-value store in your Apify account, so the second run already shows what is new.

### Pricing

**$0.50 per 1,000 reviews** ($0.0005 each), plus $0.0005 per run. Summary rows and error rows are free. With *Only new reviews* you pay only for the reviews returned, so a daily check of 5 companies that finds 10 new reviews costs about $0.006.

### Notes

- **Public data only**: what anyone sees on PissedConsumer without signing in. `userName` is the reviewer's display name as the site shows it; the profile and picture are not returned, and neither are the comments under a review. Turn on **Leave out people's names** (`omitPersonalNames`) and `userName` stays empty: useful for GDPR-minded projects in the EU that should hold no personal data.
- **Speed**: one page of 15 reviews every 1.5 seconds. 100 reviews take about 10 seconds; the deepest companies have around 500 pages.
- **Order**: PissedConsumer lists reviews roughly newest first, but not strictly (a page can mix reviews from several months). So *Only new reviews* stops after two pages in a row where every review was already seen, and *since* stops at the first page where every review is older than your date.
- **Company names**: the Actor turns the name into the company's address on PissedConsumer (`Comcast` → comcast.pissedconsumer.com, `Bank of America` → bank-of-america, `AT&T` → att). If that is not the company's page, paste the page's address instead.
- **Text** is the full review as shown on the list page; longer reviews also have their own page in `reviewUrl`.
- If PissedConsumer refuses the requests the company gets an error row; busy responses (429) and connection errors are retried twice. The Actor does not get around bot checks.

### For AI agents

`{"companies": ["Comcast"], "maxReviewsPerCompany": 30, "maxRating": 2}` returns up to 30 one- and two-star reviews (and reviews without stars) about Comcast, plus one summary row with the company's average rating. Rows have `type`: `review`, `summary` or `error`. To watch over time, call it again with the same companies and `"onlyNew": true`: every review row returned is new since the previous call.

# Actor input Schema

## `companies` (type: `array`):

One per line: the company's name as on PissedConsumer (Comcast, AT\&T, Bank of America) or the address of its reviews page (https://comcast.pissedconsumer.com/review.html). If a name is not found, open pissedconsumer.com, find the company and paste the address of its page.

## `maxReviewsPerCompany` (type: `integer`):

How many reviews to read for each company, 15 per page, up to 10,000. With "Only new reviews" switched on, this is how deep to look; only the new ones are returned and charged.

## `onlyNew` (type: `boolean`):

Return only reviews you have not seen in an earlier run for the same company. The first run has nothing to compare with and returns everything it read. Good for a daily or hourly check: a run that finds nothing new costs only the start fee.

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

Leave out reviews posted before this day (YYYY-MM-DD).

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

Only reviews with at least this many stars (1 to 5).

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

Only reviews with at most this many stars (1 to 5). For example 2 for the angriest complaints.

## `includeUnrated` (type: `boolean`):

About a third of the reviews have no star rating. They are kept unless you switch this off, also when you set minimum or maximum stars.

## `omitPersonalNames` (type: `boolean`):

Off: names and handles are returned as shown publicly. On: they are left out (empty), for GDPR-minded projects that need no personal data.

## Actor input object example

```json
{
  "companies": [
    "Comcast"
  ],
  "maxReviewsPerCompany": 100,
  "onlyNew": false,
  "includeUnrated": true,
  "omitPersonalNames": false
}
```

# Actor output Schema

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

Title, full text, stars, date and location of each review or complaint.

## `companies` (type: `string`):

One row per company: average rating, number of reviews, and how many were read, returned and new since the last run.

# 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 = {
    "companies": [
        "Comcast"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("northbell/pissedconsumer-reviews-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 = { "companies": ["Comcast"] }

# Run the Actor and wait for it to finish
run = client.actor("northbell/pissedconsumer-reviews-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 '{
  "companies": [
    "Comcast"
  ]
}' |
apify call northbell/pissedconsumer-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,northbell/pissedconsumer-reviews-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/fz0Q7iNbPAGbqyclB/builds/eXED80m91b5og4MiU/openapi.json
