--- title: Web Crawl description: Scrape any page or crawl a whole site into clean markdown --- The web crawler fetches one or more pages — or spiders a whole site — and returns each page as clean markdown, plus metadata, every link with its anchor text, and harvested contact signals (emails, phone numbers, social profiles). JS-rendered pages are loaded in a real browser and auto-scrolled, so lazy-loaded listings are captured too. ## Endpoint ```bash POST /api/v1/workspaces/{workspace_id}/scrapers/web/crawl ``` ## Inputs | Field | Default | Description | |-------|---------|-------------| | `startUrls` | required | 1–20 seed URLs | | `maxCrawlDepth` | `0` | Link-hops to follow from each seed. `0` = fetch only the seeds; `1` = also the pages they link to; up to 5. The spider stays on the seed's site | | `maxCrawlPages` | `10` | Total pages fetched per call, seeds included (max 200) | | `maxLength` | `50000` | Max characters of markdown kept per page | | `includeUrlPatterns` | — | Regexes a discovered link must match to be followed (empty = follow every same-site link) | | `excludeUrlPatterns` | — | Regexes that exclude links from being followed (wins over include) | ## Example Scrape a single page: ```bash curl -X POST "$BASE_URL/api/v1/workspaces/1/scrapers/web/crawl" \ -H "Authorization: Bearer $SURFSENSE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "startUrls": ["https://example.com/pricing"] }' ``` Crawl a site's blog, two hops deep: ```bash curl -X POST "$BASE_URL/api/v1/workspaces/1/scrapers/web/crawl" \ -H "Authorization: Bearer $SURFSENSE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "startUrls": ["https://example.com/blog"], "maxCrawlDepth": 2, "maxCrawlPages": 50, "includeUrlPatterns": ["/blog/"] }' ``` ## Output One item per fetched page (in crawl order) with its markdown, metadata (title, description), crawl provenance (depth, referrer), links classified as internal/external/social/email/tel, and page-level contacts. The response also includes a site-wide `contacts` summary that deduplicates every email, phone, and social profile found — `siteWide: true` marks header/footer values (the company's own contacts) versus page-local finds like individual team members. Contact details often live on about/contact/privacy pages, so crawl with `maxCrawlDepth >= 1` to surface them — useful for lead generation and competitive intelligence. Billing is per successfully fetched page. For the full input and output JSON schemas and generated code snippets in your language, open **API Playground → Web → Crawl** in your workspace.