# Australia Product Safety Recalls Scraper (`crawlerbros/australia-product-safety-recalls-scraper`) Actor

Search Australia's official product recall register (ACCC Product Safety Australia). Find recalled products by keyword, category, brand, or date. Get hazard details, affected batches/SKUs, supplier, and consumer instructions.

- **URL**: https://apify.com/crawlerbros/australia-product-safety-recalls-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, E-commerce, 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 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Australia Product Safety Recalls Scraper

Search Australia's official product recall register, published by the ACCC on **Product Safety Australia** (productsafety.gov.au). Find recalled products by keyword, category, brand, or publish date — get the full recall notice: hazard description, reason for recall, consumer action, affected barcodes/SKU, supplier, and sale dates.

### What this actor does

- **Two modes:** `search` (keyword + filters) and `byUrl` (exact recall page lookup)
- **Filters:** category (15 top-level product categories), brand, published-date range
- **Sorting:** relevance or newest-first
- **Full recall notice per product:** description, reason for recall, hazards, consumer action, supplier, barcodes/SKU, sale date range, locations sold, recall notice PDF, product photos
- **Empty fields are omitted** — every field in a record is real, populated data

### Output per recall

- `recallId` — URL slug, stable unique identifier
- `recallUrl` — canonical recall page URL
- `title`
- `publishedDate`
- `recallGuid` — ACCC's internal recall record identifier
- `category` — specific product sub-category (e.g. "Stuffed and plush toys")
- `productDescription`
- `reasonForRecall`
- `hazards`
- `consumerAction`
- `imageUrl`
- `brand`, `model`, `supplierName`, `traders`, `otherIdentifyingNumbers` *(requires `fetchFullDetails`)*
- `countryOfManufacture` *(requires `fetchFullDetails`)*
- `sku`, `barcodeNumbers[]` *(requires `fetchFullDetails`)*
- `saleDateFrom`, `saleDateTo` *(requires `fetchFullDetails`)*
- `lastUpdatedDate` — date the recall notice page was last revised *(requires `fetchFullDetails`)*
- `locationsSold[]` *(requires `fetchFullDetails`)*
- `recallNoticeUrl` — PDF of the official recall notice *(requires `fetchFullDetails`)*
- `tradersListUrl` — PDF listing the retailers/traders who sold the product, when published *(requires `fetchFullDetails`)*
- `productPhotoUrl`, `productPhotoUrls[]` *(requires `fetchFullDetails`)*
- `recordType: "recall"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` / `byUrl` |
| `searchQuery` | string | `battery` | Free-text keyword search (mode=search) |
| `recallUrls` | array | – | Exact recall page URLs (mode=byUrl) |
| `category` | select | – | One of 15 top-level product categories |
| `brand` | string | – | Case-insensitive filter to recalls whose brand contains this text. Auto-enables `fetchFullDetails`; recalls with no brand on file are excluded. |
| `publishedDateFrom` / `publishedDateTo` | string | – | `YYYY-MM-DD` |
| `sortBy` | select | `relevance` | `relevance` / `date` |
| `fetchFullDetails` | boolean | `true` | Fetch each recall's detail page for brand/supplier/barcodes/sale-dates/locations |
| `maxItems` | integer | `50` | Hard cap on emitted records (1-2000). In `mode=search`, a single search/filter combination can return at most ~100 matches (an upstream feed limit, not this actor's) -- run multiple searches with narrower filters (date range, category) to collect more. |

### Example input

```json
{
  "mode": "search",
  "searchQuery": "toy",
  "category": "Kids' toys",
  "publishedDateFrom": "2025-01-01",
  "maxItems": 50
}
```

```json
{
  "mode": "byUrl",
  "recallUrls": [
    "https://www.productsafety.gov.au/search-consumer-product-recalls/findon-light-up-sensory-plush"
  ]
}
```

### Use cases

- **Compliance monitoring** — track recalls in your product category or industry.
- **E-commerce risk management** — cross-check your catalogue's barcodes/SKUs against recalled products.
- **Consumer safety research** — analyze recall trends by category, brand, or time period.
- **Insurance & legal** — evidence gathering for product-liability due diligence.

### Data source

This actor uses productsafety.gov.au's own public RSS feed and recall detail pages — the same data published on the site's `/recalls` search page, maintained by the Australian Competition & Consumer Commission (ACCC). Public, no authentication required.

### FAQ

**How current is the data?** New recalls are published on the site as they're lodged; the feed reflects the live register.

**Does this cover food recalls?** Food safety recalls in Australia are managed separately by FSANZ / state food authorities, not the ACCC — this actor covers general consumer product recalls (electronics, toys, vehicles, cosmetics, etc.), not food.

**Why are `brand`, `sku`, and `barcodeNumbers` sometimes missing?** These are detail-page fields (only populated when `fetchFullDetails` is enabled) and not every recall notice includes them — vehicle recalls, for example, typically have no barcode/SKU.

**Can I filter by state/region?** The register doesn't expose an Australian state/territory filter; `locationsSold` (e.g. "Nationally", "Online", specific states) is available as an output field when `fetchFullDetails` is enabled.

**Why does `mode=search` return at most ~100 records for a given search/filter combination?** productsafety.gov.au's own RSS feed for this listing hard-caps at ~100 matches per query and doesn't support requesting further pages -- this is an upstream limit, not a limitation of this actor. To collect more than ~100 total, run the actor multiple times with narrower filters (split by `publishedDateFrom`/`publishedDateTo` or `category`) and combine the results.

**Why do some "Vehicles (registered)" recalls have fewer detail fields?** Registered-vehicle recall pages on productsafety.gov.au redirect to the separate `vehiclerecalls.gov.au` register (run by the Department of Infrastructure, not the ACCC). This actor doesn't follow that redirect, so those records ship with the RSS teaser fields (title, description, hazards, consumer action) but not the detail-page fields (brand, SKU, sale dates). In `mode=byUrl`, a registered-vehicle recall URL that redirects this way returns 0 records (the detail page is the only source of data for that mode) rather than hanging.

# Actor input Schema

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

What to fetch.

## `searchQuery` (type: `string`):

Free-text keyword search across recall titles, descriptions, and hazards (mode=search). Leave empty to browse by filters only.

## `recallUrls` (type: `array`):

Exact recall page URLs from productsafety.gov.au, e.g. `https://www.productsafety.gov.au/search-consumer-product-recalls/findon-light-up-sensory-plush`.

## `category` (type: `string`):

Filter to a top-level product category.

## `brand` (type: `string`):

Filter to recalls whose brand name contains this text (case-insensitive). Brand is a detail-page field, so setting this automatically enables 'Fetch full details'; recalls with no brand on file are excluded.

## `publishedDateFrom` (type: `string`):

Only include recalls published on or after this date.

## `publishedDateTo` (type: `string`):

Only include recalls published on or before this date.

## `sortBy` (type: `string`):

Sort order for results (mode=search).

## `fetchFullDetails` (type: `boolean`):

Fetch each recall's detail page for brand, supplier, barcodes/SKU, sale dates, and locations sold. Uses 1 extra request per recall; disable for a faster, lighter run (mode=search only — mode=byUrl always fetches the detail page).

## `maxItems` (type: `integer`):

Hard cap on emitted records. In mode=search, productsafety.gov.au's own feed returns at most ~100 matches for a single search/filter combination (no deeper pagination is available upstream) -- to collect more, run multiple searches with narrower filters (e.g. split by `publishedDateFrom`/`publishedDateTo` or `category`). In mode=byUrl, this caps how many of the supplied `recallUrls` are processed.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "battery",
  "recallUrls": [],
  "category": "",
  "sortBy": "relevance",
  "fetchFullDetails": true,
  "maxItems": 50
}
```

# Actor output Schema

## `recalls` (type: `string`):

Dataset containing all scraped Australian product safety recalls.

# 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 = {
    "mode": "search",
    "searchQuery": "battery",
    "recallUrls": [],
    "category": "",
    "sortBy": "relevance",
    "fetchFullDetails": true,
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/australia-product-safety-recalls-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 = {
    "mode": "search",
    "searchQuery": "battery",
    "recallUrls": [],
    "category": "",
    "sortBy": "relevance",
    "fetchFullDetails": True,
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/australia-product-safety-recalls-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 '{
  "mode": "search",
  "searchQuery": "battery",
  "recallUrls": [],
  "category": "",
  "sortBy": "relevance",
  "fetchFullDetails": true,
  "maxItems": 50
}' |
apify call crawlerbros/australia-product-safety-recalls-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/australia-product-safety-recalls-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/g1CWqRyIizsT9V1bA/builds/f9RBLRyNg71OQ3hVc/openapi.json
