# Smyths Toys Stock & Price Scraper - $1.50 / 1000 Products (`scrapeunblocker/smyths-toys-scraper`) Actor

Live stock and price for Smyths Toys UK products: price, was-price and RRP, home delivery stock, click & collect stock and pre-order dates, as the JSON Smyths' own store reads. Product codes or links in bulk. $1.50 per 1000 products.

- **URL**: https://apify.com/scrapeunblocker/smyths-toys-scraper.md
- **Developed by:** [Scrapeunblocker](https://apify.com/scrapeunblocker) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Smyths Toys Stock & Price Scraper

Get **live stock and price for Smyths Toys UK products** as clean JSON - the current price with was-price, RRP and discount, **home delivery stock** (in stock, out of stock, pre-order, expected stock date), **click & collect stock** and the delivery and collection messages, plus age suitability and delivery type. You get the same JSON Smyths' own store reads for its product pages, unchanged. Turn on **product page details** to also get each product's description, key features, safety warnings, brand, EAN and full image gallery. Give product codes or links, or **find the products by search or by category** - up to a whole Smyths department in one run. No Smyths account, no API key, no proxies to configure.

### Features

- **Any product input** - a Smyths product code (`156809`), a product or bundle page link (`https://www.smythstoys.com/uk/en-gb/.../p/156809`) or a product-inventory API link.
- **No codes needed** - search Smyths (`lego star wars`) or list a category (`SM0601` Toys, `SM0602` Baby, `SM0603` Outdoor, `SM0604` Gaming & Tech, any deeper category, or a category link) and every product found is collected.
- **Stock where it matters** - home delivery and click & collect stock status, stock messages, pre-order flags and expected stock dates.
- **Prices** - current price, was-price, then-price, RRP and discount percentage, in GBP.
- **Product page details** - description (HTML and plain text), key features, safety warnings, brand, EAN, the full image gallery and videos, the category path and the review count; a bundle lists the products it holds.
- **Unchanged JSON** - the product-inventory response Smyths' store uses, so code written against Smyths' own data keeps working. Products found by search or category also get their name, link, image and rating.
- **Bundles handled** - bundle products (consoles with games and the like) are recognised and read as bundles.
- **Deduplicated** - the same product given twice, or found by two searches, is collected once.
- **Not billed for misses** - a code Smyths does not know or a category that does not exist goes to the `ERRORS` record with the reason, free.

### Use cases

- **Stock monitoring** - check thousands of toys twice a day and act when one comes back in stock.
- **Catalogue discovery** - collect every product of a department or brand, with stock, without knowing a single code.
- **Price tracking** - follow current, was and RRP prices across a catalogue or against other retailers.
- **Product content** - descriptions, features, safety warnings and images for your own catalogue, feed or comparison site.
- **Pre-order and launch watch** - see pre-order status and expected stock dates for new releases.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `products` | array | - | Smyths product codes, product or bundle page links or product-inventory API links. |
| `searchQueries` | array | - | Search terms; every product each search finds is collected. Smyths' search returns its best 240 matches at most. |
| `categories` | array | - | Category codes (`SM0601`, `SM060101`, ...) or category page links; every product of each category is collected. |
| `maxProductsPerList` | integer | `60` | Products taken from each search term and each category (1-10000). |
| `sort` | string | Smyths' default | Order products are taken from searches and categories in: `bestsellers`, `price_asc`, `price_desc`, `rating_desc` or `newest`. |
| `includeStock` | boolean | `true` | Check live stock for products found by searches and categories. Off: save them as listed (code, name, link, price, image, rating, bundle flag), faster. |
| `includeDetails` | boolean | `false` | Add what each product's page shows: brand, EAN, description, key features, safety warnings, images, videos, category path, review count and bundle contents. One more request per product; $0.50 per 1000 products more. |
| `concurrency` | integer | `5` | Products fetched at the same time (1-10). |

With no input at all the actor reads the example product `156809`.

#### Example input

```json
{
  "products": [
    "156809",
    "https://www.smythstoys.com/uk/en-gb/brand/graco/graco-extend-lx-r129-car-seat-midnight/p/227867"
  ],
  "searchQueries": ["lego star wars"],
  "categories": ["https://www.smythstoys.com/uk/en-gb/toys/lego-and-bricks/adult-lego/c/adult-lego"],
  "maxProductsPerList": 100,
  "includeDetails": true
}
```

To collect a whole department, list its category with a high limit, for example `{"categories": ["SM0602"], "maxProductsPerList": 1000}` for every Baby product.

### Output

One dataset item per product (some fields shortened):

```json
{
  "code": "156809",
  "type": "REGULAR",
  "ageSuitabilities": ["5 Years +"],
  "hdSection": {
    "stockStatus": "INSTOCK",
    "stockMessage": "In Stock",
    "guestDeliveryMessage": "Free delivery on orders over £20",
    "isAvailableForDelivery": true,
    "isPreOrder": false,
    "expectedStockDate": null
  },
  "ccSection": {
    "stockStatus": "INSTOCK",
    "stockMessage": "In Stock",
    "deliveryMessage": "FREE collection within 2 hours",
    "isPreOrder": false,
    "expectedStockDate": null
  },
  "carrierType": {"name": "REGULAR"},
  "prices": {
    "price": "£9.99",
    "value": "9.99",
    "wasPrice": null,
    "thenPrice": null,
    "rrpPrice": null,
    "discountedPercentage": null
  },
  "name": "Marvel Avengers Thor Battle Hammer",
  "url": "https://www.smythstoys.com/uk/en-gb/toys/fashion-and-dolls/kids-costumes-dress-up-and-face-paint/character-and-super-hero-and-dress-up/marvel-avengers-thor-battle-hammer/p/156809",
  "image": "https://image.smythstoys.com/picture/desktop/156809",
  "averageRating": 5,
  "source": "search",
  "input": "thor hammer"
}
```

`source` says how the product was given or found (`product`, `search` or `category`) and `input` is the code, link, search term or category it came from. `name`, `url`, `image` and `averageRating` come with products found by searches and categories (and with a code you give that a search or category also lists); Smyths' stock JSON for a bare code does not carry them. With `includeStock` off, a found product is saved as listed: `code`, `name`, `url`, `prices`, `currency`, `image`, `averageRating`, `productType` (`BUNDLE` for bundles) and `decals`.

With `includeDetails` on, each product also gets (shortened):

```json
{
  "brand": "Skateboards & Accessories",
  "ean": "0840148210097",
  "description": "<p>Dare to be different with 858 Drift Board. ...</p>",
  "descriptionText": "Dare to be different with 858 Drift Board. ...",
  "features": ["Easy pull hand brake", "Super soft knee pads", "360° rear caster wheels", "No assembly"],
  "safetyWarnings": ["SMALL PARTS - CHOKING HAZARD. Not suitable for children under 3 years"],
  "images": [
    "https://image.smythstoys.com/original/800/desktop/225095",
    "https://image.smythstoys.com/original/800/desktop/225095_1"
  ],
  "videos": ["https://www.youtube-nocookie.com/embed/S53iNeGt1-U?rel=0"],
  "breadcrumbs": ["Outdoor", "Skateboards"],
  "numberOfReviews": 12
}
```

A bundle also gets `bundleItems` (`code`, `name`, `price` of each product it holds). A product whose details cannot be read goes to the `ERRORS` record instead and is not billed.

The **Products** view shows one row per product with the name, price, both stock statuses, pre-order, expected date and rating; the **Product details** view shows the brand, EAN, features, safety warnings, images and videos. Inputs that could not be read are listed in the `ERRORS` record of the run's key-value store with the reason.

### Pricing

**$1.50 per 1000 products**, and $0.50 per 1000 more for products with page details (`includeDetails`), $2.00 per 1000 in all. You pay only for products delivered; codes Smyths does not know, unknown categories and failed calls are not charged. Searching and listing categories costs nothing by itself - only the products saved are billed.

### Notes

- `stockStatus` values come from Smyths as is (for example `INSTOCK`, `OUTOFSTOCK`); `stockMessage` is the text the store shows.
- For a product code it does not know, Smyths answers with an error ("Sorry, there was a problem. Retry shortly."). The same answer can come during an outage on Smyths' side, so retry a code that worked before.
- Smyths' search returns at most 240 products per term; categories have no such limit.
- Data is fetched through ScrapeUnblocker, which keeps the browser sessions Smyths' bot protection requires.

# Actor input Schema

## `products` (type: `array`):

Smyths Toys UK product codes (e.g. 156809), product or bundle page links (https://www.smythstoys.com/uk/en-gb/.../p/156809) or product-inventory API links (https://www.smythstoys.com/api/uk/en-gb/product/product-inventory?code=156809). One dataset item per product. Leave empty to use only searches or categories.

## `searchQueries` (type: `array`):

Find products by searching Smyths, e.g. lego star wars. Every product a search finds is collected, up to the limit below. Smyths' search returns its best 240 matches at most - to get every product of a range, list its category.

## `categories` (type: `array`):

Find products by category: a category code (SM0601 Toys, SM0602 Baby, SM0603 Outdoor, SM0604 Gaming & Tech, or any deeper code such as SM060101) or a category page link (https://www.smythstoys.com/uk/en-gb/toys/action-figures-and-playsets/c/SM060101). Every product of the category is collected, up to the limit below.

## `maxProductsPerList` (type: `integer`):

How many products to take from each search term and each category (1-10000).

## `sort` (type: `string`):

The order products are taken from searches and categories in, which decides which ones fit under the limit.

## `includeStock` (type: `boolean`):

On: every product found by a search or category is checked for its live stock and price, and gets its name, link, image and rating added. Off: found products are saved as listed - code, name, link, price, image, rating and bundle flag - without stock, which is faster.

## `includeDetails` (type: `boolean`):

On: every product also gets what its Smyths product page shows - brand, EAN, description (HTML and plain text), key features, safety warnings, the full image gallery and videos, the category path, the review count and, for a bundle, the products it holds. One more request per product, so a run takes longer, and $0.50 per 1000 products more ($2.00 per 1000 with details).

## `concurrency` (type: `integer`):

How many products (or searches and categories) to fetch at the same time (1-10).

## Actor input object example

```json
{
  "products": [
    "156809"
  ],
  "maxProductsPerList": 60,
  "sort": "",
  "includeStock": true,
  "includeDetails": false,
  "concurrency": 5
}
```

# Actor output Schema

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

One item per product: price, home delivery stock and click & collect stock

## `errors` (type: `string`):

Products, searches and categories that could not be read (a code Smyths does not know, an unknown category, a bad link, a block), with the reason (not billed)

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

// Run the Actor and wait for it to finish
const run = await client.actor("scrapeunblocker/smyths-toys-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 = { "products": ["156809"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapeunblocker/smyths-toys-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 '{
  "products": [
    "156809"
  ]
}' |
apify call scrapeunblocker/smyths-toys-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapeunblocker/smyths-toys-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/NZsR7FQQZVqTaNXyc/builds/Zy6X6mzcGpemUfYXF/openapi.json
