{
  "openapi": "3.0.1",
  "info": {
    "title": "Etsy Ultimate Data Extractor (All-in-One)",
    "description": "Recon build.",
    "version": "0.0",
    "x-build-id": "Puta1sgjXJLLhaFBY"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/fanndev~etsy-ultimate-data-extractor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-fanndev-etsy-ultimate-data-extractor",
        "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/fanndev~etsy-ultimate-data-extractor/runs": {
      "post": {
        "operationId": "runs-sync-fanndev-etsy-ultimate-data-extractor",
        "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/fanndev~etsy-ultimate-data-extractor/run-sync": {
      "post": {
        "operationId": "run-sync-fanndev-etsy-ultimate-data-extractor",
        "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": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "shop",
              "product",
              "reviews",
              "deepCrawl"
            ],
            "type": "string",
            "description": "Which extraction to run. 'search' discovers products and shops, 'shop' profiles a seller and its catalogue, 'product' pulls one listing in full, 'reviews' pulls reviews and sentiment, and 'deepCrawl' chains search into product and reviews in one pass.",
            "default": "search"
          },
          "searchKeywords": {
            "title": "Search keywords",
            "type": "array",
            "description": "Keywords for search and deepCrawl. IMPORTANT: Etsy's robots.txt disallows /search?q= product search for every crawler, so this actor uses the surface Etsy explicitly allows instead - /search/shops - and then searches each matched shop's own catalogue for the keyword. You get keyword-matched products and the shops behind them, without a disallowed request. Nonsense keywords correctly return nothing.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Start URLs",
            "type": "array",
            "description": "Etsy URLs to process. Category pages (https://www.etsy.com/c/jewelry/rings), shop pages (https://www.etsy.com/shop/PBJewelryGift), product pages (https://www.etsy.com/listing/4306368113/birth-flower-ring-925-sterling-silver) and shop searches (https://www.etsy.com/search/shops?q=candle) all work; the actor routes each by shape. A product URL must include its exact slug - see productUrls for why.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "productUrls": {
            "title": "Product URLs",
            "type": "array",
            "description": "Full Etsy listing URLs for product and reviews modes, as an alternative to startUrls. The exact slug is required: Etsy answers /listing/<id> and any wrong slug with a redirect, and DataDome blocks the redirect, so a bare listing ID cannot be resolved. Paste the url field of any search_result record.",
            "items": {
              "type": "string"
            }
          },
          "shopNames": {
            "title": "Shop names",
            "type": "array",
            "description": "Shop names (e.g. PBJewelryGift) or shop URLs for shop and reviews modes. Bare names are fine - the actor builds the URL itself, including the locale prefix that Etsy's bot protection requires on shop pages.",
            "items": {
              "type": "string"
            }
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 0,
            "type": "integer",
            "description": "Hard ceiling on dataset records for the whole run, shared across every stage of a chained crawl. 0 means no limit. This is the main control over compute cost.",
            "default": 200
          },
          "maxPagesPerTarget": {
            "title": "Max pages per target",
            "minimum": 1,
            "maximum": 250,
            "type": "integer",
            "description": "How many result pages to walk per category, shop or keyword. A category page holds 64 products, a shop search page 12 shops, a shop reviews page 14 reviews. Category grids stop at page 250 no matter what you set here.",
            "default": 5
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Etsy is behind DataDome. Residential proxies are strongly recommended: during recon, datacentre addresses were challenged on every surface tested, including the category grid that residential cleared. Without a proxy, request rate from one address degrades results after roughly 30 requests.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "locale": {
            "title": "Locale (pins the currency)",
            "enum": [
              "",
              "uk",
              "de-en",
              "ie",
              "au",
              "ca",
              "nz",
              "in-en",
              "sg-en",
              "hk-en",
              "il-en",
              "dk-en",
              "fi-en",
              "no-en",
              "se-en"
            ],
            "type": "string",
            "description": "Etsy's locale path prefix. Prices otherwise follow the proxy's exit country - the same ring came back in IDR, EUR, GBP, AUD and CAD purely by changing the exit - so set this if you need a stable currency. Leave empty for Etsy's default US site (USD from a US exit). Shop pages always get a prefix regardless, because the unprefixed shop path is blocked.",
            "default": "uk"
          },
          "extractReviews": {
            "title": "Also extract reviews",
            "type": "boolean",
            "description": "In shop and product modes, also emit review records. A product page carries only the handful of reviews Etsy renders inline; the deep set comes from the shop's reviews pages, 14 per page.",
            "default": false
          },
          "deepReviews": {
            "title": "Reviews: walk the whole shop",
            "type": "boolean",
            "description": "In reviews mode, after reading a product's inline reviews, also walk its shop's reviews pages and keep every review left for that product. Costs one request per 14 reviews.",
            "default": false
          },
          "maxReviewPages": {
            "title": "Max review pages per shop",
            "minimum": 1,
            "type": "integer",
            "description": "How many shop reviews pages to walk (14 reviews each). Defaults to maxPagesPerTarget when unset."
          },
          "deepCrawlProducts": {
            "title": "Deep crawl: products to follow",
            "minimum": 1,
            "type": "integer",
            "description": "In deepCrawl, how many of the discovered products to open in full. Each one is a separate page request, so this is the setting that decides the run's cost.",
            "default": 10
          },
          "shopsPerKeyword": {
            "title": "Shops to search per keyword",
            "minimum": 1,
            "type": "integer",
            "description": "How many of the shops matched by a keyword to search for products. Each shop costs one request and returns up to 36 keyword-matched listings.",
            "default": 12
          },
          "bestsellerOnly": {
            "title": "Bestseller / Star Seller badge only",
            "type": "boolean",
            "description": "Keep only products carrying a Bestseller or Star Seller badge. READ THIS FIRST: Etsy currently does not render these badges into server-side HTML on grid pages at all - the page's own config reports badges_disabled and the bestseller experiment is off - so this filter returns almost nothing today. It is kept because it starts working the moment Etsy re-enables the badge. For popularity filtering that works now, use minReviewCount and minRating.",
            "default": false
          },
          "minReviewCount": {
            "title": "Minimum review count",
            "minimum": 0,
            "type": "integer",
            "description": "Keep only products whose seller has at least this many reviews. Grid cards publish the SHOP's review count, not the item's (Etsy renders the seller's stars on every card), so this is a seller-quality filter - and it is the popularity signal that actually works here, unlike bestsellerOnly. For per-item review counts, run product mode."
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Keep only products whose seller is rated at least this many stars (1-5). Like minReviewCount this reads the shop's rating, because that is what a grid card carries."
          },
          "includeAds": {
            "title": "Include promoted listings",
            "type": "boolean",
            "description": "Category and shop grids mix in promoted listings, which Etsy renders without a shop name. They are dropped by default; turn this on to keep them, flagged with isAd.",
            "default": false
          },
          "requestDelaySecs": {
            "title": "Delay between requests (seconds)",
            "minimum": 0,
            "type": "integer",
            "description": "Floor between requests. DataDome scores request rate per address, so lowering this raises the block rate on long runs.",
            "default": 2
          },
          "maxRetries": {
            "title": "Max retries per URL",
            "minimum": 1,
            "type": "integer",
            "description": "Attempts per URL before giving up. Each retry rotates to a different TLS fingerprint, which is what actually clears a DataDome challenge, so this is at least the number of profiles in the ladder.",
            "default": 6
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (seconds)",
            "minimum": 10,
            "type": "integer",
            "description": "Per-request timeout. Etsy pages run from 200 KB to 1 MB, so keep this generous on residential proxies.",
            "default": 60
          }
        }
      },
      "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "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
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}