# Coles Australia Scraper - Prices, Specials, Barcodes (`s-r/coles-scraper`) Actor

Watch Coles Australia prices at one real store and get back only what moved: price cuts, stock, promotions, unit price. Or scrape outright by keyword, aisle or specials. Pin any run to a store by postcode, suburb or store id, because Coles prices are not national. Barcode and nutrition on request.

- **URL**: https://apify.com/s-r/coles-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (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 $0.50 / 1,000 product rows

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

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

## Coles Australia Scraper

Pull live product data out of the Coles Australia grocery catalogue at a real
store: name, brand, pack size, current price in Australian dollars, the price
before the promotion, unit price, stock, image and the product's own barcode.
Search by keyword, browse any aisle, take the whole specials catalogue in one
run, or read a full product record including ingredients, allergens, nutrition
panel and country of origin.

**Coles prices are not national.** Give this actor a postcode, a suburb or a
store id and every row comes back priced at that shop, with the store stamped on
it. That matters more than it sounds: see below.

**Or watch instead of scraping.** Name a watchlist, schedule the run, and from
the second run on you get back only the products whose price, stock, promotion
or unit price moved at that shop, with what they used to cost alongside what
they cost now.

No account, no cookies to paste, no browser to babysit. Give it a search term
and it returns rows.

### What you get

| Field | What it holds |
|---|---|
| `product_id` | Coles' own id. Stable, and the key you join runs on |
| `name`, `brand`, `size` | "Full Cream Milk", "Coles", "3L" |
| `price` | Current price in AUD. Null, never zero, when Coles publishes none |
| `was_price` | Price before the promotion. Null when nothing is on promotion |
| `save_amount`, `save_percent`, `save_statement` | The saving, three ways Coles states it |
| `is_on_special`, `promotion_type`, `multi_buy_promotion` | What kind of deal is running |
| `unit_price`, `unit_measure`, `unit_price_label` | `$1.65`, `1L`, `"$1.65/ 1L"` |
| `is_available`, `availability_type`, `available_quantity` | Whether Coles will actually sell it to you |
| `is_sponsored` | True when Coles served the row as a paid placement |
| `retail_limit`, `promotional_limit`, `is_age_restricted` | Purchase limits |
| `department`, `category`, `aisle` | Where it sits in the shop |
| `variations_total` | How many variants of the product Coles lists |
| `image`, `url` | Image and product page |
| `store_id`, `store_name`, `store_suburb`, `store_state`, `store_postcode` | Which shop these prices were read at |
| `is_store_priced` | False means the row is a national catalogue figure, not a shelf price |

With **Add barcode, ingredients and nutrition** switched on, every row also
carries `gtin`, `ingredients`, `allergen_statement`, `dietary_claims`,
`nutrition`, `storage_instructions`, `pack_dimensions`, `country_of_origin`,
`country_of_origin_statement`, `long_description`, `min_guarantee` and
`last_updated`.

### The four things it does

**Search by keyword.** One or more terms, each run separately, each row
recording which term found it. "milk" returns 146 products, "chocolate" returns
670, and the actor pages through them 48 at a time until it reaches your limit.

**Browse a category.** A whole department, `dairy-eggs-fridge`, or one aisle
inside it, `dairy-eggs-fridge/milk`. The milk aisle holds 197 products. Top
levels include `fruit-vegetables`, `meat-seafood`, `bakery`, `deli`, `pantry`,
`frozen`, `drinks`, `chips-chocolates-snacks`, `health-beauty`, `cleaning-laundry`,
`baby`, `pet` and `home-garden`. A path that does not exist is reported as such
rather than quietly returning a different aisle.

**Product detail by id or URL.** Paste product ids, or paste product URLs and the
id gets read off the end of them. This is the operation that returns the barcode
and the nutrition panel, neither of which appears in a listing row.

**Everything on special.** The current promotions catalogue, 7.591 products at
the time of writing, paged the same way as a search.

You can narrow a search or a browse to one kind of offer: half price, multi buy
or online only. It is applied by Coles rather than by filtering after the fact,
so it is a genuine narrowing. "chocolate" returns 670 products with no filter and
77 with half price on.

### Prices differ by store, and that is the point

Measured on one afternoon, same product ids, same two-minute window, only the
store changed:

| Product | Sydney | Darwin | Karratha WA |
|---|---|---|---|
| Tim Tam Original 200g | $3.00, was $6.00 | $3.00, was **$6.30** | $3.00, was **$6.42** |
| Bananas, loose | $4.90/kg | $4.90/kg | **$4.50/kg** |
| a2 Full Cream UHT 1L | $3.90 | $4.05 | $4.17 |
| Coles Full Cream Milk 3L | $4.95 | **not sold** | $4.95 |
| White sliced bread | $4.60 | $4.60 | $4.60, and **not sold** in Burnie TAS |

The range moves further than the prices do, and store format moves it most. A
search for "milk" returned 128 products in one Victorian supermarket, 121 in
Karratha, 118 in Broken Hill, 110 in Darwin and **84** at a small-format Coles
Central in the Sydney CBD. The specials catalogue ran from **2.567** products at
that express store to 7.066 in Broken Hill.

So a promotion tracker that ignores the store will report a markdown that is not
running in half the country, and a price comparison will quote a figure nobody
is charged.

**Leave the store empty and you get Coles' national catalogue instead.** That is
a real thing and sometimes what you want, but it is not a shelf price: the
national listing for "milk" is 146 products, larger than every store measured,
and the national specials catalogue is 7.591 against 2.567 to 7.066 in real
shops. Runs with no store say so in the summary and every row carries
`is_store_priced: false`, so it is never something you find out later.

A store that cannot be found **stops the run**. It does not quietly fall back to
national figures, because handing you national prices under a store label would
be exactly the kind of confident wrong answer the rest of this page is about.

If you have been told that store-specific Coles pricing cannot be pinned from a
scraper, that Coles resolves it from where the request comes from and there is no
way to override it: that is not true, and the table above is what overriding it
looks like.

### Watch mode: only what moved, at the shop you buy from

Turn on **Watch for changes**, give the watchlist a name, and schedule the run.
From the second run on you get back only the products that moved, with what they
used to cost sitting next to what they cost now.

The comparison is done at **your store**. That matters more here than anywhere
else on this page: a price change in a national catalogue is a change to a
figure nobody is charged, while a price change at the shop you actually buy from
is the thing you wanted to know. Same for promotions, which run in some states
and not others, and for range, because a product can be dropped from your store
while the national listing still carries it.

#### Five kinds of change, each with its own flag

A row that changed because the product went out of stock is a different alert
from a price cut, and one merged `changed` flag makes both of them useless. So
every row says which dimensions moved, and you can pick which ones count:

| Dimension | What it catches | On by default |
|---|---|---|
| `price` | What you pay moved | yes |
| `availability` | In stock, out of stock, or the price withdrawn entirely | yes |
| `promotion` | A multi-buy or half-price week starting or ending | yes |
| `unit_price` | The price per kg or per litre moved | yes |
| `was_price` | The advertised saving moved while the price held | no |

Two of those are worth spelling out, because a price-only watcher misses both.

**A promotion can start without the price moving.** "2 for $8" leaves the shelf
price exactly where it was. Anything watching `price` alone reports UNCHANGED
for the entire promotion.

**A pack can shrink instead of getting dearer.** 3L at $4.95 becomes 2.5L at
$4.95 and `price` is identical, while `unit_price` goes from $1.65/L to
$1.98/L. That is the whole event, and it only shows up if something is watching
the unit price.

Each row carries `price_changed`, `availability_changed`, `promotion_changed`,
`unit_price_changed` and `was_price_changed` separately, a `changes` list of
everything that moved, and one `change_type` headline for the biggest of them.
Stock outranks price in that headline, because a price on something you cannot
buy is not a price.

#### The first run tells you it is the first run

A watchlist with no history cannot know whether anything changed. It has not
measured "no changes", it has measured nothing, and those are different.

So a first run returns **every row marked `change_type: BASELINE`** with
`is_change: false`, and the summary reports `changesDetected: null` rather than
`0`. **"Only return rows that changed" is ignored on that run**, on purpose, so
you can see the watchlist matched the products you meant before you schedule it.
The summary says all of this in words.

Returning everything labelled NEW would fire an alert for every product you
already knew about on day one. Returning nothing would leave you a successful
run with an empty dataset and no way to tell it from a breakage. Neither is
worth the ten rows it saves.

#### What it refuses to tell you

**It will not compare two different stores.** A baseline captured at one store
against a run at another would report almost every product as changed, and every
one of those alerts would be wrong. The watchlist records its store and refuses
the comparison, then starts again at the store this run used, and says so.

**It will not report a withdrawn product as free.** Coles answers a product it
has stopped selling with a complete record and no price at all. Against a
baseline of $4.95 that is a 100% markdown to anyone who subtracts, and "milk now
free" arriving as a price alert is the worst thing this feature could do. A
price comparison here needs a real number on both sides: a price disappearing is
reported as `PRICE_WITHDRAWN` and a price reappearing as `PRICE_RESTORED`, both
under stock rather than price, and neither ever produces a delta.

**It will not call a product discontinued on a hunch.** If you watch a fixed
list of product ids and one stops resolving, that is `DELISTED` and you get told
once. If you watch a search term, a product missing from this run has almost
certainly moved off page one rather than out of the range, so it is counted in
the summary and no alert is invented for it. A run that also hit fetch errors
never claims a delisting at all.

**It will not call a failed run quiet.** If a run retrieves no products, the
summary says the comparison could not be made. It does not say nothing changed,
and it does not say your whole list was discontinued.

#### Where the watchlist lives

In **your** Apify account, under the name you gave it, created by the actor on
its first run and kept indefinitely. We never hold it and cannot see what you
watch. Every run also writes the same record to its own key-value store as
`watchlist_state`, so if the saved copy is ever unreachable you can paste that
back in as `baseline` and carry on without losing your history. The summary
always names which of the two the run actually compared against.

### What it deliberately does not do

**It will not pretend to look products up by barcode.** Coles does not index
barcodes, and it does not say so. Feed its search the GTIN printed on its own
milk bottle and you get fifteen products headed by a paper towel at $5.50 and a
tin of dog food at $14.00. Real names, real prices, HTTP 200, no error anywhere.
Any scraper that offers a barcode input against Coles without reading the flag
Coles sets on that response will tell you, with total confidence, that your milk
barcode is dog food. So there is no barcode-lookup operation here, because there
is no barcode lookup at Coles. The barcode itself is published on each product record and is returned
whenever you ask for detail, which is a different and honest thing. If you need
to go from a barcode to a product, run detail over the ids you already have and
match on `gtin` at your end.

**It will not offer a sort order.** Coles accepts a sort parameter and ignores
it. Price ascending and price descending returned identical first rows in
testing and the response kept reporting relevance ordering either way. Shipping
a sort control would be shipping a button that does nothing, so there isn't one.
Sort the dataset after the run instead.

### The part that matters: it does not hand you a confident wrong answer

Coles has several ways of saying "no" that arrive as a successful response with
products in it. Each one was found by testing for it, and each one is guarded.

**A query it cannot match returns substitutes, not nothing.** Search for
`zzzqqqxxwwv` and Coles returns two products, the first being a hayfever tablet.
Search for `asdkjhasdkjhasd` and it returns a children's matching game. These are
well-formed rows with real names and real prices, and nothing about the row
itself looks wrong. Coles does flag the response, and this actor reads that flag:
a term that matched nothing comes back as a row with `found: false` and a reason,
never as an unrelated product.

**A product Coles no longer sells keeps its record and loses its price.** Ask for
a product that never existed and you get a clean "not found". Ask for one Coles
has stopped selling and you get a complete record - name, brand, barcode, images

- with the entire price object set to null. Anything that treats a missing price
  as zero publishes a free product. Prices here are only ever read through a helper
  that returns null, never zero, and the row carries `is_available: false` so you
  can filter on the fact rather than infer it from a suspicious number.

**Sponsored rows repeat across pages.** Coles injects paid placements on top of
the 48-per-page grid, so page one of a search carries more than 48 products. Those
extras are not stable between pages: three products on page two and five on page
three of one test had already been returned earlier. Rows are deduplicated by
product id, and every row tells you whether it was a paid placement, so you can
drop them or keep them as you like.

**Coles advertises a filter it then refuses.** Its own response lists an
"all specials" filter with a count next to it. Requesting that filter returns a
404, every time. The specials operation uses the dedicated promotions catalogue
instead, which is why it works.

Every run writes a `summary` record saying how many products came back, how many
had a price, how many were paid placements, how many are no longer available, and
which of your search terms Coles could not match. If something went thin, the
summary says so rather than leaving you to notice.

### Input

| Input | Meaning |
|---|---|
| `operation` | `search`, `category`, `product` or `specials` |
| `store` | A postcode, a suburb, or a Coles store id. Prices the whole run at that shop |
| `monitor_mode` | `off`, or `changes` to compare this run against the last one |
| `watchlist_name` | Keeps separate watchlists apart. One name per store and per set of products |
| `track` | Which of `price`, `availability`, `promotion`, `unit_price`, `was_price` count as a change |
| `only_changed` | Return just the rows that moved. Ignored on a first run |
| `baseline` | Optional. A saved `watchlist_state` record to compare against directly |
| `queries` | Search terms, one per line |
| `categories` | Category paths such as `dairy-eggs-fridge/milk` |
| `product_ids` | Product ids or full product URLs |
| `special_offer` | `any`, `half_price`, `multi_buy` or `online_only` |
| `with_details` | Adds barcode, ingredients, nutrition and origin. One extra request per product |
| `max_results` | How many products in total. A page carries 48 |
| `max_pages` | Page ceiling per term or category |
| `retries` | Re-asks for a page that did not come back |

### What people use it for

Price monitoring against your own range or a competitor's, at the stores you
actually care about rather than at a national average nobody pays. Regional
price-gap analysis: run the same basket at a metropolitan store and a remote one
and the difference falls straight out. Promotion tracking, because `was_price`
and `save_percent` make a half-price week visible without watching the catalogue
by hand, and because the store field tells you where the markdown is actually
running. Range-gap analysis: browse an aisle, compare the
product ids against your own list, and the difference is the gap. Unit-price
comparison across pack sizes, which `unit_price` and `unit_measure` make
arithmetic rather than guesswork. Product content, because the detail operation
returns the ingredients and nutrition panel Coles prints on the pack.

Prices are Coles' online prices in AUD for the store you selected. Promotions
change weekly, so treat a run as a snapshot with a timestamp rather than a
permanent fact.

### Notes

Empty results are a successful run, not a failure: if Coles has nothing for your
term, you get zero rows and a summary that explains why, not a crash. Errors
carry a code and a message and land in the `errors` record.

This is an unofficial scraper. It is not affiliated with, endorsed by or
connected to Coles Group Limited. Use the data in line with Coles' terms and with
the law that applies to you.

# Actor input Schema

## `operation` (type: `string`):

Search the catalogue by keyword, browse a category or aisle, read full detail for known product ids or URLs, or pull the whole current specials catalogue.

## `store` (type: `string`):

A postcode such as 2000, a suburb such as Parramatta, or a Coles store id such as COL:840. Coles prices are per store, not national: on one day the same Tim Tam pack was marked down from $6.00 in Sydney, $6.30 in Darwin and $6.42 in Karratha, loose bananas were $4.90/kg everywhere except Karratha at $4.50/kg, and 3L Coles milk was simply not sold in Darwin. The range moves too: a small-format CBD store listed 84 milk products and 2.567 specials where a suburban one listed 128 and 7.066. Leave it empty and you get Coles' national catalogue, which is larger than every store measured and is nobody's shelf price. A store that cannot be found stops the run rather than quietly falling back.

## `queries` (type: `array`):

What to search the Coles catalogue for, one term per line. Used when the operation is 'Search by keyword'. Every term is run separately and each row records which term found it. A term Coles cannot match comes back as a row with found set to false, never as a substitute product.

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

Coles category paths, one per line, for the 'Browse a category' operation. A top level looks like dairy-eggs-fridge, fruit-vegetables, bakery, pantry, frozen, drinks or health-beauty. An aisle inside one looks like dairy-eggs-fridge/milk. A path that does not exist is reported as such rather than returning a different aisle.

## `product_ids` (type: `array`):

Coles product ids, one per line, for the 'Product detail by id or URL' operation. A full product URL works too, the id is read off the end of it. This is the operation that returns the barcode, ingredients, nutrition panel and country of origin. A product Coles no longer sells comes back with found set to true, is\_available false and a null price, never as a free product.

## `special_offer` (type: `string`):

Narrows a keyword search or a category browse to one kind of promotion. Applied by Coles, not by this actor: 'chocolate' returned 670 products unfiltered and 77 with half price on. Note that a filter leaving nothing behind is reported as no match, because Coles answers it the same way it answers a typo.

## `monitor_mode` (type: `string`):

Off returns current data every run. Track changes compares this run against the last run of the same watchlist name and adds change fields to every row. A first run has no baseline, so it records one and reports no changes rather than calling everything new.

## `watchlist_name` (type: `string`):

Separates independent watchlists so a milk list and a bread list do not overwrite each other. Saved under your own Apify account, not ours. Use a different name for a different store or a different set of products.

## `track` (type: `array`):

Price, stock, promotion shape and unit price are on by default. Unit price catches a pack shrinking at the same price. Was-price catches an advertised saving moving while the shelf price holds; it is off by default because it moves often.

## `only_changed` (type: `boolean`):

Ignored on a first run, which always returns every row so you can check the watchlist matched the products you meant. A changed row still carries the whole product record, not only the difference.

## `baseline` (type: `array`):

Optional escape hatch. Paste back the watchlist\_state record from an earlier run to compare against it directly. Normally leave this empty: the actor remembers the last run for you under the watchlist name.

## `with_details` (type: `boolean`):

Opens each product's own record for its barcode (GTIN), ingredients, allergen statement, nutrition panel, storage instructions and country of origin. None of that is in a listing row. One extra request per product, so runs are slower and cost more.

## `max_results` (type: `integer`):

How many products to return in total, across every search term or category. A catalogue page carries 48.

## `max_pages` (type: `integer`):

Stops each search term or category after this many pages even if the product target has not been reached.

## `retries` (type: `integer`):

How many times to re-ask for a page that did not come back. Coles is steady, so the default is enough for almost every run.

## Actor input object example

```json
{
  "operation": "search",
  "store": "2000",
  "queries": [
    "tim tam"
  ],
  "categories": [
    "dairy-eggs-fridge/milk"
  ],
  "product_ids": [
    "8150288"
  ],
  "special_offer": "any",
  "monitor_mode": "off",
  "watchlist_name": "default",
  "track": [
    "price",
    "availability",
    "promotion",
    "unit_price"
  ],
  "only_changed": false,
  "baseline": [],
  "with_details": false,
  "max_results": 100,
  "max_pages": 20,
  "retries": 3
}
```

# Actor output Schema

## `products` (type: `string`):

One row per Coles product.

## `summary` (type: `string`):

Which store the run was priced at, counts, price and barcode coverage, how many lookups resolved, how many rows were paid placements and which terms Coles could not match.

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

Failures with a code and a redacted message.

## `watchlist_state` (type: `string`):

What this run recorded for the next one to compare against. The actor keeps its own copy under your watchlist name, so this is only needed if you want to drive the comparison yourself: pass it back as the baseline input.

# 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 = {
    "operation": "search",
    "store": "2000",
    "queries": [
        "tim tam"
    ],
    "categories": [
        "dairy-eggs-fridge/milk"
    ],
    "product_ids": [
        "8150288"
    ],
    "special_offer": "any",
    "monitor_mode": "off",
    "watchlist_name": "default",
    "track": [
        "price",
        "availability",
        "promotion",
        "unit_price"
    ],
    "only_changed": false,
    "baseline": [],
    "with_details": false,
    "max_results": 100,
    "max_pages": 20,
    "retries": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/coles-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 = {
    "operation": "search",
    "store": "2000",
    "queries": ["tim tam"],
    "categories": ["dairy-eggs-fridge/milk"],
    "product_ids": ["8150288"],
    "special_offer": "any",
    "monitor_mode": "off",
    "watchlist_name": "default",
    "track": [
        "price",
        "availability",
        "promotion",
        "unit_price",
    ],
    "only_changed": False,
    "baseline": [],
    "with_details": False,
    "max_results": 100,
    "max_pages": 20,
    "retries": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/coles-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 '{
  "operation": "search",
  "store": "2000",
  "queries": [
    "tim tam"
  ],
  "categories": [
    "dairy-eggs-fridge/milk"
  ],
  "product_ids": [
    "8150288"
  ],
  "special_offer": "any",
  "monitor_mode": "off",
  "watchlist_name": "default",
  "track": [
    "price",
    "availability",
    "promotion",
    "unit_price"
  ],
  "only_changed": false,
  "baseline": [],
  "with_details": false,
  "max_results": 100,
  "max_pages": 20,
  "retries": 3
}' |
apify call s-r/coles-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/coles-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/xvLDkyPSozyBcF4Af/builds/wbj4QNZGwa8whK5MX/openapi.json
