{
  "openapi": "3.0.1",
  "info": {
    "title": "Local.ch $1💰 Listings | URLs | Reviews Scraper",
    "description": "From $1/1K. Pull structured company data from local.ch, including name, address, GPS, phone, email, website, hours, ratings, social links, photos, and categories. Search by category and location or use URLs. Supports Deutsch, English, Français, and Italiano.",
    "version": "0.1",
    "x-build-id": "tVC5ORaYkArPh7aoA"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~local-ch-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-local-ch-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~local-ch-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-local-ch-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~local-ch-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-local-ch-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": "Run mode",
            "enum": [
              "search",
              "url"
            ],
            "type": "string",
            "description": "Choose where the actor should start. Search mode builds searches from category and location. URL mode uses pasted local.ch URLs.",
            "default": "search"
          },
          "reviewOnly": {
            "title": "Review-only output",
            "type": "boolean",
            "description": "When ON, output one row per review comment instead of profile listing rows. Works in both search and URL modes.",
            "default": false
          },
          "category": {
            "title": "Category (single)",
            "type": "string",
            "description": "Used in search mode. Examples: `restaurant`, `coiffeur`, `hairdresser`, `dentist`, `garage`, `hotel`.",
            "default": "restaurant"
          },
          "queries": {
            "title": "Categories (multi)",
            "type": "array",
            "description": "Used in search mode. Optional list of categories to search. When set, this overrides the single `category` field.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "where": {
            "title": "Location",
            "type": "string",
            "description": "Used in search mode. Examples: city slug (`zurich`), postal code (`8001`), canton code (`zh`), or `switzerland`.",
            "default": "zurich"
          },
          "language": {
            "title": "Language",
            "enum": [
              "de",
              "en",
              "fr",
              "it"
            ],
            "type": "string",
            "description": "Used for URLs and page content. local.ch supports German, English, French, and Italian.",
            "default": "de"
          },
          "urls": {
            "title": "local.ch URLs",
            "type": "array",
            "description": "Used in URL mode. Paste one or more local.ch URLs.\n• Search URL: walks result pages\n• Profile URL: scrapes one profile page\n\nWith `reviewOnly=true`, the actor outputs review comments instead of listing rows.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxPages": {
            "title": "Maximum pages per search",
            "minimum": 1,
            "maximum": 20000,
            "type": "integer",
            "description": "Maximum result pages to walk per category or search URL.",
            "default": 1
          },
          "maxListings": {
            "title": "Maximum rows (0 = unlimited)",
            "minimum": 0,
            "type": "integer",
            "description": "Maximum dataset rows to output. Listing rows when `reviewOnly=false`, review rows when `reviewOnly=true`.",
            "default": 0
          },
          "fetchDetails": {
            "title": "Fetch detail pages",
            "type": "boolean",
            "description": "When ON, enrich listing rows with profile-page fields like phone, email, full address, coordinates, opening hours, social links, and attributes.",
            "default": true
          },
          "includeReviews": {
            "title": "Include review comments",
            "type": "boolean",
            "description": "Listing output only. Embed review comments inside each listing row. Ignored when `reviewOnly=true`.",
            "default": false
          },
          "maxReviewsPerListing": {
            "title": "Maximum reviews per listing",
            "minimum": 0,
            "maximum": 10,
            "type": "integer",
            "description": "Listing output only. Maximum review comments to embed in each listing row. Values above 10 are capped to 10.",
            "default": 10
          },
          "maxReviewRows": {
            "title": "Maximum review rows",
            "minimum": 0,
            "type": "integer",
            "description": "Review-only output only. Default review-row cap when `reviewOnly=true` and `maxListings=0`.",
            "default": 10
          },
          "maxConcurrency": {
            "title": "Max concurrent detail requests",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many profile pages to fetch in parallel.",
            "default": 6
          },
          "ratedOnly": {
            "title": "Only listings with ratings",
            "type": "boolean",
            "description": "Listing output only. Keep only listing rows that have an average rating.",
            "default": false
          },
          "minRating": {
            "title": "Minimum rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Listing output only. Keep only listing rows at or above this rating."
          },
          "withPhone": {
            "title": "Only listings with a phone number",
            "type": "boolean",
            "description": "Listing output only. Keep only listing rows with a phone number.",
            "default": false
          },
          "withEmail": {
            "title": "Only listings with an email address",
            "type": "boolean",
            "description": "Listing output only. Keep only listing rows with an email address.",
            "default": false
          },
          "withWebsite": {
            "title": "Only listings with a website",
            "type": "boolean",
            "description": "Listing output only. Keep only listing rows with a website.",
            "default": false
          },
          "premiumOnly": {
            "title": "Only premium-listed companies",
            "type": "boolean",
            "description": "Listing output only. Keep only premium-listed profiles.",
            "default": false
          },
          "matchQueryPostalCode": {
            "title": "Only listings matching the query postal code",
            "type": "boolean",
            "description": "Search mode only. When ON and the location is a postal code (e.g. `8001`), keep only results whose postal code exactly matches the queried one, and skip the rest before any detail-page fetch (saves proxy GB). local.ch's search is not strictly postal-code-bound — when few exact matches exist it pads the page with other regions — so this removes those off-target hits. Default OFF preserves current behaviour.",
            "default": false
          },
          "skipRegionalFallback": {
            "title": "Only listings from exact query matches (no regional fallback)",
            "type": "boolean",
            "description": "Search mode only. When a query has zero exact matches, local.ch silently falls back to a region-wide search and shows unrelated results (e.g. `psychologie` in `1346`). When ON, the actor detects this fallback and emits no output for that query — no detail-page fetch, no rows. Default OFF preserves current behaviour.",
            "default": false
          },
          "proxy": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Proxy settings. Swiss residential is recommended — local.ch serves large pages and the shared datacenter pool can stall on them. If residential isn't on your plan, the actor automatically falls back to a datacenter and then a backup pool.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ],
              "apifyProxyCountry": "CH"
            }
          },
          "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}