{
  "openapi": "3.0.1",
  "info": {
    "title": "Nettiauto Scraper — Finland Cars, EV Battery & Dealers",
    "description": "Scrape nettiauto.com, Finland's largest car marketplace: every listing with VIN, plate, first registration date, battery kWh, electric range and state of health, the full photo gallery, the dealer's own details and the phone number hidden behind the call button. One flat row per car.",
    "version": "0.0",
    "x-build-id": "i6LLSREwYgaEzhiYt"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~nettiauto-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-nettiauto-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/memo23~nettiauto-scraper/runs": {
      "post": {
        "operationId": "runs-sync-memo23-nettiauto-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/memo23~nettiauto-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-nettiauto-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": {
          "startUrls": {
            "title": "Nettiauto URLs (search or ad)",
            "type": "array",
            "description": "nettiauto.com search-result or ad URLs, auto-classified. Search: `https://www.nettiauto.com/pikalinkit/sahkoautot?posted_by=dealer`. Filter search: `https://www.nettiauto.com/vaihtoautot?posted_by=dealer`. Ad: `https://www.nettiauto.com/audi/e-tron/16025210`. A dealer's own inventory page works too. Leave empty to build a search from the filters below. Example: [\"https://www.nettiauto.com/pikalinkit/sahkoautot?posted_by=dealer\"]. Default: empty.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "dealersOnly": {
            "title": "Dealers only",
            "type": "boolean",
            "description": "Only cars posted by dealers, which is what `posted_by=dealer` does on the site. Turn off to include private sellers. Example: true. Default: true.",
            "default": true
          },
          "electricOnly": {
            "title": "Electric cars only",
            "type": "boolean",
            "description": "Restrict to electric cars, the way the site's own quick link does. Turn off for every fuel type. Example: true. Default: true.",
            "default": true
          },
          "priceFrom": {
            "title": "Min price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Lowest asking price in euros. nettiauto's quick links ignore price and its filter form drops the dealer filter when a price is set, so the actor sorts the search by price and applies the range itself, stopping once prices pass it. A price in a pasted search URL (`priceFrom`/`priceTo`) is handled the same way. Example: 10000. Default: no minimum."
          },
          "priceTo": {
            "title": "Max price (EUR)",
            "minimum": 0,
            "type": "integer",
            "description": "Highest asking price in euros, applied the same way as the minimum. Example: 15000. Default: no maximum."
          },
          "scrapeDetails": {
            "title": "Scrape ad pages",
            "type": "boolean",
            "description": "Open each car's own page for the full record: spec table, battery capacity and range, VIN, plate, first-registration date, description, the whole gallery and the dealer's block. Without it there is nothing to return but an id and a URL, so leave it on unless you want the list-only mode below. Example: true. Default: true.",
            "default": true
          },
          "scrapePhone": {
            "title": "Get seller phone numbers",
            "type": "boolean",
            "description": "Return the number behind the call button as `phone`. The page shows it as an image, but the button answers with a redirect carrying the number in plain text, so no image is read and no login is needed. Costs one extra request per car and is included in the per-result price. While Cloudflare blocks a run's IP the actor continues through Apify's Unblocker, which cannot pass that redirect, so cars fetched during a block come without a phone; the run log says how many. Example: true. Default: false.",
            "default": false
          },
          "listOnly": {
            "title": "List mode (id and URL only)",
            "type": "boolean",
            "description": "Emit one thin row per car, with its id and URL, without opening a single ad page. Useful for working out which cars are new since your last run before paying to scrape them in full. `modifiedAt` stays empty in this mode: search results carry no date, and the updated date is printed only on the ad itself. Example: false. Default: false.",
            "default": false
          },
          "includeRawData": {
            "title": "Include the page's raw data",
            "type": "boolean",
            "description": "Attach the ad's own `window.digitalData` object and every ld+json block to each row as `raw`, unchanged, for anyone who wants to read fields themselves. The handful of values the browser computes at load time (viewport, window width, user agent, page title, page location) are null, because they have no value outside a browser. Adds about 5 KB per row and many columns to CSV and Excel exports, so it is off by default. Included in the per-result price. Example: true. Default: false.",
            "default": false
          },
          "enrichEmails": {
            "title": "Find dealer emails",
            "type": "boolean",
            "description": "Look up the dealer's email address on their own website and return it as `contactEmail`. The ad's own \"Www-sivut\" link gives the site on nearly every row, and where it does not, the dealer's name is used to find it. Each dealer is looked up once per run however many cars they list, and only a found address is charged. Example: false. Default: false.",
            "default": false
          },
          "failOnIncomplete": {
            "title": "Fail the run when the dataset is short",
            "type": "boolean",
            "description": "End the run as FAILED when the shortfall against the reported count exceeds the threshold below. Runs stopped by your own row limits are exempt — those are partial by request. Delivering more rows than reported never fails: ads are published while a run is in flight and rows are deduplicated by ad id. Example: true. Default: true.",
            "default": true
          },
          "completenessTolerancePercent": {
            "title": "Tolerance (% of reported)",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Relative half of the threshold. The count moves while a run is in flight, so a strict match would fail nearly every run. Example: 1. Default: 1.",
            "default": 1
          },
          "completenessToleranceAbsolute": {
            "title": "Tolerance (ads)",
            "minimum": 0,
            "type": "integer",
            "description": "Absolute floor of the threshold; the larger of the two wins. On a small search 1% is only a handful of cars, well inside a day's churn — this floor is what stops those runs failing on noise. Example: 25. Default: 25.",
            "default": 25
          },
          "maxItems": {
            "title": "Max results (whole run)",
            "minimum": 1,
            "type": "integer",
            "description": "Hard cap on rows across the entire run; each row is one paid result. Free-tier accounts are additionally capped at 100. Example: 500. Default: 1000.",
            "default": 1000
          },
          "maxItemsPerSearch": {
            "title": "Max results per search",
            "minimum": 1,
            "type": "integer",
            "description": "Cap on rows from any one search URL. Example: 1000. Default: 1000.",
            "default": 1000
          },
          "maxConcurrency": {
            "title": "Max parallel requests",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many HTTP requests run at once. Eight is comfortable against this site; raise for speed, lower to be gentler. Example: 8. Default: 8.",
            "default": 8
          },
          "maxRequestRetries": {
            "title": "Max request retries",
            "minimum": 0,
            "maximum": 20,
            "type": "integer",
            "description": "Per-request retry budget for 403/429/5xx and network errors, with exponential backoff. Example: 6. Default: 6.",
            "default": 6
          },
          "proxy": {
            "title": "Proxy configuration (optional)",
            "type": "object",
            "description": "Leave empty. The actor clears the site's Cloudflare setup from plain datacenter IPs once the session cookies are in place, and when Cloudflare does block a run's IP it falls back to Apify's Unblocker on its own, at no extra charge to you. Set this only if you need requests to exit through your own proxy. Example: {\"useApifyProxy\": true}. Default: no proxy."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}