{
  "openapi": "3.0.1",
  "info": {
    "title": "Blocket.se Car Scraper: All Swedish listings",
    "description": "Scrape every car on Blocket.se — price with and without VAT, mileage in km, VIN, registration plate, battery kWh, equipment, all photos, plus seller phone, email, website and address. Splits past Blocket's 2,450-per-search limit to reach all ~144,000 listings. JSON or CSV.",
    "version": "0.0",
    "x-build-id": "noeJiEmMxkYcAbigL"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~blocket-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-blocket-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~blocket-scraper/runs": {
      "post": {
        "operationId": "runs-sync-memo23-blocket-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~blocket-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-blocket-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": "Blocket URLs",
            "type": "array",
            "description": "Search URLs, single ads, or dealer pages — the actor works out which is which. Leave empty to scrape every car on Blocket. Example search: https://www.blocket.se/mobility/search/car?fuel=4&dealer_segment=2&sales_form=1 (used electric cars sold by businesses). Any filter Blocket supports is passed through untouched.",
            "items": {
              "type": "string"
            }
          },
          "dealerOrgIds": {
            "title": "Dealer organisation IDs",
            "type": "array",
            "description": "Dealer org IDs (the number in /mobility/dealer/{orgId}). Each one is expanded into that dealer's complete inventory.",
            "items": {
              "type": "string"
            }
          },
          "detailLevel": {
            "title": "Detail level",
            "enum": [
              "basic",
              "full",
              "fullDealer"
            ],
            "type": "string",
            "description": "How much is collected per ad. 'Basic' reads the search results only — about 35 fields per car including price, mileage, VIN, registration number, coordinates and images — and needs no extra request, so it is by far the fastest. 'Full' opens each ad for description, equipment list, battery capacity, colour, registration date, inspection dates, previous owners and the seller's street address. 'Full + dealer' also loads each dealer's profile page once for their website, email and postal address.",
            "default": "full"
          },
          "includePhone": {
            "title": "Resolve phone numbers",
            "type": "boolean",
            "description": "Fetch the number behind each ad's 'Visa telefonnummer' button. It can differ from the phone on the dealer's profile page, so both are kept in separate fields. Needs a detail level above Basic and costs one extra request per ad. Around 7% of ads expose no number.",
            "default": false
          },
          "maxItems": {
            "title": "Max results",
            "minimum": 1,
            "type": "integer",
            "description": "Stop after this many cars. Blocket lists newest first, so up to 2,000 cars come straight from the newest results in seconds. Larger numbers make the actor split the search to get past Blocket's 2,450-per-search limit; the whole market is roughly 149,000 cars.",
            "default": 1000
          },
          "onlyNew": {
            "title": "Only new listings (for scheduled runs)",
            "type": "boolean",
            "description": "Return only ads that earlier runs did not return. Each run remembers the ads it returned and where it stopped reading, so a run on a schedule picks up exactly what was published since the previous one, stops paging as soon as it reaches older ads, and never charges twice for the same car. The first run sets the starting point by returning the newest ads up to Max results. The memory is kept in a key-value store named blocket-scraper-monitor in your account, one record per set of URLs (or per Monitor name under Advanced).",
            "default": false
          },
          "compareToMarket": {
            "title": "Compare each car with the market",
            "type": "boolean",
            "description": "Add an estimated market value to every car: the median asking price of similar cars listed on Blocket right now (same model, fuel, gearbox and new/used, then as close as possible on year, trim, seller type and mileage, with each comparable adjusted to this car's mileage). Adds marketValue, priceVsMarketSek, priceVsMarketPct, how many cars it rests on, a confidence level and five of the comparables so you can check it. These are asking prices; Blocket publishes no sale prices. Charged per car valued.",
            "default": false
          },
          "onlyBelowMarketBySek": {
            "title": "Only cars at least this many SEK below market",
            "minimum": 0,
            "type": "integer",
            "description": "Return only cars priced at least this far under their market value, e.g. 10000. Turns market comparison on. A car is checked against the market from its search result first, so cars that miss cost no ad-page request. With this set, Max results limits how many cars are checked, not how many come back."
          },
          "onlyBelowMarketByPct": {
            "title": "Only cars at least this many percent below market",
            "minimum": 0,
            "maximum": 90,
            "type": "integer",
            "description": "Same as above, as a percentage, e.g. 10. When both are set a car has to clear both."
          },
          "minDealConfidence": {
            "title": "Confidence needed for a below-market match",
            "enum": [
              "medium",
              "high"
            ],
            "type": "string",
            "description": "'Medium' needs at least five close comparables that roughly agree on price. 'High' also needs the same seller type (private or dealer), eight or more cars and a tight price spread: fewer matches, fewer false alarms.",
            "default": "medium"
          },
          "includeRedFlagged": {
            "title": "Keep red-flagged cars",
            "type": "boolean",
            "description": "Below-market cars whose ad mentions engine or gearbox failure, a driving ban, parts only, crash or water damage, export only or a lease takeover, or whose price is under 35% of market, are dropped by default: they are cheap for a reason. Turn this on to keep them (they still carry the redFlags field). The ad text is read at detail level Full; at Basic only the title is checked.",
            "default": false
          },
          "telegramBotToken": {
            "title": "Telegram bot token",
            "type": "string",
            "description": "Send every car this run returns to Telegram, as a photo with price, mileage, market comparison and link. Create a bot with @BotFather and paste its token here. Pairs well with 'Only new listings' on a schedule and a below-market threshold: you get a message only for new cheap cars. Charged per alert delivered."
          },
          "telegramChatId": {
            "title": "Telegram chat ID",
            "type": "string",
            "description": "Your chat, group or channel ID (e.g. 123456789 or -1001234567890). Message your bot once first, or add it to the group. @userinfobot tells you your own ID."
          },
          "maxTelegramAlerts": {
            "title": "Max alerts per run",
            "minimum": 1,
            "maximum": 500,
            "type": "integer",
            "description": "Stop sending after this many; the rest are summed up in one closing message with a link to the run. Telegram allows about one message a second to a person and twenty a minute to a group.",
            "default": 50
          },
          "safePartitionCap": {
            "title": "Partition split threshold",
            "minimum": 100,
            "maximum": 2450,
            "type": "integer",
            "description": "Blocket refuses to paginate past 2,450 results per query, so the actor splits any search bigger than this into price ranges. The default of 2,000 leaves headroom for ads posted mid-crawl. Raising it toward 2,450 risks silently losing the tail of a partition.",
            "default": 2000
          },
          "fullCoveragePass": {
            "title": "Full coverage pass",
            "type": "boolean",
            "description": "About 0.05% of Blocket's cars are listed without a price, and the actor splits large searches by price — so those ads cannot be reached on that axis. Turn this on to run a second sweep by year and merge the results. It roughly doubles the search-page traffic; per-ad and per-dealer requests are deduplicated, so those are not repeated.",
            "default": false
          },
          "partitionConcurrency": {
            "title": "Partition planning concurrency",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many counting queries run at once while the actor works out how to split a large search.",
            "default": 5
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Maximum parallel requests while scraping ads.",
            "default": 10
          },
          "minConcurrency": {
            "title": "Min concurrency",
            "minimum": 1,
            "type": "integer",
            "description": "Minimum parallel requests.",
            "default": 1
          },
          "maxRequestRetries": {
            "title": "Max request retries",
            "minimum": 0,
            "type": "integer",
            "description": "How many times a failed request is retried before the actor gives up on it.",
            "default": 5
          },
          "monitorId": {
            "title": "Monitor name",
            "type": "string",
            "description": "Only used with 'Only new listings'. Runs with the same name share one memory of which ads were already returned. Leave empty to tie the memory to the exact list of URLs, which means editing the list starts a fresh baseline. Give each schedule its own name if you run several over the same search."
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. Blocket serves this actor without a proxy, so leave it unset unless your runs start failing. When set, it replaces the actor's built-in residential pool."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}