# Listing Quality Checker: Product Page Audit & Score (`cleanpull/listing-quality-checker`) Actor

Audit any product page or Amazon listing: a 0–100 score and pass, warn or fail checks with a fix for each. Structured data (Product, Offer, GTIN), titles, images and alt text, attributes, shipping and returns, meta tags, canonical, page weight. Compare against competitors; watch for changes.

- **URL**: https://apify.com/cleanpull/listing-quality-checker.md
- **Developed by:** [CleanPull](https://apify.com/cleanpull) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 page audits

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

## Listing Quality Checker: Product Page Audit & Score

Give it **product page URLs from any online shop or Amazon listings** and get a **score from 0 to 100** for each, with **every check marked pass, warn or fail and a concrete fix**. Store pages are checked against **Google's product structured-data rules** (Product and Offer, GTIN, availability, priceValidUntil, review markup, shipping and return policy), **Merchant Center's product data specification** (title, brand, colour, size, material) and on-page basics (title tag, meta description, canonical, image alt text, page weight). Amazon listings are checked against **Amazon's own guidance**: title length and rules, bullet points, images, A+ content, description and attributes. Add a competitor's page and get a **comparison row**: the score gap and the checks where they do better, with your fix. From **$5.00 per 1,000 audits**.

### What you can do with it

- **"Why doesn't Google show my product with price and stars?"** The structured-data checks name exactly what is missing from the Product and Offer markup, and what to add.
- **"Fix my listings before a launch or a theme change."** Every failed check has its fix, and `topFixes` lists the five worth the most points.
- **"How does my page compare with the competitor that outranks me?"** Give both URLs: the comparison row shows where they do better and what to change.
- **"Is my Amazon listing following Amazon's rules?"** Title length and forbidden characters, repeated words, promotional wording, five bullets, images, A+ content.
- **"Are my keywords in my titles?"** Give the search terms; each audit names the ones present and the ones missing.
- **"Tell me when a listing breaks."** A weekly watchlist with Changes only returns a page only when a check moved (a theme update dropped the GTIN, a sale date expired) or a page was removed.
- **"Feed audits to an AI agent or a spreadsheet."** Compact JSON with the same check ids on every page, a field picker and dataset views.

### How a page is checked

Each URL is **read once** (an Amazon page served without its lower half gets one sections request and one more read). Store pages get 16 checks; Amazon listings 8. Each check has a weight; a pass earns its full weight, a warn half, a fail nothing. The total is the score (store weights and Amazon weights each add up to 100), with a grade from A (90+) to F (below 40).

| Store page check         | Weight | Passes when                                                                                                                            | Based on                       |
| ------------------------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| Product structured data  | 14     | a JSON-LD Product (or ProductGroup) with name, image and offers, in the HTML; every JSON-LD block parses                               | Google merchant listings       |
| Offer price and currency | 10     | the Offer has a price above 0 and an ISO 4217 currency (an AggregateOffer warns: merchant listings need an Offer)                      | Google merchant listings       |
| GTIN                     | 8      | a GTIN-8/12/13/14 with a valid check digit (missing: warn, as it is required only for products that have one; a bad check digit fails) | Merchant Center specification  |
| Attributes               | 8      | brand, plus colour, size or material (from markup or variant options)                                                                  | Merchant Center specification  |
| Shipping and returns     | 8      | shippingDetails and hasMerchantReturnPolicy are marked up (only mentioned in text: warn)                                               | Google return policy markup    |
| Title length             | 7      | the product name is 20 to 110 characters (a rule of thumb; over 150 fails: Merchant Center's limit)                                    | Merchant Center specification  |
| Product images           | 7      | 3 or more product images in the markup                                                                                                 | Google merchant listings       |
| Availability             | 6      | each offer has a schema.org availability (missing: warn; Google recommends it)                                                         | Google merchant listings       |
| Title keywords           | 6      | your keywords are in the title or title tag; no word used more than twice                                                              | Google title links             |
| Review markup            | 5      | aggregateRating or review on the Product, or no rating shown on the page (a rating in the HTML without markup warns)                   | Google product snippets        |
| Image alt text           | 5      | 80% of the product's image tags have descriptive alt text                                                                              | Google image SEO               |
| Title tag                | 4      | 15 to 70 characters, no repeated words (a rule of thumb: Google sets no limit and cuts to the screen)                                  | Google title links             |
| Meta description         | 4      | 50 to 320 characters (a rule of thumb: Google sets no limit and cuts as needed)                                                        | Google snippets                |
| Canonical                | 3      | points to this page (the home page or noindex fails)                                                                                   | Google canonical URLs          |
| priceValidUntil          | 3      | not set (it is optional), or set and in the future (a past date fails)                                                                 | Google merchant listings       |
| Page weight              | 2      | HTML under 2 MB and under 4,200 elements (product markup after the first 2 MB fails)                                                   | Googlebot, Lighthouse DOM size |

| Amazon check   | Weight | Passes when                                                                                                                                        |
| -------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Title length   | 15     | 80 characters or fewer (Amazon: a 200-character limit and "we recommend no more than 60"; the warning above 80 is a rule of thumb; over 200 fails) |
| Title rules    | 15     | no `! $ ? _ { } ^ ¬ ¦` outside the brand, no word more than twice, no promotional wording                                                          |
| Bullet points  | 15     | five bullets, none over 500 characters                                                                                                             |
| Images         | 15     | six or more, a video counting as one (Amazon: "at least one image, and we recommend having at least six"); none fails                              |
| A+ content     | 10     | A+ modules below the bullets                                                                                                                       |
| Title keywords | 10     | your keywords in the title (else in the bullets: warn); brand first when no keywords are given                                                     |
| Attributes     | 10     | brand, plus at least two of colour, size, material in the details                                                                                  |
| Description    | 10     | 200 characters or more, or A+ content in its place                                                                                                 |

In a test of 27 product pages from 23 shops on 10 platforms and Amazon (US, UK, Germany), read from Apify's servers, all 27 were audited. A watchlist of 16 of them audited twice, minutes apart, reported **no false changes**.

### What makes the audit right

- **Every finding names what was found.** `found` says what the page has ("1 GTIN(s), e.g. 4009839334917", "0 of 4 product image tags have alt text"); `fix` says what to change; `source` names the guidance.
- **What Google reads, not what a browser draws.** Checks read the page's HTML, as Google's shopping crawl does. Product markup that only a script writes after load is reported as such, since Google says it makes shopping crawls less reliable.
- **A product page, not just any page.** A page is audited only when it has Product markup, an Offer or a price. A store that now redirects the address to a category or its home page has dropped the product: it is reported as removed on the second run in a row, and never charged as an audit.
- **A block is never a bad score.** Each site gets its own proxy ladder (direct, then datacenter, then residential only for sites that block the others). A page that cannot be read is listed in the run summary with the reason and never charged.
- **Changes are real changes.** Page weight moves with every theme deploy, so only reaching or leaving fail counts; scores that move by less than the threshold are ignored; a page is reported removed only after two runs without it.
- **Only public addresses are read.** A URL or redirect pointing into a private network is never fetched.
- **Runs do not fail for one bad entry.** An invalid URL is skipped with a warning; an empty input runs the form's example.

### Input

| Field                                                         | What it does                                                                                       |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `productUrls`                                                 | Your product pages: any shop, or Amazon (`amazon.<marketplace>/dp/ASIN`), one per line             |
| `competitorUrls`                                              | Competitors' pages: audited too, with one comparison row per page of yours                         |
| `keywords`                                                    | Search terms the titles should carry                                                               |
| `changesOnly`, `monitorName`, `minScoreChange`                | Return a page only when a check or the score moved since the last run with the same watchlist name |
| `maxRunCostUsd`                                               | Stop before this run's charges pass the amount (for scheduled runs)                                |
| `fields`, `maxConcurrency`, `proxyConfiguration`, `startUrls` | Field selection, pace, your own proxy, and compatibility with other actors                         |

#### Example inputs

Audit your page against a competitor's, with keywords:

```json
{
  "productUrls": ["https://www.allbirds.com/products/mens-tree-runners"],
  "competitorUrls": ["https://www.amazon.com/dp/B0DTK7VDTH"],
  "keywords": ["wool sneakers", "running shoes"]
}
```

Amazon listings in two marketplaces:

```json
{ "productUrls": ["https://www.amazon.com/dp/B07C1YFV6D", "https://www.amazon.de/dp/B003B3RGLE"] }
```

A weekly listing watch, capped at 50 cents a run:

```json
{
  "productUrls": ["https://www.tentree.com/products/kessler-sweater-warm-oak-heather-fade"],
  "changesOnly": true,
  "monitorName": "my-listings",
  "maxRunCostUsd": 0.5
}
```

### Output

One `audit` row per page. A real row (two of its 16 checks shown):

```json
{
  "recordType": "audit",
  "url": "https://www.zwilling.com/us/miyabi-evolution-5-inch-prep-knife-fine-edge--34025-133/34025-133-0.html",
  "domain": "zwilling.com",
  "role": "yours",
  "pageType": "store",
  "platform": "salesforce-commerce-cloud",
  "title": "MIYABI Evolution 5-inch Prep Knife, Fine Edge",
  "brand": "MIYABI",
  "price": 129.99,
  "currency": "USD",
  "score": 96,
  "grade": "A",
  "passed": 15,
  "warnings": 1,
  "failed": 0,
  "topFixes": [
    "Shipping and returns: Add shippingDetails (OfferShippingDetails: shippingRate, shippingDestination, deliveryTime) and hasMerchantReturnPolicy (applicableCountry, returnPolicyCategory, merchantReturnDays), on the Offer or once on your Organization, so Google can show them with the listing."
  ],
  "checks": [
    {
      "id": "gtin",
      "group": "structured-data",
      "label": "GTIN (barcode)",
      "status": "pass",
      "weight": 8,
      "found": "1 GTIN(s), e.g. 4009839334917",
      "fix": null,
      "source": "Google Merchant Center: Product data specification (support.google.com/merchants/answer/7052112)"
    },
    {
      "id": "shipping-returns",
      "group": "attributes",
      "label": "Shipping and returns",
      "status": "warn",
      "weight": 8,
      "found": "shipping in page text only; returns in page text only",
      "fix": "Add shippingDetails (…) and hasMerchantReturnPolicy (…), so Google can show them with the listing.",
      "source": "Google Search Central: Merchant return policy structured data (developers.google.com/search/docs/appearance/structured-data/return-policy)"
    }
  ],
  "pageWeight": { "htmlKB": 220.5, "wireKB": 46.8, "wireEstimated": false, "domElements": 1272 },
  "images": 3,
  "structuredData": ["json-ld", "open-graph"],
  "readThroughResidentialProxy": false,
  "firstSeen": true,
  "previousScore": null,
  "scoreChange": null,
  "changedChecks": [],
  "auditedAt": "2026-10-15T01:10:34.930Z"
}
```

With competitors, one `comparison` row per page of yours:

```json
{
  "recordType": "comparison",
  "url": "https://www.allbirds.com/products/mens-tree-runners",
  "score": 86,
  "competitors": [
    { "url": "https://www.zwilling.com/us/…", "domain": "zwilling.com", "score": 96, "grade": "A" }
  ],
  "bestCompetitorScore": 96,
  "scoreGap": -10,
  "behindOn": [
    {
      "check": "gtin",
      "label": "GTIN (barcode)",
      "yours": "warn",
      "theirs": "pass",
      "theirFinding": "1 GTIN(s), e.g. 4009839334917",
      "fix": "If the product has a GTIN (the barcode: EAN, UPC, ISBN), add it as gtin13, gtin12 or gtin14 to the Product or each variant; …"
    }
  ],
  "aheadOn": [],
  "summary": "86 vs 96 (zwilling.com): behind on 3 check(s), ahead on 0."
}
```

A store page and an Amazon listing are compared on what they share: title length and keywords, images and attributes. On a watchlist, `changedChecks` lists each check that moved (`{ "check": "gtin", "from": "pass", "to": "fail", "fix": "…" }`); a page gone on two runs in a row gives one `change` row with `"change": "removed"`, `removedHow` (`not-found` or `redirected`) and `redirectedTo`.

Amazon rows also have `marketplace`, `asin`, `bullets` and `aplusModules`. Amazon sometimes serves a listing without its lower half; the actor then asks for the page's sections (as Amazon Product Scraper does) and reads the page once more. If the lower half still is not there, the row has `"partial": true` and `notChecked`: the attributes, A+ and description checks are left out of the score (not failed), and a watchlist does not count them as changes on the next run. Dataset views: **Scores**, **Fixes** and **Comparisons**. `RUN_SUMMARY` in the key-value store gives the outcome (`COMPLETE`, `PARTIAL`, `NO_CHANGES`, `EMPTY`, `FAILED`), each page's score, charges, and every page that could not be audited, with the reason.

### Pricing

| Event                                                                             | Free and Bronze | Silver | Gold and above |
| --------------------------------------------------------------------------------- | --------------- | ------ | -------------- |
| Audit (a delivered audit row)                                                     | $5.00           | $4.50  | $4.00          |
| Page checked, unchanged (Changes only), or confirmed removed                      | $0.60           | $0.55  | $0.50          |
| Page through residential addresses (add-on, only for sites that block the others) | $7.00           | $7.00  | $7.00          |

Per 1,000 pages. Each run also has a $0.00005 start fee. Comparison rows are free. A page read through residential addresses may transfer at most 600 KB, compressed as sent, over all its attempts together (a larger one is not read or charged). A weekly watch of 100 product pages with Changes only is about 430 checks a month: $0.26, plus the pages that changed.

### Guidance the checks follow

- Google Search Central: [Merchant listing structured data](https://developers.google.com/search/docs/appearance/structured-data/merchant-listing) (Product: name, image, offers required; Offer: price above 0 and priceCurrency; availability, priceValidUntil, shippingDetails, hasMerchantReturnPolicy recommended)
- Google Search Central: [Product snippet structured data](https://developers.google.com/search/docs/appearance/structured-data/product-snippet) (review and aggregateRating)
- Google Search Central: [Merchant return policy](https://developers.google.com/search/docs/appearance/structured-data/return-policy) and [shipping policy](https://developers.google.com/search/docs/appearance/structured-data/shipping-policy) structured data
- Google Merchant Center: [Product data specification](https://support.google.com/merchants/answer/7052112) (title up to 150 characters; GTIN and brand for new products; colour and size for apparel; material where it tells variants apart)
- Google Search Central: [Title links](https://developers.google.com/search/docs/appearance/title-link), [Snippets and meta descriptions](https://developers.google.com/search/docs/appearance/snippet), [Canonical URLs](https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls), [Image SEO](https://developers.google.com/search/docs/appearance/google-images), [Googlebot](https://developers.google.com/search/docs/crawling-indexing/googlebot) (reads the first 2 MB of an HTML file)
- Chrome Lighthouse: [Avoid an excessive DOM size](https://developer.chrome.com/docs/lighthouse/performance/dom-size)
- schema.org: [Product](https://schema.org/Product), [Offer](https://schema.org/Offer), [OfferShippingDetails](https://schema.org/OfferShippingDetails), [MerchantReturnPolicy](https://schema.org/MerchantReturnPolicy)
- Amazon: [Product photos](https://sell.amazon.com/blog/product-photos) (at least one image required, at least six recommended, 500 to 10,000 pixels, over 1,000 for zoom)
- Amazon: [Amazon SEO](https://sell.amazon.com/blog/amazon-seo) (title limit 200 characters, "we recommend no more than 60"; bullets led by a one- or two-word feature and 100 characters or fewer; plain white backgrounds; A+ content); Seller Central product title requirements (no special characters such as `! $ ? _ { } ^ ¬ ¦` unless part of the brand, no word more than twice)

### Limits

- **What the HTML holds.** Markup and images that only scripts add after the page loads are not run; the checks say when that is the case.
- **Image sizes are not measured** (that would take a request per image); counts and alt text are.
- **Some retailers are not read:** Walmart, Target, Best Buy, REI, Hydro Flask and Patagonia block automated visitors or draw their pages with scripts only; they are skipped with a note and never charged.
- **Amazon:** the listing is read as a signed-out shopper sees it; Seller Central data (search terms, suppressed attributes) is not visible.
- **The score is a guide, not a ranking promise.** It weighs documented requirements and recommendations; search engines use many other signals.
- **Up to 200 pages a run.**
- **Nothing found**: when nothing could be read because it is not there (a page that answers 404, or input naming no page), the run still succeeds, with one free `recordType: "unreadable"` row per item giving the `reason`; nothing is charged. A run near its time limit stops starting pages, delivers what it read and lists the rest the same way.

### Changelog

- **0.1.x, reliability** (2026-10-24): runs that find nothing (a page that answers 404, or input naming no page) end SUCCEEDED with a free `unreadable` row per item saying why, instead of FAILED; a run stops starting pages before its time limit and ends with what it read, never TIMED-OUT. A run where the site refused on every route for every page still fails. Prices and events unchanged.
- **0.1** (October 2026): audits of store product pages (16 checks) and Amazon listings (8 checks) with a 0–100 score and a fix per check; keyword coverage; comparison rows against competitors; Changes only watchlists with removal confirmed on a second run; Max cost per run.

# Actor input Schema

## `productUrls` (type: `array`):

Product page URLs, one per line: from any shop (Shopify, WooCommerce, Magento, BigCommerce, Wix, Squarespace, custom) or an Amazon listing (amazon.com/dp/ASIN, any marketplace). Each page is read once and gets one audit row.

## `competitorUrls` (type: `array`):

Optional. Competitors' product pages for the same product type, one per line. Each is audited too, and every page of yours gets a comparison row: the score gap and the checks where a competitor does better, with your fix.

## `keywords` (type: `array`):

Optional. Search terms the listing should carry, one per line ("chef knife", "japanese steel"). The title checks report which are present and which are missing. Without keywords they check for repeated words and a product type.

## `changesOnly` (type: `boolean`):

Return a page's audit only when it changed since the last run with the same watchlist name: a check that moved (pass, warn or fail), or a score that moved by at least Score change. A page gone (404 or redirected away) is reported as removed only after two runs in a row. The first run is the baseline. Schedule it weekly to catch theme or feed changes that break your listings.

## `monitorName` (type: `string`):

Runs with the same name compare against each other. Use one name per watchlist.

## `minScoreChange` (type: `integer`):

With Changes only: a score that moved by fewer points, with no check changing, is not reported.

## `maxRunCostUsd` (type: `number`):

Optional. Stop once this run's charges would pass this amount. Use it for scheduled runs, which may have no spending limit of their own. Pages not audited are audited on the next run.

## `fields` (type: `array`):

Optional. Keep only these fields, for example \["url", "score", "grade", "topFixes"].

## `maxConcurrency` (type: `integer`):

Pages read in parallel. One site gets at most two requests at a time.

## `proxyConfiguration` (type: `object`):

Optional. The actor picks proxies itself per site: direct, then datacenter, then residential only for sites that block the others.

## `startUrls` (type: `array`):

Optional. Accepted for compatibility with other actors: product pages, same as Your product pages.

## Actor input object example

```json
{
  "productUrls": [
    "https://www.zwilling.com/us/miyabi-evolution-5-inch-prep-knife-fine-edge--34025-133/34025-133-0.html"
  ],
  "competitorUrls": [
    "https://www.amazon.com/dp/B07C1YFV6D"
  ],
  "changesOnly": false,
  "monitorName": "default",
  "minScoreChange": 5,
  "maxConcurrency": 4
}
```

# Actor output Schema

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

Audit, comparison and change rows.

## `audits` (type: `string`):

No description

## `fixes` (type: `string`):

No description

## `comparisons` (type: `string`):

No description

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

Outcome (COMPLETE, PARTIAL, NO_CHANGES, EMPTY, FAILED), the score of each page, charges and every page that could not be audited, with the reason.

# 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 = {
    "productUrls": [
        "https://www.zwilling.com/us/miyabi-evolution-5-inch-prep-knife-fine-edge--34025-133/34025-133-0.html"
    ],
    "competitorUrls": [
        "https://www.amazon.com/dp/B07C1YFV6D"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleanpull/listing-quality-checker").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 = {
    "productUrls": ["https://www.zwilling.com/us/miyabi-evolution-5-inch-prep-knife-fine-edge--34025-133/34025-133-0.html"],
    "competitorUrls": ["https://www.amazon.com/dp/B07C1YFV6D"],
}

# Run the Actor and wait for it to finish
run = client.actor("cleanpull/listing-quality-checker").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 '{
  "productUrls": [
    "https://www.zwilling.com/us/miyabi-evolution-5-inch-prep-knife-fine-edge--34025-133/34025-133-0.html"
  ],
  "competitorUrls": [
    "https://www.amazon.com/dp/B07C1YFV6D"
  ]
}' |
apify call cleanpull/listing-quality-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cleanpull/listing-quality-checker"
        }
    }
}
```

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/BkHvw7peDuNOAPNqq/builds/GjCh8tkS12djk6N8e/openapi.json
