{
  "openapi": "3.0.1",
  "info": {
    "title": "Kleinanzeigen.de Scraper - Ads, Prices & Seller Details",
    "description": "From $1/1K. Scrape Kleinanzeigen.de ads by keyword, category, location, price, seller type, or search URL. Extract descriptions, photos, attributes, seller details, posted dates, category paths, and imprint data. Returns flat JSON records ready for spreadsheets or databases.",
    "version": "1.0",
    "x-build-id": "W1HB4xGbLqzFchSW5"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~kleinanzeigen-de-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-kleinanzeigen-de-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/abotapi~kleinanzeigen-de-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-kleinanzeigen-de-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/abotapi~kleinanzeigen-de-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-kleinanzeigen-de-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",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "Pick how you want to start: 'search' builds search URLs from the filter fields below, 'url' takes ready-made Kleinanzeigen.de search URLs you paste yourself.",
            "default": "search"
          },
          "keyword": {
            "title": "Keyword",
            "type": "string",
            "description": "Free-text query, e.g. 'fahrrad', 'iphone 14', 'sofa'. Leave empty to browse a whole category."
          },
          "categoryId": {
            "title": "Category ID (optional)",
            "type": "string",
            "description": "Category name or numeric id. A name such as 'Fahrräder' or 'Elektronik' is matched against the site's own category tree (an unknown name stops the run with a clear error); a numeric id such as '217' (Fahrräder & Zubehör) or '161' (Elektronik) is used as is. Find ids in any category URL: .../c217. Leave empty to search all categories."
          },
          "location": {
            "title": "Location (city or postal code, optional)",
            "type": "string",
            "description": "City name or German postal code, e.g. 'Berlin', 'München', '10115'. Resolved automatically to the matching location id. Leave empty to search all of Germany."
          },
          "radiusKm": {
            "title": "Radius around location (km)",
            "minimum": 0,
            "maximum": 200,
            "type": "integer",
            "description": "Search radius in kilometres around the chosen location. Ignored when no location is set. 0 = exact location only.",
            "default": 0
          },
          "minPrice": {
            "title": "Min price (€)",
            "minimum": 0,
            "type": "integer",
            "description": "Lowest price to include. Leave empty for no lower bound."
          },
          "maxPrice": {
            "title": "Max price (€)",
            "minimum": 0,
            "type": "integer",
            "description": "Highest price to include. Leave empty for no upper bound."
          },
          "offerType": {
            "title": "Offer type",
            "enum": [
              "any",
              "angebote",
              "gesuche"
            ],
            "type": "string",
            "description": "Limit to ads offering something ('angebote') or wanted ads ('gesuche'). 'any' includes both.",
            "default": "any"
          },
          "sellerType": {
            "title": "Seller type",
            "enum": [
              "any",
              "privat",
              "gewerblich"
            ],
            "type": "string",
            "description": "Limit to private sellers ('privat') or commercial sellers/shops ('gewerblich'). 'any' includes both.",
            "default": "any"
          },
          "zipCodes": {
            "title": "Several postal codes / cities (optional)",
            "type": "array",
            "description": "Search several places in one run, one search per entry (postal codes such as '10115' or city names). When set it replaces the single Location field; the radius applies to each entry. Ads found by more than one entry are returned once.",
            "items": {
              "type": "string"
            }
          },
          "minRooms": {
            "title": "Min rooms (real estate)",
            "minimum": 0,
            "type": "number",
            "description": "Fewest rooms. Works with categoryId 203 (Mietwohnungen), 196 (Eigentumswohnungen), 205 (Häuser zur Miete) or 208 (Häuser zum Kauf); any other category stops the run with a clear message. Search mode only; in URL mode paste a URL that already carries the filter."
          },
          "maxRooms": {
            "title": "Max rooms (real estate)",
            "minimum": 0,
            "type": "number",
            "description": "Most rooms. Same categories as Min rooms."
          },
          "minArea": {
            "title": "Min living area m² (real estate)",
            "minimum": 0,
            "type": "integer",
            "description": "Smallest living area in m². Same categories as Min rooms."
          },
          "maxArea": {
            "title": "Max living area m² (real estate)",
            "minimum": 0,
            "type": "integer",
            "description": "Largest living area in m². Same categories as Min rooms."
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "relevance",
              "date",
              "price-asc",
              "price-desc",
              "distance"
            ],
            "type": "string",
            "description": "Result ordering. Note: Kleinanzeigen shows promoted ads first regardless of sort.",
            "default": "relevance"
          },
          "urls": {
            "title": "Search URLs",
            "type": "array",
            "description": "One or more Kleinanzeigen.de URLs to scrape (used only when mode = url): search and category pages (keyword k0, category cNNN, keyword within category k0cNNN, location k0l<id>r<km>, price/offer/seller filters, sortingField sort, s-seite:N start page, also /s-<category>/seite:N/cNNN), single ad pages (/s-anzeige/...) which return exactly that ad, seller listing pages (/s-bestandsliste.html?userId=...), commercial shop pages (/pro/<name>, scraped through the shop's seller ad list), the legacy /s-suchanfrage.html?keywords= form and the m. mobile host. ebay-kleinanzeigen.de no longer exists and is skipped with a warning. The default list holds one example per shape.",
            "default": [
              "https://www.kleinanzeigen.de/s-fahrrad/k0",
              "https://www.kleinanzeigen.de/s-fahrraeder/c217",
              "https://www.kleinanzeigen.de/s-auto-rad-boot/c161",
              "https://www.kleinanzeigen.de/s-fahrraeder/mountainbike/k0c217",
              "https://www.kleinanzeigen.de/s-seite:2/fahrrad/k0",
              "https://www.kleinanzeigen.de/s-fahrraeder/seite:2/c217",
              "https://www.kleinanzeigen.de/s-fahrrad/k0?sortingField=SORTING_DATE",
              "https://www.kleinanzeigen.de/s-fahrrad/k0?sortingField=PRICE_AMOUNT",
              "https://www.kleinanzeigen.de/s-rennrad/k0?sortingField=SORTING_DATE&pageNum=2",
              "https://www.kleinanzeigen.de/s-berlin/fahrrad/k0l3331r20",
              "https://www.kleinanzeigen.de/s-85737/fahrrad/k0l7554",
              "https://www.kleinanzeigen.de/s-berlin/c217",
              "https://www.kleinanzeigen.de/s-berlin/k0l3331",
              "https://www.kleinanzeigen.de/s-fahrraeder/c217?sortingField=SORTING_DATE",
              "https://www.kleinanzeigen.de/s-anzeige:angebote/anbieter:privat/preis:100:300/fahrrad/k0",
              "https://www.kleinanzeigen.de/s-anzeige/-jubilaeumsangebot-bullitt-e6100-kiddo-ebullitt-e6100-lizzard-king-ebullitt-lastenrad-cargobike-shimano-6100-kindertransport-504wh-larry-vs-harry/2807683512-217-6860",
              "https://www.kleinanzeigen.de/s-anzeige/2807683512",
              "https://www.kleinanzeigen.de/s-bestandsliste.html?userId=1",
              "https://www.kleinanzeigen.de/pro/ClassyCycleClub",
              "https://www.kleinanzeigen.de/s-suchanfrage.html?keywords=fahrrad",
              "https://m.kleinanzeigen.de/s-fahrrad/k0"
            ],
            "items": {
              "type": "string"
            }
          },
          "maxPages": {
            "title": "Max pages per search",
            "minimum": 0,
            "type": "integer",
            "description": "How many result pages to walk per search/URL (27 ads per page). 0 = unlimited (walk until the last page Kleinanzeigen serves for that search; Kleinanzeigen may itself cap a search around 50 pages, which is fine, the walk simply stops there).",
            "default": 0
          },
          "maxListings": {
            "title": "Max listings total",
            "minimum": 0,
            "type": "integer",
            "description": "Stop after this many ads across all searches. 0 = unlimited (still bounded by maxPages).",
            "default": 20
          },
          "fetchDetails": {
            "title": "Fetch full ad details",
            "type": "boolean",
            "description": "Open every ad's detail page to pull the full description, all photos, attributes, seller info, view count, category path, and commercial-seller imprint. Turn off for a faster, cheaper run with just the search-result fields (~14 fields).",
            "default": true
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Residential proxy is strongly recommended and is the default. When no country is pinned (the default), each new connection lands on a different EU country (DE, AT, NL, BE, FR, IT, ES, PL, CZ, SE, DK, CH) so a single throttled exit cannot stall the whole run. Pin a country (DE recommended for kleinanzeigen.de) to force all connections through one location.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run (optional)",
            "type": "string",
            "description": "Paste a previous run ID or dataset ID to continue ONE interrupted full-catalogue walk across separate runs. Ads already collected there (matched by ad id) are skipped, so this run only saves the new ones. Leave empty for a normal fresh run. Distinct from 'Incremental mode' below, which tracks the SAME recurring search across many scheduled runs by itself."
          },
          "incrementalMode": {
            "title": "Incremental mode (track changes across scheduled runs)",
            "type": "boolean",
            "description": "When ON, this actor remembers the ads from its own previous run of the SAME search (see 'State key' below) and tags every ad with a changeType: NEW, UPDATED, UNCHANGED, REAPPEARED, or EXPIRED. Use with the Apify Scheduler to monitor a search over time instead of re-scraping everything from scratch. Distinct from 'Resume from a previous run' above, which continues one specific interrupted run rather than tracking a recurring search. Default OFF — existing users/schedules are unaffected.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional, incremental mode only)",
            "type": "string",
            "description": "A name for this recurring search's saved state, e.g. 'berlin-fahrrad-watch'. Leave empty to auto-derive one from your search/filter settings (mode, keyword, category, location, radius, price, offer/seller type, sort, URLs, fetch details) — two different filter setups never share a baseline. Set this explicitly if you want a stable name across input tweaks that shouldn't reset tracking, or to run several independent monitors from the same actor."
          },
          "emitUnchanged": {
            "title": "Emit UNCHANGED ads (incremental mode only)",
            "type": "boolean",
            "description": "When ON, ads with no detected change are still pushed to the dataset (tagged changeType=UNCHANGED) instead of being skipped. This returns — and BILLS — one extra row per unchanged ad every run. Default OFF: only NEW/UPDATED/REAPPEARED/EXPIRED ads are pushed.",
            "default": false
          },
          "emitExpired": {
            "title": "Emit EXPIRED ads (incremental mode only)",
            "type": "boolean",
            "description": "When ON, ads tracked in a previous run but no longer found after a complete, uncapped scan are pushed once more tagged changeType=EXPIRED. This returns — and BILLS — one extra row per expired ad. Only fires on a run that reaches the real end of every tracked search (no resumeFromRunId, no maxListings/maxPages cap hit) — a partial run never marks anything expired. Default OFF.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Field names that must NOT count as a change in incremental mode, e.g. description or imageUrls. A name matches at any depth; use a dotted path such as seller.name to target one nested field. Ignored fields stay in the output; they just never turn an ad into UPDATED or appear in changedFields. Already ignored by default: scrapedAt, searchUrl, viewCount, sellerOtherAdsCount, postedDateText, isTopAd, image resize parameters and the order of tags.",
            "items": {
              "type": "string"
            }
          },
          "mcpConnectors": {
            "title": "Pipe results into your apps (optional)",
            "type": "array",
            "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
          },
          "notionParentPageUrl": {
            "title": "Notion parent page (Notion connector only)",
            "type": "string",
            "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
          },
          "maxNotifyListings": {
            "title": "Max items to export per connector",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Cap on items written to each connector per run. Does not affect the dataset.",
            "default": 50
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}