{
  "openapi": "3.0.1",
  "info": {
    "title": "Clutch Scraper - Companies, Ratings, Reviews & Pricing",
    "description": "Scrape Clutch company directories and profiles. Get names, ratings, review counts, hourly rate, min project size, employees, location, services, full reviews with reviewer details and per-criterion scores. Search and URL mode, 40+ fields per company.",
    "version": "1.1",
    "x-build-id": "b03QTl1vm0Bs6YNye"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/abotapi~clutch-directory-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-abotapi-clutch-directory-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~clutch-directory-scraper/runs": {
      "post": {
        "operationId": "runs-sync-abotapi-clutch-directory-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~clutch-directory-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-abotapi-clutch-directory-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": "How to start the scrape. 'search' builds a directory URL from the filters below. 'url' takes the exact Clutch directory URLs you paste.",
            "default": "search"
          },
          "directory": {
            "title": "Directory",
            "type": "string",
            "description": "Which Clutch directory to scrape in search mode. Accepts a plain category name ('Web Developers', 'SEO', 'Mobile App Development') or a Clutch directory slug directly, including a nested one like 'developers/php'. Live-verified slugs: 'web-developers', 'web-designers', 'developers', 'agencies', 'seo-firms', 'app-developers', 'it-services', 'pr-firms', 'call-centers', 'bpo', 'accounting', 'translation'. Any other slug is still tried as-is, but a bad one now gets a loud warning in the run log instead of a silent empty result.",
            "default": "web-developers"
          },
          "location": {
            "title": "Location",
            "type": "string",
            "description": "Optional location to narrow results -- a plain name ('united states', 'London', 'India') or the exact Clutch path segment. Most countries are a leading segment ('us', 'de', 'au', ...); the United Kingdom and India are a confirmed exception handled automatically, and a handful of major cities (New York, Los Angeles, Houston, Chicago, Ontario, London, Sydney, Dubai) are recognised by name. An unrecognised value is still tried as a best-effort guess. Leave empty for worldwide."
          },
          "agencySize": {
            "title": "Company size",
            "type": "string",
            "description": "Optional company-size filter -- one of Clutch's own buckets: '2 - 9', '10 - 49', '50 - 249', '250 - 999', '1,000 - 9,999' employees (underscore or plain forms like '50_-_249' / '50-249' also work; the thousands bucket's comma is added automatically if left out -- Clutch's own filter silently ignores an un-comma'd '1000 - 9999'). Leave empty for any size."
          },
          "relatedServices": {
            "title": "Related service",
            "type": "string",
            "description": "Optional service-line filter -- a plain name ('Mobile App Development', 'SEO', 'Ecommerce Development', 'Public Relations') or the raw Clutch value directly, for example 'field_pp_sl_ecommerce'. An unrecognised name is still sent as-is, but Clutch silently ignores a value it does not recognise (the run log warns when this happens). Leave empty for all services."
          },
          "sortBy": {
            "title": "Sort by",
            "enum": [
              "default",
              "review_rating",
              "reviews",
              "date"
            ],
            "type": "string",
            "description": "Result ordering. Search mode only: this reorders the results the site returns, so it has no equivalent in URL mode.",
            "default": "default"
          },
          "urls": {
            "title": "Clutch directory URLs",
            "type": "array",
            "description": "Paste one or more Clutch URLs. Multi-URL supported. Filter fields above are ignored. Supported shapes: a directory listing, a nested directory (.../developers/php), a country- or city-scoped directory (.../us/web-developers, .../web-developers/uk), a directory with filter query params and/or a page number (results continue from that page), a company profile (.../profile/<slug>, with or without a #reviews fragment -- returned as ONE fully enriched record, not a listing), Clutch's own keyword-search page (.../search?q=...), and the www host / utm_* tracking params (ignored harmlessly). A URL that matches none of these (a dead slug, a genuine 404) gets a loud warning in the run log, never a silent empty result.",
            "items": {
              "type": "string"
            }
          },
          "minRating": {
            "title": "Min rating",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Only keep companies with at least this overall rating (0 to 5). Applied after fetching, so it narrows results in BOTH search mode and URL mode."
          },
          "minReviews": {
            "title": "Min reviews",
            "minimum": 0,
            "type": "integer",
            "description": "Only keep companies with at least this many reviews. Applied after fetching, so it narrows results in BOTH search mode and URL mode."
          },
          "fetchDetails": {
            "title": "Fetch full profile details (richer records)",
            "type": "boolean",
            "description": "Open each company profile to add founding year, languages, locations, reviews (up to Max reviews, quote, feedback, summary, reviewer details, per-criterion scores, project size and length) and the rating breakdown. Adds one HTTP request per record, plus one more per extra review page (see Max reviews).",
            "default": true
          },
          "maxReviews": {
            "title": "Max reviews per company",
            "minimum": 0,
            "type": "integer",
            "description": "How many reviews to collect per company, oldest pages fetched first (Clutch shows ~10-11 per profile page). Only applies when Fetch full profile details is on, in both search mode and URL mode (incl. a pasted company-profile URL). 0 skips extra review pages entirely and keeps just the reviews already on the profile's first page. Default 20 reads one extra review page per company when needed.",
            "default": 20
          },
          "maxPages": {
            "title": "Max pages per list",
            "minimum": 0,
            "type": "integer",
            "description": "How many result pages to read per directory URL. Does NOT cap the run. Leave at 0 to walk the whole catalogue — the run stops on its own at the site's last page or a repeat-page guard, not an artificial page cap. The run is bounded by Max records, which is the cap. Set this only if you want to additionally limit how many pages are read per directory.",
            "default": 0
          },
          "maxListings": {
            "title": "Max records",
            "minimum": 0,
            "type": "integer",
            "description": "THE cap for the run: stop after this many records (default 20). Set to 0 for unlimited.",
            "default": 20
          },
          "proxy": {
            "title": "Proxy",
            "type": "object",
            "description": "Network connection. The default works on all plans and is recommended. You can switch to a different proxy option for heavier runs.",
            "default": {
              "useApifyProxy": true
            }
          },
          "resumeFromRunId": {
            "title": "Resume from a previous run (delta)",
            "type": "string",
            "description": "Optional. ID of a previous run of this actor (or a dataset ID). Companies already in that dataset are skipped, so this run returns only NEW companies (a delta). Combine both runs' datasets for the full set. For a recurring monitoring schedule, use Incremental mode below instead."
          },
          "incrementalMode": {
            "title": "Incremental mode (recurring monitoring)",
            "type": "boolean",
            "description": "When ON, this actor remembers the companies from its last run of the SAME search (see State key) and tags each company NEW / UPDATED / UNCHANGED / REAPPEARED / EXPIRED, so a daily/weekly schedule returns only what changed. Off by default: every run returns the full result set with no change tracking, exactly as before. Combine with resumeFromRunId only to bootstrap a monitoring campaign from one prior run's dataset, not on every scheduled run.",
            "default": false
          },
          "stateKey": {
            "title": "State key (optional)",
            "type": "string",
            "description": "Only used when Incremental mode is ON. Leave empty to auto-derive the tracked scope from your search filters (directory, location, company size, related service, sort, min rating, min reviews, URLs, fetch details) — two different filter setups then never share a baseline. Set an explicit value to intentionally share state across otherwise-different filter setups, or to run multiple separate monitoring campaigns."
          },
          "emitUnchanged": {
            "title": "Also return unchanged companies",
            "type": "boolean",
            "description": "Only used when Incremental mode is ON. Off by default: companies with no changes since the last run are suppressed (not returned, not billed). Turn ON to also return every UNCHANGED company each run — this returns and BILLS more rows.",
            "default": false
          },
          "emitExpired": {
            "title": "Also return expired companies",
            "type": "boolean",
            "description": "Only used when Incremental mode is ON. Off by default. Turn ON to emit a row (changeType EXPIRED) for companies that were in the previous run's tracked set but are no longer found — only on a run that completes a full, uncapped, non-resumed scan of the tracked search. This returns and BILLS extra rows.",
            "default": false
          },
          "ignoreFieldsForChanges": {
            "title": "Ignore fields when detecting changes (incremental mode only)",
            "type": "array",
            "description": "Only used when Incremental mode is ON. Output field names (or dotted paths, e.g. \"metadata.scraped_at\") that should NOT make a company count as UPDATED. The directory-rank fields (position, metadata.position, listing.position) and this page's own URL (sourceUrl, metadata.seed_url) are always ignored, since they shift whenever any other company is added, removed, or reordered on the page, not because this company actually changed. Add a field here if changes to it are not relevant to you — it is still returned in the output, just excluded from change detection.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}