{
  "openapi": "3.0.1",
  "info": {
    "title": "Otomoto.pl Scraper With Dealer Contact Leads",
    "description": "Otomoto.pl Scraper extracts car listings, prices, specifications, mileage, seller details, locations, and other vehicle data from Otomoto.pl. Automate automotive market research, competitor analysis, price tracking, and lead generation with structured data.",
    "version": "0.1",
    "x-build-id": "NeiBsqzJK9LrCCxIf"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/simpleapi~otomoto-pl-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-simpleapi-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/simpleapi~otomoto-pl-scraper/runs": {
      "post": {
        "operationId": "runs-sync-simpleapi-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/simpleapi~otomoto-pl-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-simpleapi-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": {
          "extractSellerContacts": {
            "title": "☎️ Read seller phone numbers",
            "type": "boolean",
            "description": "Resolve each advert's published phone numbers and attach the seller's outreach record (dealership name, address, storefront URL, live stock count, opening hours, badges). Costs one small extra request per published number, plus one to detect the end of the list. Leave this ON - it is what this actor is for. When it is OFF, sellerContacts, hasPhone and sellerContactsFetched are all null (never false, never an empty list) because nothing was asked.",
            "default": true
          },
          "sellerType": {
            "title": "👤 Dealerships or private sellers",
            "enum": [
              "dealer",
              "private",
              "any"
            ],
            "type": "string",
            "description": "Applied by Otomoto BEFORE any advert page is fetched (search[private_business]), so it shrinks the run rather than filtering afterwards. Measured on /osobowe/bmw: 19,601 adverts unfiltered, 8,229 dealerships, 11,372 private sellers. Every returned advert is additionally checked row by row and a contradicting advert is dropped and logged. Ignored when you paste Start URLs - those override every search filter.",
            "default": "dealer"
          },
          "withPhoneOnly": {
            "title": "📞 Only keep sellers with a phone number",
            "type": "boolean",
            "description": "Drop advert rows where no phone number could be read, so the file handed to a sales team has no dead lines in it. Free rows for removed adverts are never dropped. OFF by default so your first run shows the true hit rate before you decide. Requires the phone reader above to be on; if the filter removes every row the run FAILS loudly instead of finishing with an empty dataset.",
            "default": false
          },
          "oneRowPerSeller": {
            "title": "🏢 One row per seller instead of one per advert",
            "type": "boolean",
            "description": "Collapse every advert from the same seller id into a single row - the advert with the most resolved phone numbers and the richest contact record - and add sellerAdIds plus sellerAdCount describing the rest. The surviving row is still a complete advert record; no field is dropped. Rows are buffered and pushed at the end of the run instead of streaming. Note that Max Items still caps how many ADVERT pages are fetched, so collapsing 40 adverts into 6 sellers still fetches 40 adverts.",
            "default": false
          },
          "startUrls": {
            "title": "🔗 Paste Otomoto URLs (listings or single adverts)",
            "type": "array",
            "description": "Full Otomoto.pl URLs. Accepts BOTH listing pages (https://www.otomoto.pl/osobowe/volvo) and individual advert pages (https://www.otomoto.pl/osobowe/oferta/bmw-x5-ID6IbcJS.html). When this list is non-empty it OVERRIDES every search filter below, including the dealer/private split. An advert that has been sold or removed produces a free, uncharged row with the reason instead of silently disappearing.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "category": {
            "title": "🏷️ Otomoto section",
            "enum": [
              "cars",
              "vans",
              "trucks",
              "motorcycles",
              "trailers",
              "campers",
              "construction",
              "agricultural",
              "parts"
            ],
            "type": "string",
            "description": "Otomoto section to sweep. 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"
          },
          "query": {
            "title": "🚘 Brand, or brand plus model",
            "type": "string",
            "description": "Brand, or brand plus model separated by a space. Examples: \"volvo\" → /osobowe/volvo · \"bmw seria 3\" → /osobowe/bmw/seria-3 · \"mercedes-benz c-klasa\". 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": ""
          },
          "location": {
            "title": "🗺️ Town or voivodeship",
            "type": "string",
            "description": "A Polish town (\"Warszawa\", \"Kraków\", \"Łódź\") or a voivodeship (\"Małopolskie\", \"Mazowieckie\"). Polish characters are handled. Otomoto applies its own default catchment radius around a town, so nearby localities are included; a voivodeship is an exact administrative match. If Otomoto cannot resolve the name it falls back to the whole country, so the run FAILS instead of returning national results labelled as a local search.",
            "default": ""
          },
          "sort": {
            "title": "↕️ Result 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: \"Price: low → high\" and \"Price: high → low\" 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 because Otomoto publishes no server-side year sort. The run log always states which one was used.",
            "default": "relevance_web"
          },
          "minPrice": {
            "title": "💰 Price from (PLN)",
            "minimum": 0,
            "type": "integer",
            "description": "Minimum advert price in Polish złoty. Applied by Otomoto as search[filter_float_price:from]."
          },
          "maxPrice": {
            "title": "💸 Price to (PLN)",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum advert price in Polish złoty. Applied by Otomoto as search[filter_float_price:to]."
          },
          "minProductionYear": {
            "title": "📅 Production year from",
            "minimum": 1900,
            "maximum": 2030,
            "type": "integer",
            "description": "Earliest production year, e.g. 2019. Applied by Otomoto as search[filter_float_year:from]."
          },
          "maxProductionYear": {
            "title": "📆 Production year to",
            "minimum": 1900,
            "maximum": 2030,
            "type": "integer",
            "description": "Latest production year, e.g. 2025. Applied by Otomoto as search[filter_float_year:to]."
          },
          "maxItems": {
            "title": "🔢 Max advert pages to fetch",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Hard cap on how many ADVERT pages are scraped. In one-row-per-seller mode the dataset can hold fewer rows than this because adverts are collapsed, never more. Free accounting rows for removed adverts are never charged. Default is 10.",
            "default": 10
          },
          "concurrency": {
            "title": "⚡ Concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many Otomoto requests are made in parallel, advert pages and phone lookups alike. 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}