# Official Complaint Auditor (`skootle/public-review-inventory-auditor`) Actor

Audit official CFPB and NHTSA public complaint inventories with normalized records, source status, provenance, deterministic snapshots, API output, scheduling, monitoring, and integrations.

- **URL**: https://apify.com/skootle/public-review-inventory-auditor.md
- **Developed by:** [Skootle](https://apify.com/skootle) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 official complaint inventory records

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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

<!-- skootle:growth-loop-hook -->
## Official Public Complaint Inventory Auditor

**Audit official public complaint inventories for companies and vehicles, preserve source provenance, and export normalized evidence for monitoring, due diligence, and agent workflows.** Run it from the Apify Console, call it through the API, or schedule recurring snapshots.

![Official public complaint inventory audit](https://raw.githubusercontent.com/kesjam/skootle-actors-assets/main/heroes/public-review-inventory-auditor.png)

### TL;DR

Give the Actor one or more company or vehicle entities. It queries only official government open-data APIs:

- CFPB Consumer Complaint Database for company complaint inventory.
- NHTSA Vehicle Complaints API for make, model, and model-year complaint inventory.

You receive:

- `source_status` rows that state whether each official source was available, partial, rate limited, unavailable, or invalid.
- `public_record` rows with normalized public complaint facts and source IDs.
- `inventory_summary` rows with counts, category distributions, response distributions, and deterministic snapshot hashes.
- One `run_summary` with source completion, errors, truncation, redaction counts, runtime, and source versions.
- `AGENT_BRIEFING.md` in the default key-value store for downstream review or automation.

This Actor does not scrape review websites, ratings, stars, social profiles, or HTML pages. It does not claim that complaint volume measures quality, fault, prevalence, or market share. It reports public complaint records with their official provenance.

<!-- skootle:review-cta -->
If the Actor saves you a manual export or makes an audit repeatable, share a short review on its Apify Store page.

### What does Official Public Complaint Inventory Auditor do?

The Actor turns two different official government data sources into one bounded output contract. CFPB and NHTSA expose different identifiers, fields, response shapes, and filtering rules. This Actor applies strict inputs, bounded retries, explicit status records, privacy redaction, deterministic normalization, and schema-valid output so buyers do not need to build and maintain that glue themselves.

For each compatible entity and source, the Actor:

1. Validates the entity shape and requested source combination.
2. Builds a request only for a fixed official endpoint.
3. Applies a 12-second request timeout and up to three bounded attempts for retryable failures.
4. Validates the returned JSON structure before trusting counts or rows.
5. Verifies CFPB company identity against the requested exact name or an explicitly supplied alias.
6. Normalizes public complaint fields without inventing missing values.
7. Redacts VIN-like identifiers and ZIP codes when optional narrative text is enabled.
8. Emits a source status even when an official query returns a valid empty set.
9. Computes a deterministic snapshot hash that excludes retrieval time.
10. Fails the run by default when an expected source cannot be proven healthy.

The result is useful as a current inventory, a scheduled monitoring input, a quality-controlled research export, or an evidence substrate for a human or agent. It is not a reputation score.

### Why use official complaint data instead of scraping reviews?

Public reviews and official complaints answer different questions. Review sites summarize customer opinions under platform-specific moderation and account rules. CFPB and NHTSA publish complaint records under government data programs with official identifiers and program-specific metadata.

This Actor is appropriate when the buyer needs questions such as:

- Which public complaint records are currently returned by an official source?
- How many official records are available for a named company or vehicle configuration?
- Which product, issue, component, response, crash, fire, injury, or death fields are present?
- Did the source return a real empty result, or did the source fail?
- Can two scheduled runs be compared without retrieval timestamps changing the snapshot hash?
- Can a downstream workflow keep the source ID and provenance attached to every record?

It is not appropriate when the buyer needs star ratings, reviewer profiles, sentiment from review text, private case records, legal conclusions, or a representative measure of product safety or company quality.

### Which official sources are supported?

#### CFPB Consumer Complaint Database

The Consumer Financial Protection Bureau publishes a searchable public complaint database. This Actor uses the official CFPB search API and requires a `company` entity. The requested company name and optional aliases are explicit inputs. Returned rows must identify exactly one company and match the requested name or one declared alias. Ambiguous identity fails closed.

Official information: https://www.consumerfinance.gov/data-research/consumer-complaints/

#### NHTSA Vehicle Complaints API

The National Highway Traffic Safety Administration publishes public vehicle complaint data. This Actor uses the official `complaintsByVehicle` endpoint and requires a `vehicle` entity with make, model, and model year.

Official endpoint information: https://api.nhtsa.gov/complaints/complaintsByVehicle

The Actor does not accept arbitrary URLs, alternate API hosts, browser instructions, credentials, cookies, or user-provided request headers. That fixed-source design removes an SSRF surface and keeps the source contract auditable.

### Input

The `entities` array is a strict union. A company and a vehicle use different required fields.

```json
{
  "entities": [
    {
      "id": "example-financial",
      "kind": "company",
      "name": "EXAMPLE FINANCIAL, INC.",
      "aliases": ["EXAMPLE FINANCIAL"]
    },
    {
      "id": "camry-2020",
      "kind": "vehicle",
      "make": "Toyota",
      "model": "Camry",
      "modelYear": 2020
    }
  ],
  "sources": ["cfpb", "nhtsa"],
  "dateFrom": "2024-01-01",
  "dateTo": "2026-07-24",
  "maxRecordsPerEntitySource": 100,
  "includeNarratives": false,
  "failOnSourceError": true
}
````

#### Input limits

- 1 to 10 entities per run.
- 1 to 500 records per compatible entity/source pair.
- Maximum requested total of 2,000 public records per run.
- Company IDs and vehicle IDs must be unique and URL-safe.
- CFPB requires at least one company entity.
- NHTSA requires at least one vehicle entity.
- `dateTo` cannot be before `dateFrom`.
- Narratives are disabled by default.
- Source errors fail the run by default.

These limits prevent accidental unbounded collection and make buyer cost easier to predict.

### Output records

#### `source_status`

Every compatible entity/source pair gets one source status. This is the first row to inspect when a scheduled run changes.

```json
{
  "recordType": "source_status",
  "source": "nhtsa",
  "entityId": "camry-2020",
  "status": "available",
  "queriedAt": "2026-07-24T10:00:00.000Z",
  "retrievedAt": "2026-07-24T10:00:00.000Z",
  "httpStatus": 200,
  "matchedIdentity": "2020 Toyota Camry",
  "matchMethod": "exact",
  "matchConfidence": 1,
  "availableCount": 0,
  "fetchedCount": 0,
  "truncated": false,
  "provenanceUrl": "https://api.nhtsa.gov/complaints/complaintsByVehicle"
}
```

A zero count is meaningful only when `status` is `available` and the official response passed schema checks. An unavailable source is never converted into a healthy zero.

#### `public_record`

Each normalized complaint keeps its official source record ID and provenance.

```json
{
  "recordType": "public_record",
  "source": "nhtsa",
  "sourceRecordId": "OFFICIAL-SOURCE-ID",
  "entityId": "camry-2020",
  "recordKind": "complaint",
  "retrievedAt": "2026-07-24T10:00:00.000Z",
  "receivedDate": "2025-01-15",
  "incidentDate": "2025-01-10",
  "productOrComponent": "SERVICE BRAKES",
  "issueOrCategory": "SERVICE BRAKES",
  "companyOrManufacturer": "MANUFACTURER FROM OFFICIAL RECORD",
  "safetyFlags": {
    "crash": false,
    "fire": false,
    "injuries": 0,
    "deaths": 0
  },
  "provenanceUrl": "https://api.nhtsa.gov/complaints/complaintsByVehicle"
}
```

The example shows the output shape. Values are not a claim about a particular current complaint. Run the Actor for current official records.

#### `inventory_summary`

The summary is designed for snapshot comparisons and dashboards.

```json
{
  "recordType": "inventory_summary",
  "source": "nhtsa",
  "entityId": "camry-2020",
  "recordKind": "complaint",
  "retrievedAt": "2026-07-24T10:00:00.000Z",
  "fetchedCount": 100,
  "categoryCounts": {
    "SERVICE BRAKES": 12,
    "ELECTRICAL SYSTEM": 9
  },
  "responseCounts": {},
  "snapshotHash": "deterministic-sha256-of-normalized-records",
  "provenanceUrl": "https://api.nhtsa.gov/complaints/complaintsByVehicle"
}
```

The snapshot hash excludes `retrievedAt`. If the normalized official records do not change, the hash remains stable across runs.

#### `run_summary`

The final row makes partial or failed evidence visible to automation.

```json
{
  "recordType": "run_summary",
  "retrievedAt": "2026-07-24T10:00:00.000Z",
  "requestedSources": ["nhtsa"],
  "completedSources": ["nhtsa"],
  "requestedEntities": 1,
  "outputCounts": {
    "source_status": 1,
    "public_record": 100,
    "inventory_summary": 1
  },
  "errors": [],
  "truncated": true,
  "privacyRedactions": 0,
  "runtimeMs": 850,
  "sourceVersions": {
    "cfpb": "consumer-complaint-search-api-v1",
    "nhtsa": "complaintsByVehicle-v1"
  }
}
```

### Worked example 1: audit one vehicle configuration

Start with the prefilled input:

```json
{
  "entities": [
    {
      "id": "camry-2020",
      "kind": "vehicle",
      "make": "Toyota",
      "model": "Camry",
      "modelYear": 2020
    }
  ],
  "sources": ["nhtsa"],
  "maxRecordsPerEntitySource": 100,
  "includeNarratives": false,
  "failOnSourceError": true
}
```

Use the resulting `source_status` to verify source health. Use `inventory_summary.snapshotHash` to compare this configuration with a later scheduled run. Use `public_record.safetyFlags` only as fields reported in the public complaint record, not as verified findings.

### Worked example 2: compare model years

Create two vehicle entities with distinct IDs:

```json
{
  "entities": [
    { "id": "camry-2020", "kind": "vehicle", "make": "Toyota", "model": "Camry", "modelYear": 2020 },
    { "id": "camry-2021", "kind": "vehicle", "make": "Toyota", "model": "Camry", "modelYear": 2021 }
  ],
  "sources": ["nhtsa"],
  "maxRecordsPerEntitySource": 200,
  "includeNarratives": false,
  "failOnSourceError": true
}
```

Group summaries by `entityId`. Do not divide complaint counts by sales, registrations, or exposure unless you have a separate authoritative denominator. Raw complaint count alone is not a rate.

### Worked example 3: audit a company by exact CFPB identity

```json
{
  "entities": [
    {
      "id": "example-financial",
      "kind": "company",
      "name": "EXAMPLE FINANCIAL, INC.",
      "aliases": ["EXAMPLE FINANCIAL"]
    }
  ],
  "sources": ["cfpb"],
  "dateFrom": "2025-01-01",
  "maxRecordsPerEntitySource": 100,
  "includeNarratives": false,
  "failOnSourceError": true
}
```

Replace the placeholder with the exact public CFPB company identity you intend to query. Aliases are not fuzzy matching. They are explicit allowed identities. If the returned rows contain an ambiguous or different company identity, the source fails closed.

### Worked example 4: create a weekly change monitor

1. Run a bounded input and save each `inventory_summary`.
2. Schedule the same input weekly through Apify.
3. Join snapshots by `source` and `entityId`.
4. Compare `snapshotHash`, `fetchedCount`, category counts, and source status.
5. Alert only when the source is available and a meaningful field changed.
6. Keep unavailable runs as operational evidence rather than overwriting the last successful snapshot.

This workflow distinguishes source health from domain change. A government API outage does not prove that complaint inventory fell to zero.

### Worked example 5: include public narratives with redaction

Set `includeNarratives` to true only when the text is needed:

```json
{
  "entities": [
    { "id": "camry-2020", "kind": "vehicle", "make": "Toyota", "model": "Camry", "modelYear": 2020 }
  ],
  "sources": ["nhtsa"],
  "maxRecordsPerEntitySource": 25,
  "includeNarratives": true,
  "failOnSourceError": true
}
```

VIN-like strings and ZIP codes are replaced with `[REDACTED_IDENTIFIER]`. The final summary reports the number of redactions. The Actor does not promise that every possible identifier can be detected in free text. Buyers should apply their own downstream privacy review before redistribution.

### Worked example 6: allow an explicit partial result

For exploratory work, `failOnSourceError` can be set to false. A failed source still emits a non-healthy `source_status`, and `run_summary.errors` remains nonempty.

```json
{
  "entities": [
    { "id": "camry-2020", "kind": "vehicle", "make": "Toyota", "model": "Camry", "modelYear": 2020 }
  ],
  "sources": ["nhtsa"],
  "maxRecordsPerEntitySource": 50,
  "includeNarratives": false,
  "failOnSourceError": false
}
```

Do not use this setting when a complete source check is required. The default fail-closed mode is safer for monitoring and production workflows.

### How do I run it through the Apify API?

After the Actor is available in your account, send the same JSON input to the standard Apify Actor run endpoint or use the Apify client library. The dataset ID on the run points to normalized rows. The default key-value store contains `AGENT_BRIEFING.md`.

A generic API pattern is:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/skootle~public-review-inventory-auditor/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d @input.json
```

Keep tokens in your secret manager or environment. Do not place tokens in input, source code, logs, README examples, or datasets.

### How can I integrate the output?

Apify datasets can be consumed by:

- A database or warehouse ingestion job.
- Google Sheets or another supported Apify integration.
- A webhook that starts only after a successful run.
- A monitoring service that compares snapshot hashes.
- A research notebook that keeps official source IDs attached.
- An agent that reads `AGENT_BRIEFING.md` before opening detailed rows.

A safe downstream workflow should preserve `source`, `sourceRecordId`, `entityId`, `retrievedAt`, and `provenanceUrl`. It should not merge records across companies or vehicles merely because names look similar.

### How much does it cost?

The Actor uses pay-per-result pricing with a small run-start event and a dataset-item event. The live Apify pricing panel is the source of truth for current amounts. A buyer-controlled maximum total charge remains enabled by default.

Cost depends on:

- Number of compatible entities.
- Selected official sources.
- Maximum records requested per entity/source pair.
- Number of rows returned by the official APIs.

The Actor does not use a browser or proxy, which keeps compute use low. Start with one entity and a small record cap, inspect the output, and scale only when the result contract fits your workflow.

### Is it legal to use official public complaint data?

The sources are public government data services, but public availability does not remove every legal, policy, privacy, attribution, or fairness responsibility. Review the current source documentation and terms for your use case. Preserve provenance. Do not present consumer allegations as adjudicated facts. Do not use complaint counts as a discriminatory eligibility rule or as a substitute for professional, legal, safety, or financial judgment.

This Actor does not provide legal advice. It does not bypass access controls, authentication, CAPTCHAs, paywalls, or platform restrictions. It does not scrape third-party review sites.

### Privacy and responsible use

- Narratives are off by default.
- VIN-like strings and ZIP codes are redacted when narratives are enabled.
- The Actor does not request reviewer names, contact data, cookies, credentials, or private case files.
- The Actor does not accept arbitrary URLs.
- Outputs can still contain sensitive public allegations or contextual facts. Review them before sharing.
- Follow your retention, access-control, and deletion policies.
- Preserve the source program's disclaimers and provenance.

### Reliability and failure semantics

The Actor deliberately distinguishes these states:

- `available`: official JSON passed schema checks, including a valid empty response.
- `rate_limited`: the official source returned a rate-limit condition after bounded retries.
- `upstream_error`: a retryable server or request failure remained unresolved.
- `unavailable`: the source returned a non-retryable failure or company identity could not be verified.
- `partial`: reserved for explicitly incomplete source evidence.
- `invalid_input`: the entity or source pairing is invalid.

With `failOnSourceError: true`, a source error fails the Actor run. The production wrapper calls `Actor.fail()` on fatal errors. It does not use an unconditional successful exit from a `finally` block.

### Limitations

- CFPB company names must match exactly or match a declared alias.
- NHTSA queries are limited to make, model, and model year supported by the official endpoint.
- Date filters apply only where the official source supports them.
- Category names differ across CFPB and NHTSA and are not forced into one artificial taxonomy.
- Public complaints are allegations and reports, not verified findings.
- Complaint volume is not normalized by customers, transactions, vehicles, miles, or exposure.
- Optional redaction is bounded and cannot guarantee removal of every identifier in free text.
- Government APIs can change schemas, rate limit, or become unavailable.
- The Actor does not provide review ratings, sentiment analysis, legal conclusions, recall status, or safety scores.

### FAQ

#### Can I query CFPB and NHTSA in one run?

Yes. Include both a company entity and a vehicle entity, then select both sources. Incompatible entity/source pairs are skipped, while each compatible pair is processed and reported.

#### Can I provide a business website or arbitrary API URL?

No. The Actor uses fixed official endpoints and strict entity fields. It does not fetch user-provided URLs.

#### Does a zero result mean there are no complaints anywhere?

No. It means the named official query returned a valid empty result at the recorded time. Always preserve source, identity, filters, and retrieval time.

#### Are complaint narratives included?

Not by default. Enable `includeNarratives` explicitly. VIN-like strings and ZIP codes are redacted before output, but downstream privacy review remains necessary.

#### Can I use fuzzy company matching?

No. The Actor uses the exact requested company name or explicitly declared aliases. This reduces false attribution.

#### Can I schedule the Actor?

Yes. Use Apify schedules with a stable input. Compare `snapshotHash` only when source status is healthy.

#### Can I export CSV, JSON, or Excel-compatible data?

Yes. Apify datasets support standard export formats. Nested fields may need flattening for some spreadsheet workflows.

#### Does the Actor decide whether a company or vehicle is safe?

No. It inventories official public complaint records. It does not compute a safety, quality, trust, fault, or legal score.

#### What happens when an official API changes?

Schema validation or source checks fail instead of silently producing empty healthy data. The source status and run error identify the affected source.

#### Can I use the output with an LLM or agent?

Yes. Start with `AGENT_BRIEFING.md`, then retrieve only relevant dataset rows. Keep source IDs and provenance attached, and require human review for consequential decisions.

### Support and feedback

When reporting a problem, include the Actor run ID, source name, entity ID, source status, and a redacted input shape. Do not send tokens, cookies, private account data, or full sensitive narratives.

Useful feature requests include additional official open-data sources with clear commercial-use and privacy boundaries, stronger normalized taxonomies that preserve source semantics, and new bounded summary records. Third-party review scraping, login bypass, and arbitrary URL collection are outside this Actor's contract.

### Other Skootle Actors you may find useful

The Skootle Apify portfolio includes official-data, website audit, research, safety, and market-intelligence Actors. Browse the current portfolio at https://apify.com/skootle and choose the Actor whose source contract matches the decision you need to support.

### Source and non-affiliation notice

This Actor is independently operated by Skootle. It is not affiliated with, endorsed by, or sponsored by CFPB, NHTSA, or Apify. Source names identify the official public data programs queried. The official source remains authoritative.

### Final buyer checklist

Before using output in a production decision:

1. Confirm each required `source_status` is `available`.
2. Confirm the returned identity matches the entity you intended.
3. Check truncation and record limits.
4. Preserve official IDs and provenance.
5. Distinguish allegation from verified fact.
6. Add an exposure denominator before comparing raw counts as rates.
7. Review narratives and privacy boundaries before redistribution.
8. Keep a human in the loop for consequential decisions.

// skootle:review-prompt

# Actor input Schema

## `entities` (type: `array`):

Strict union: a CFPB company has id, kind=company, name and optional aliases; an NHTSA vehicle has id, kind=vehicle, make, model and modelYear.

## `sources` (type: `array`):

Only official CFPB Consumer Complaint Database and NHTSA Vehicle Complaints APIs are supported.

## `dateFrom` (type: `string`):

Optional ISO date (YYYY-MM-DD); applied where the official source supports the filter.

## `dateTo` (type: `string`):

Optional ISO date (YYYY-MM-DD); must be on or after dateFrom.

## `maxRecordsPerEntitySource` (type: `integer`):

Per official source/entity cap. The combined requested maximum must not exceed 2,000 records.

## `includeNarratives` (type: `boolean`):

Disabled by default. When enabled, optional public narrative/summary text is redacted for VINs and ZIP codes before output.

## `failOnSourceError` (type: `boolean`):

Default fail-closed behavior. Set false only to receive explicit partial/unavailable source statuses in a completed local run.

## Actor input object example

```json
{
  "entities": [
    {
      "id": "camry-2020",
      "kind": "vehicle",
      "make": "Toyota",
      "model": "Camry",
      "modelYear": 2020
    }
  ],
  "sources": [
    "nhtsa"
  ],
  "maxRecordsPerEntitySource": 100,
  "includeNarratives": false,
  "failOnSourceError": true
}
```

# Actor output Schema

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

No description

## `briefing` (type: `string`):

No description

# 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 = {
    "entities": [
        {
            "id": "camry-2020",
            "kind": "vehicle",
            "make": "Toyota",
            "model": "Camry",
            "modelYear": 2020
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("skootle/public-review-inventory-auditor").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 = { "entities": [{
            "id": "camry-2020",
            "kind": "vehicle",
            "make": "Toyota",
            "model": "Camry",
            "modelYear": 2020,
        }] }

# Run the Actor and wait for it to finish
run = client.actor("skootle/public-review-inventory-auditor").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 '{
  "entities": [
    {
      "id": "camry-2020",
      "kind": "vehicle",
      "make": "Toyota",
      "model": "Camry",
      "modelYear": 2020
    }
  ]
}' |
apify call skootle/public-review-inventory-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=skootle/public-review-inventory-auditor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Official Complaint Auditor",
        "description": "Audit official CFPB and NHTSA public complaint inventories with normalized records, source status, provenance, deterministic snapshots, API output, scheduling, monitoring, and integrations.",
        "version": "1.0",
        "x-build-id": "mJq9DTfzLVufOZUg6"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/skootle~public-review-inventory-auditor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-skootle-public-review-inventory-auditor",
                "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/skootle~public-review-inventory-auditor/runs": {
            "post": {
                "operationId": "runs-sync-skootle-public-review-inventory-auditor",
                "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/skootle~public-review-inventory-auditor/run-sync": {
            "post": {
                "operationId": "run-sync-skootle-public-review-inventory-auditor",
                "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": [
                    "entities"
                ],
                "properties": {
                    "entities": {
                        "title": "Company or vehicle entities",
                        "minItems": 1,
                        "maxItems": 10,
                        "type": "array",
                        "description": "Strict union: a CFPB company has id, kind=company, name and optional aliases; an NHTSA vehicle has id, kind=vehicle, make, model and modelYear."
                    },
                    "sources": {
                        "title": "Official sources",
                        "type": "array",
                        "description": "Only official CFPB Consumer Complaint Database and NHTSA Vehicle Complaints APIs are supported.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "cfpb",
                                "nhtsa"
                            ],
                            "enumTitles": [
                                "CFPB Consumer Complaint Database",
                                "NHTSA Vehicle Complaints"
                            ]
                        },
                        "default": [
                            "nhtsa"
                        ]
                    },
                    "dateFrom": {
                        "title": "Received on or after",
                        "type": "string",
                        "description": "Optional ISO date (YYYY-MM-DD); applied where the official source supports the filter."
                    },
                    "dateTo": {
                        "title": "Received on or before",
                        "type": "string",
                        "description": "Optional ISO date (YYYY-MM-DD); must be on or after dateFrom."
                    },
                    "maxRecordsPerEntitySource": {
                        "title": "Maximum records per entity and source",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Per official source/entity cap. The combined requested maximum must not exceed 2,000 records.",
                        "default": 100
                    },
                    "includeNarratives": {
                        "title": "Include redacted public narratives",
                        "type": "boolean",
                        "description": "Disabled by default. When enabled, optional public narrative/summary text is redacted for VINs and ZIP codes before output.",
                        "default": false
                    },
                    "failOnSourceError": {
                        "title": "Fail when an official source fails",
                        "type": "boolean",
                        "description": "Default fail-closed behavior. Set false only to receive explicit partial/unavailable source statuses in a completed local run.",
                        "default": true
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
