{
  "openapi": "3.0.1",
  "info": {
    "title": "Joybuy scraper 🛍️",
    "description": "Extract full product data from Joybuy (JD.com's European marketplace — FR, DE, BE, NL, LU, UK). Get prices, discounts, variants, ratings, reviews, Q&A, specs, images and delivery estimates by product URL, search URL or keyword. Fast structured JSON",
    "version": "0.0",
    "x-build-id": "bxOAFvCf0aweNnfh7"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/borderline~joybuy-api/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-borderline-joybuy-api",
        "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/borderline~joybuy-api/runs": {
      "post": {
        "operationId": "runs-sync-borderline-joybuy-api",
        "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/borderline~joybuy-api/run-sync": {
      "post": {
        "operationId": "run-sync-borderline-joybuy-api",
        "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": {
          "startUrls": {
            "title": "🔗 Product or search URLs",
            "type": "array",
            "description": "Joybuy product pages (<code>/dp/{slug}/{skuId}</code> or <code>/dg/{skuId}</code>) and search result pages. <b>Filters in a search URL are honoured</b> — sort order, price range, category, brand and page all carry over. Tracking parameters are ignored. A bare sku id works too.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "keywords": {
            "title": "🔍 Search keywords",
            "type": "array",
            "description": "Search terms, one per line. Each keyword is searched and the resulting products are scraped, up to <b>Max results</b>.",
            "items": {
              "type": "string"
            }
          },
          "maxItemsPerInput": {
            "title": "🔢 Max results per URL or keyword",
            "minimum": 0,
            "type": "integer",
            "description": "Upper bound on products scraped for <b>each</b> start URL or keyword, so one broad keyword cannot starve the others. Set <code>0</code> for no cap — the run then takes everything Joybuy returns, which can be <b>1,800 products for a broad keyword</b>, all of them billed.",
            "default": 50
          },
          "sortType": {
            "title": "↕️ Sort order (keyword searches)",
            "enum": [
              "sort_default",
              "sort_dredisprice_asc",
              "sort_dredisprice_desc"
            ],
            "type": "string",
            "description": "Sort order applied to <b>keyword</b> searches. Search URLs keep their own <code>sortType</code> from the URL.",
            "default": "sort_default"
          },
          "scrapeDescription": {
            "title": "📄 Scrape description & specifications",
            "type": "boolean",
            "description": "Fetch the product description, specification table and 'important information' images. Adds one extra request per product; it can occasionally come back empty, in which case the rest of the product is unaffected. Enabled by default.",
            "default": true
          },
          "minPrice": {
            "title": "💰 Minimum price",
            "minimum": 0,
            "type": "integer",
            "description": "Skip products cheaper than this, in the site currency."
          },
          "maxPrice": {
            "title": "💰 Maximum price",
            "minimum": 0,
            "type": "integer",
            "description": "Skip products more expensive than this, in the site currency."
          },
          "brand": {
            "title": "🏷️ Brand",
            "type": "string",
            "description": "Keep only products of this brand (exact name, case-insensitive), e.g. <code>Apple</code>. Products Joybuy lists without a brand of their own are dropped, since they cannot be shown to match. Joybuy has no brand filter of its own, so this one runs over the search results, which makes the run walk further."
          },
          "minRating": {
            "title": "⭐ Minimum rating",
            "enum": [
              "0",
              "2",
              "3",
              "4"
            ],
            "type": "string",
            "description": "Keep only products rated at or above this many stars. Joybuy's own search does not offer a rating filter that works, so this is applied on our side — products that list no rating are kept.",
            "default": "0"
          },
          "inStockOnly": {
            "title": "📦 In stock only",
            "type": "boolean",
            "description": "Skip products Joybuy reports as out of stock.",
            "default": false
          },
          "bestsellersOnly": {
            "title": "🏆 Bestsellers only",
            "type": "boolean",
            "description": "Keep only products in Joybuy's bestseller ranking. Applied by Joybuy's own search, so it cannot be double-checked on our side the way price or brand can.",
            "default": false
          },
          "lightningOffersOnly": {
            "title": "⚡️ Lightning offers only",
            "type": "boolean",
            "description": "Keep only products carrying a lightning-offer deal. Applied by Joybuy's own search.",
            "default": false
          },
          "fastDeliveryOnly": {
            "title": "⚡ Fast delivery only",
            "type": "boolean",
            "description": "Keep only products eligible for JoyExpress fast delivery. Applied by Joybuy's own search (measured: it cuts a 297-result search to 235).",
            "default": false
          },
          "scrapeReviews": {
            "title": "⭐ Scrape reviews",
            "type": "boolean",
            "description": "Include customer reviews on each product. Reviews are billed separately.",
            "default": true
          },
          "maxReviews": {
            "title": "🔢 Max reviews per product",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "Upper bound on reviews collected per product. Reviews are paginated, so a high value is honoured — Joybuy itself stops at 1,000 per product. This is the single biggest driver of run cost — every review is billed on its own, so doubling this roughly doubles what a run costs.",
            "default": 10
          },
          "scrapeQuestions": {
            "title": "❓ Scrape questions",
            "type": "boolean",
            "description": "Include the customer Q&A shown on the product page.",
            "default": true
          },
          "maxQuestions": {
            "title": "🔢 Max questions per product",
            "minimum": 0,
            "type": "integer",
            "description": "Upper bound on customer questions collected per product, when Scrape questions is on. Paginated the same way as reviews.",
            "default": 5
          },
          "includePersonalData": {
            "title": "🙍 Include reviewer names",
            "type": "boolean",
            "description": "Reviewer and question-author display names are public on Joybuy's product pages. Included by default; set to false to redact them (returned as <code>null</code>). The hashed account id, avatars and order ids are never collected either way.",
            "default": true
          },
          "country": {
            "title": "🌐 Country / site",
            "enum": [
              "FR",
              "DE",
              "BE",
              "NL",
              "LU",
              "GB"
            ],
            "type": "string",
            "description": "The Joybuy site to read from: currency, pricing and delivery follow the country you pick. Belgium, the Netherlands and Luxembourg share Joybuy's Dutch storefront (NL-Site). Everything works on all six — search, product URLs, reviews, descriptions. A start URL from another storefront is read from <b>its own</b> market instead — a catalogue only carries its own products — and the run log says so; pass the bare sku id rather than the full URL to read a product from the country you picked here.",
            "default": "FR"
          },
          "language": {
            "title": "🗣️ Language",
            "enum": [
              "",
              "en_GB",
              "fr_FR",
              "de_DE",
              "nl_NL"
            ],
            "type": "string",
            "description": "Language for titles, specifications and delivery wording. Defaults to the country's own language — pick English to read a French, German or Dutch catalogue in English. Each site only serves some languages; an unsupported one falls back to the site default.",
            "default": ""
          },
          "postCode": {
            "title": "📮 Delivery postcode",
            "type": "string",
            "description": "Postcode used as the delivery address, so prices and delivery times match it. Leave empty to use the site default. It must belong to the <code>country</code> you picked: a start URL from another storefront is refused while a postcode is set, since the address would mean nothing on that market."
          },
          "latitude": {
            "title": "🧭 Latitude (optional)",
            "type": "string",
            "description": "Optional GPS latitude for a more precise delivery location."
          },
          "longitude": {
            "title": "🧭 Longitude (optional)",
            "type": "string",
            "description": "Optional GPS longitude for a more precise delivery location."
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}