{
  "openapi": "3.0.1",
  "info": {
    "title": "Otomoto.pl Scraper & Nearby Towns And Regions",
    "description": "Otomoto.pl Scraper extracts vehicle listings, prices, mileage, specifications, seller details, locations, and other car data from Otomoto.pl. Automate car market research, price monitoring, competitor analysis, and automotive lead generation.",
    "version": "0.1",
    "x-build-id": "MSod5AECWMmqI82r8"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/api-empire~otomoto-pl-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-api-empire-otomoto-pl-scraper",
        "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/api-empire~otomoto-pl-scraper/runs": {
      "post": {
        "operationId": "runs-sync-api-empire-otomoto-pl-scraper",
        "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/api-empire~otomoto-pl-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-api-empire-otomoto-pl-scraper",
        "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": {
          "cities": {
            "title": "🏙️ Towns to sweep",
            "type": "array",
            "description": "One Polish town per line - Kraków, Katowice, Wrocław. Each becomes its own Otomoto search and the results are merged, so a car sitting between two of your towns is charged once, not twice. Polish characters are handled (Łódź, Nowy Sącz, Gdańsk). A town Otomoto does not recognise is named in the log and the run fails rather than silently returning national results.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "searchRadiusKm": {
            "title": "📏 Travel radius around each town (km)",
            "minimum": 5,
            "maximum": 1000,
            "type": "integer",
            "description": "Otomoto's own distance filter, applied by Otomoto - nothing is computed here. Measured on /osobowe/bmw/krakow: 5 km → 392 adverts, 15 km → 761, 50 km → 1 372, 100 km → 4 730, 250 km → 12 854. 50 km is what Otomoto applies when no radius is given, so 100 km genuinely widens the net. The minimum is 5 because search[dist]=0 is a zero-radius circle that returns nothing. The radius applies to TOWNS only - a voivodeship sweep is an exact administrative match and Otomoto ignores the distance on it.",
            "default": 100
          },
          "voivodeships": {
            "title": "🗺️ Whole voivodeships to sweep",
            "type": "array",
            "description": "Sweep entire Polish regions instead of, or as well as, naming towns - use this when the question is where in the country a model is cheapest to source. A region sweep is NOT a radius sweep: Kraków within 50 km returned 1 372 adverts while the whole of Małopolskie returned 1 672, and they are different sets. Combines with the town list; everything is merged into one result set.",
            "items": {
              "type": "string",
              "enum": [
                "dolnoslaskie",
                "kujawsko-pomorskie",
                "lubelskie",
                "lubuskie",
                "lodzkie",
                "malopolskie",
                "mazowieckie",
                "opolskie",
                "podkarpackie",
                "podlaskie",
                "pomorskie",
                "slaskie",
                "swietokrzyskie",
                "warminsko-mazurskie",
                "wielkopolskie",
                "zachodniopomorskie"
              ],
              "enumTitles": [
                "Dolnośląskie",
                "Kujawsko-pomorskie",
                "Lubelskie",
                "Lubuskie",
                "Łódzkie",
                "Małopolskie",
                "Mazowieckie",
                "Opolskie",
                "Podkarpackie",
                "Podlaskie",
                "Pomorskie",
                "Śląskie",
                "Świętokrzyskie",
                "Warmińsko-mazurskie",
                "Wielkopolskie",
                "Zachodniopomorskie"
              ]
            },
            "default": []
          },
          "excludeCities": {
            "title": "🚫 Towns to skip",
            "type": "array",
            "description": "Drop any advert whose seller sits in one of these towns. Matched against the seller's own town with Polish diacritics folded on both sides, so lodz also matches Łódź. This runs AFTER the advert page has been fetched, so it can only take the charged row count BELOW your item cap, never above it. An advert whose seller town Otomoto did not publish is never dropped.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "📌 Single town or voivodeship (classic field)",
            "type": "string",
            "description": "The single-location field from the standard Otomoto.pl Scraper, kept working so existing input files keep running. A town (\"Warszawa\") or a voivodeship (\"Małopolskie\"). It is MERGED with the town list above rather than overridden, so it simply becomes one more search centre. A town entered here also gets the travel radius; leave the radius at 50 to reproduce the classic actor exactly.",
            "default": ""
          },
          "query": {
            "title": "🔎 Brand / Model",
            "type": "string",
            "description": "Brand, or brand plus model separated by a space. Examples: \"volvo\" → /osobowe/volvo · \"bmw seria 3\" → /osobowe/bmw/seria-3. Use Otomoto's own Polish model name. If Otomoto does not recognise the brand or the model it silently returns the whole catalogue, so the run FAILS instead and names the word it rejected.",
            "default": ""
          },
          "category": {
            "title": "🏷️ Vehicle Category",
            "enum": [
              "cars",
              "vans",
              "trucks",
              "motorcycles",
              "trailers",
              "campers",
              "construction",
              "agricultural",
              "parts"
            ],
            "type": "string",
            "description": "Otomoto section to search. English aliases are translated to the current Otomoto slug. Otomoto has moved several sections: motorcycles is now /motocykle-i-quady, trailers is /przyczepy, construction is /maszyny-budowlane, agricultural is /maszyny-rolnicze, and the standalone campers section was retired so campers are searched as the camper body type inside /dostawcze.",
            "default": "cars"
          },
          "minPrice": {
            "title": "💰 Min Price (PLN)",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum advert price in Polish złoty. Applied by Otomoto as search[filter_float_price:from] at every search centre."
          },
          "maxPrice": {
            "title": "💸 Max Price (PLN)",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum advert price in Polish złoty. Applied by Otomoto as search[filter_float_price:to] at every search centre."
          },
          "minProductionYear": {
            "title": "📅 Min Production Year",
            "minimum": 1900,
            "maximum": 2030,
            "type": "integer",
            "description": "Earliest production year, e.g. 2019. Applied by Otomoto as search[filter_float_year:from]."
          },
          "maxProductionYear": {
            "title": "📆 Max Production Year",
            "minimum": 1900,
            "maximum": 2030,
            "type": "integer",
            "description": "Latest production year, e.g. 2025. Applied by Otomoto as search[filter_float_year:to]."
          },
          "sort": {
            "title": "↕️ Sort Order",
            "enum": [
              "relevance_web",
              "created_at:desc",
              "created_at:asc",
              "price:asc",
              "price:desc",
              "year:desc",
              "year:asc",
              "filter_float_price:asc",
              "filter_float_price:desc",
              "filter_float_mileage:asc",
              "created_at_first:desc"
            ],
            "type": "string",
            "description": "Otomoto silently ignores unrecognised sort keys, so several of these values are handled for you: the two Price orders are remapped to Otomoto's working price keys, and the two Year orders plus \"Oldest first\" are applied CLIENT-SIDE over the rows this run collected. When more than one search centre is swept there is no cross-centre ranking on Otomoto's side either, so the merged set is re-sorted over the rows this run fetched and the log says so. Relevance has no cross-centre meaning and leaves rows grouped by centre.",
            "default": "relevance_web"
          },
          "maxItems": {
            "title": "🔢 Max Items (TOTAL, not per town)",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Hard cap on how many adverts are scraped and charged ACROSS THE WHOLE RUN. Six towns at 10 still fetch ten advert pages in total, not sixty - the cap is split fairly between the centres and whatever a thin town cannot absorb spills to the ones that still have adverts. Free rows (removed adverts, geo expansion) are never charged. Default is 10; raise it deliberately when you add towns.",
            "default": 10
          },
          "startUrls": {
            "title": "🔗 Start URLs (listings or single adverts)",
            "type": "array",
            "description": "Full Otomoto.pl URLs. Accepts BOTH listing pages (https://www.otomoto.pl/osobowe/bmw/krakow) and individual advert pages (https://www.otomoto.pl/osobowe/oferta/bmw-x6-ID6IbnVT.html). An advert that has been sold or removed produces a free, uncharged row with the reason instead of silently disappearing.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "includeGeoExpansion": {
            "title": "🧭 Add Otomoto's own region / town coverage list",
            "type": "boolean",
            "description": "Adds free rows of type \"geo_expansion\" carrying Otomoto's own alternativeLinks blocks: every voivodeship with its live advert counter and ready URL, and the top 20 towns of the current voivodeship. Read the caveat before using it as a proximity list - the towns block is an administrative sibling list ranked by advert count and capped at 20, NOT a distance ring, so a town 30 km away across a voivodeship border is absent. Off by default.",
            "default": false
          },
          "concurrency": {
            "title": "⚡ Concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many Otomoto pages are fetched in parallel. Default is 10, maximum 20.",
            "default": 10
          },
          "requestDelay": {
            "title": "⏱️ Request Delay (seconds)",
            "minimum": 0,
            "maximum": 30,
            "type": "integer",
            "description": "Extra pause before each request, in seconds, plus a small random jitter. Default is 0 (no extra delay).",
            "default": 0
          },
          "proxyConfiguration": {
            "title": "Proxy settings",
            "type": "object",
            "description": "Leave disabled to run without a proxy. The actor still escalates to datacenter and then residential automatically if it is genuinely blocked.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}