# GPSR Catalog Compliance Auditor (`formnexa/gpsr-catalog-compliance-auditor`) Actor

Match ecommerce catalog items to safety documents, flag missing GPSR information, and screen products against official U.S. recall data.

- **URL**: https://apify.com/formnexa/gpsr-catalog-compliance-auditor.md
- **Developed by:** [formnexa Tools](https://apify.com/formnexa) (community)
- **Categories:** E-commerce, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 audited catalog products

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

## GPSR Catalog Compliance Auditor

Bulk-match ecommerce catalog items to safety documents, flag missing GPSR readiness information, and optionally screen products against official U.S. CPSC recall data.

### What it does

1. Reads a CSV or JSON catalog (up to 20,000 rows).
2. Extracts text from PDF, TXT, CSV, JSON, XML, HTML, Markdown, or ZIP safety-document uploads.
3. Matches each document to a product using ASIN, SKU, GTIN/UPC/EAN, model, brand, and title terms.
4. Checks whether manufacturer and, for EU targets, EU Responsible Person contact fields are present.
5. Optionally queries the official U.S. CPSC public recall service and returns possible matches for human verification.

No paid AI API is used.

### Quick start

Upload a catalog or paste CSV/JSON into **Inline catalog**. Helpful column names include:

`asin`, `sku`, `gtin`, `upc`, `ean`, `title`, `brand`, `model`, `manufacturer_name`, `manufacturer_address`, `manufacturer_email`, `manufacturer_url`, `responsible_person_name`, `responsible_person_address`, `responsible_person_email`, `responsible_person_url`, and `safety_warning`.

Upload safety documents when you want product-to-document matching. Put the ASIN, SKU, GTIN, or model in the document text or filename for the strongest match.

### Result statuses

- `READY_FOR_REVIEW`: no automated high/medium issue was found. Human verification is still required.
- `MANUAL_REVIEW`: a document is missing/ambiguous or another medium issue was found.
- `NEEDS_ATTENTION`: core contact data is incomplete, no product identifier exists, or a possible recall match was found.

The numeric risk score is a prioritization aid, not a legal compliance score.

### Privacy and safety

- Contact fields are checked but their addresses and emails are not copied to dataset results.
- Uploaded catalog and document contents are processed inside the Actor run.
- With optional CPSC screening enabled, only UPC or limited product terms are sent to the public CPSC service.
- Scanned/image-only PDFs do not use OCR in this version and are flagged for manual review.
- File size, archive expansion, product count, and recall-query limits are enforced.

### Important disclaimer

This is an automated readiness-screening tool, not legal advice and not a certification or guarantee of compliance. Requirements vary by product, role, country, sales channel, and facts. Verify every result with qualified professionals and the relevant authority. This Actor is unofficial and is not affiliated with Amazon, the European Union, the European Commission, or the U.S. Consumer Product Safety Commission.

Official references:

- [EU General Product Safety Regulation (EU) 2023/988](https://eur-lex.europa.eu/eli/reg/2023/988/oj)
- [EU Safety Gate](https://ec.europa.eu/safety-gate-alerts/screen/webReport)
- [U.S. CPSC Recalls](https://www.cpsc.gov/Recalls)
- [CPSC Recall API documentation](https://www.saferproducts.gov/RestWebServices/Recall)

### Local development

```bash
npm install
npm test
npm start
````

### License

MIT

# Actor input Schema

## `catalogFile` (type: `string`):

Upload one CSV or JSON catalog. Use this or Inline catalog.

## `catalogText` (type: `string`):

Useful for a quick test. Leave empty when uploading a catalog file.

## `documentFiles` (type: `array`):

Optional PDF, TXT, CSV, JSON, XML, HTML, Markdown, or ZIP files. Text-based PDFs only; scanned PDFs are flagged for manual review.

## `targetJurisdiction` (type: `string`):

Select the checks most relevant to the catalog.

## `checkCpscRecalls` (type: `boolean`):

Queries the official U.S. CPSC public recall service. Possible matches always require human verification.

## `defaultManufacturerName` (type: `string`):

Applied only when a product row has no manufacturer name.

## `defaultManufacturerAddress` (type: `string`):

Applied only when a product row has no manufacturer address.

## `defaultManufacturerEmail` (type: `string`):

Applied only when a product row has no manufacturer electronic contact.

## `defaultManufacturerUrl` (type: `string`):

May be used as the manufacturer's electronic contact when email is absent.

## `defaultResponsiblePersonName` (type: `string`):

Applied only when an EU-target product row has no Responsible Person name.

## `defaultResponsiblePersonAddress` (type: `string`):

Applied only when an EU-target product row has no Responsible Person address.

## `defaultResponsiblePersonEmail` (type: `string`):

Applied only when an EU-target product row has no Responsible Person electronic contact.

## `defaultResponsiblePersonUrl` (type: `string`):

May be used as the Responsible Person's electronic contact when email is absent.

## `minimumDocumentScore` (type: `integer`):

A product identifier gives the strongest match. Raise this to reduce false matches.

## `maxProducts` (type: `integer`):

Cost and runtime guardrail.

## `maxRecallQueries` (type: `integer`):

Cost and rate-limit guardrail when recall screening is enabled.

## `recallTimeoutSecs` (type: `integer`):

Stops an individual CPSC request if the official service does not respond in time.

## Actor input object example

```json
{
  "catalogText": "asin,sku,title,brand,model,manufacturer_name,manufacturer_address,manufacturer_email,responsible_person_name,responsible_person_address,responsible_person_email,safety_warning\nB0DEMO1234,SKU-100,Example LED Desk Lamp,ExampleCo,LAMP-100,ExampleCo GmbH,1 Example Street Berlin Germany,safety@example.invalid,EU Contact SRL,2 Sample Avenue Paris France,contact@example.invalid,Keep away from water",
  "documentFiles": [],
  "targetJurisdiction": "EU_GPSR",
  "checkCpscRecalls": false,
  "minimumDocumentScore": 65,
  "maxProducts": 5000,
  "maxRecallQueries": 50,
  "recallTimeoutSecs": 15
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "catalogText": `asin,sku,title,brand,model,manufacturer_name,manufacturer_address,manufacturer_email,responsible_person_name,responsible_person_address,responsible_person_email,safety_warning
B0DEMO1234,SKU-100,Example LED Desk Lamp,ExampleCo,LAMP-100,ExampleCo GmbH,1 Example Street Berlin Germany,safety@example.invalid,EU Contact SRL,2 Sample Avenue Paris France,contact@example.invalid,Keep away from water`
};

// Run the Actor and wait for it to finish
const run = await client.actor("formnexa/gpsr-catalog-compliance-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 = { "catalogText": """asin,sku,title,brand,model,manufacturer_name,manufacturer_address,manufacturer_email,responsible_person_name,responsible_person_address,responsible_person_email,safety_warning
B0DEMO1234,SKU-100,Example LED Desk Lamp,ExampleCo,LAMP-100,ExampleCo GmbH,1 Example Street Berlin Germany,safety@example.invalid,EU Contact SRL,2 Sample Avenue Paris France,contact@example.invalid,Keep away from water""" }

# Run the Actor and wait for it to finish
run = client.actor("formnexa/gpsr-catalog-compliance-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 '{
  "catalogText": "asin,sku,title,brand,model,manufacturer_name,manufacturer_address,manufacturer_email,responsible_person_name,responsible_person_address,responsible_person_email,safety_warning\\nB0DEMO1234,SKU-100,Example LED Desk Lamp,ExampleCo,LAMP-100,ExampleCo GmbH,1 Example Street Berlin Germany,safety@example.invalid,EU Contact SRL,2 Sample Avenue Paris France,contact@example.invalid,Keep away from water"
}' |
apify call formnexa/gpsr-catalog-compliance-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=formnexa/gpsr-catalog-compliance-auditor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "GPSR Catalog Compliance Auditor",
        "description": "Match ecommerce catalog items to safety documents, flag missing GPSR information, and screen products against official U.S. recall data.",
        "version": "0.1",
        "x-build-id": "hCRM9XX9exeHTeYVG"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/formnexa~gpsr-catalog-compliance-auditor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-formnexa-gpsr-catalog-compliance-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/formnexa~gpsr-catalog-compliance-auditor/runs": {
            "post": {
                "operationId": "runs-sync-formnexa-gpsr-catalog-compliance-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/formnexa~gpsr-catalog-compliance-auditor/run-sync": {
            "post": {
                "operationId": "run-sync-formnexa-gpsr-catalog-compliance-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",
                "properties": {
                    "catalogFile": {
                        "title": "Catalog file",
                        "type": "string",
                        "description": "Upload one CSV or JSON catalog. Use this or Inline catalog."
                    },
                    "catalogText": {
                        "title": "Inline catalog CSV or JSON",
                        "type": "string",
                        "description": "Useful for a quick test. Leave empty when uploading a catalog file."
                    },
                    "documentFiles": {
                        "title": "Safety documents",
                        "type": "array",
                        "description": "Optional PDF, TXT, CSV, JSON, XML, HTML, Markdown, or ZIP files. Text-based PDFs only; scanned PDFs are flagged for manual review.",
                        "items": {
                            "type": "string"
                        },
                        "default": []
                    },
                    "targetJurisdiction": {
                        "title": "Target market",
                        "enum": [
                            "EU_GPSR",
                            "US_CPSC",
                            "BOTH"
                        ],
                        "type": "string",
                        "description": "Select the checks most relevant to the catalog.",
                        "default": "EU_GPSR"
                    },
                    "checkCpscRecalls": {
                        "title": "Screen official CPSC recalls",
                        "type": "boolean",
                        "description": "Queries the official U.S. CPSC public recall service. Possible matches always require human verification.",
                        "default": false
                    },
                    "defaultManufacturerName": {
                        "title": "Default manufacturer name",
                        "type": "string",
                        "description": "Applied only when a product row has no manufacturer name."
                    },
                    "defaultManufacturerAddress": {
                        "title": "Default manufacturer postal address",
                        "type": "string",
                        "description": "Applied only when a product row has no manufacturer address."
                    },
                    "defaultManufacturerEmail": {
                        "title": "Default manufacturer email",
                        "type": "string",
                        "description": "Applied only when a product row has no manufacturer electronic contact."
                    },
                    "defaultManufacturerUrl": {
                        "title": "Default manufacturer website",
                        "type": "string",
                        "description": "May be used as the manufacturer's electronic contact when email is absent."
                    },
                    "defaultResponsiblePersonName": {
                        "title": "Default EU Responsible Person name",
                        "type": "string",
                        "description": "Applied only when an EU-target product row has no Responsible Person name."
                    },
                    "defaultResponsiblePersonAddress": {
                        "title": "Default EU Responsible Person postal address",
                        "type": "string",
                        "description": "Applied only when an EU-target product row has no Responsible Person address."
                    },
                    "defaultResponsiblePersonEmail": {
                        "title": "Default EU Responsible Person email",
                        "type": "string",
                        "description": "Applied only when an EU-target product row has no Responsible Person electronic contact."
                    },
                    "defaultResponsiblePersonUrl": {
                        "title": "Default EU Responsible Person website",
                        "type": "string",
                        "description": "May be used as the Responsible Person's electronic contact when email is absent."
                    },
                    "minimumDocumentScore": {
                        "title": "Minimum document match score",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "A product identifier gives the strongest match. Raise this to reduce false matches.",
                        "default": 65
                    },
                    "maxProducts": {
                        "title": "Maximum products",
                        "minimum": 1,
                        "maximum": 20000,
                        "type": "integer",
                        "description": "Cost and runtime guardrail.",
                        "default": 5000
                    },
                    "maxRecallQueries": {
                        "title": "Maximum recall queries",
                        "minimum": 0,
                        "maximum": 250,
                        "type": "integer",
                        "description": "Cost and rate-limit guardrail when recall screening is enabled.",
                        "default": 50
                    },
                    "recallTimeoutSecs": {
                        "title": "Recall API timeout (seconds)",
                        "minimum": 5,
                        "maximum": 30,
                        "type": "integer",
                        "description": "Stops an individual CPSC request if the official service does not respond in time.",
                        "default": 15
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
