# Scrapfly Documentation

## Table of Contents

### Dashboard

- [Intro](https://scrapfly.io/docs)
- [Project](https://scrapfly.io/docs/project)
- [Account](https://scrapfly.io/docs/account)
- [Workspace & Team](https://scrapfly.io/docs/workspace-and-team)
- [Billing](https://scrapfly.io/docs/billing)

### Products

#### MCP Server

- [Getting Started](https://scrapfly.io/docs/mcp/getting-started)
- [Tools & API Spec](https://scrapfly.io/docs/mcp/tools)
- [Authentication](https://scrapfly.io/docs/mcp/authentication)
- [Examples & Use Cases](https://scrapfly.io/docs/mcp/examples)
- [FAQ](https://scrapfly.io/docs/mcp/faq)
##### Integrations

- [Overview](https://scrapfly.io/docs/mcp/integrations)
- [Claude Desktop](https://scrapfly.io/docs/mcp/integrations/claude-desktop)
- [Claude Code](https://scrapfly.io/docs/mcp/integrations/claude-code)
- [ChatGPT](https://scrapfly.io/docs/mcp/integrations/chatgpt)
- [Cursor](https://scrapfly.io/docs/mcp/integrations/cursor)
- [Cline](https://scrapfly.io/docs/mcp/integrations/cline)
- [Windsurf](https://scrapfly.io/docs/mcp/integrations/windsurf)
- [Zed](https://scrapfly.io/docs/mcp/integrations/zed)
- [Roo Code](https://scrapfly.io/docs/mcp/integrations/roo-code)
- [VS Code](https://scrapfly.io/docs/mcp/integrations/vscode)
- [LangChain](https://scrapfly.io/docs/mcp/integrations/langchain)
- [LlamaIndex](https://scrapfly.io/docs/mcp/integrations/llamaindex)
- [CrewAI](https://scrapfly.io/docs/mcp/integrations/crewai)
- [OpenAI](https://scrapfly.io/docs/mcp/integrations/openai)
- [n8n](https://scrapfly.io/docs/mcp/integrations/n8n)
- [Make](https://scrapfly.io/docs/mcp/integrations/make)
- [Zapier](https://scrapfly.io/docs/mcp/integrations/zapier)
- [Vapi AI](https://scrapfly.io/docs/mcp/integrations/vapi)
- [Agent Builder](https://scrapfly.io/docs/mcp/integrations/agent-builder)
- [Custom Client](https://scrapfly.io/docs/mcp/integrations/custom-client)


#### Web Scraping API

- [Getting Started](https://scrapfly.io/docs/scrape-api/getting-started)
- [API Specification]()
- [Monitoring](https://scrapfly.io/docs/monitoring)
- [Customize Request](https://scrapfly.io/docs/scrape-api/custom)
- [Debug](https://scrapfly.io/docs/scrape-api/debug)
- [Unblocker (formerly ASP)](https://scrapfly.io/docs/scrape-api/unblocker)
- [Proxy](https://scrapfly.io/docs/scrape-api/proxy)
- [Proxy Mode](https://scrapfly.io/docs/scrape-api/proxy-mode)
- [Proxy Mode - Screaming Frog](https://scrapfly.io/docs/scrape-api/proxy-mode/screaming-frog)
- [Proxy Mode - Apify](https://scrapfly.io/docs/scrape-api/proxy-mode/apify)
- [(Auto) Data Extraction](https://scrapfly.io/docs/scrape-api/extraction)
- [Javascript Rendering](https://scrapfly.io/docs/scrape-api/javascript-rendering)
- [Javascript Scenario](https://scrapfly.io/docs/scrape-api/javascript-scenario)
- [SSL](https://scrapfly.io/docs/scrape-api/ssl)
- [DNS](https://scrapfly.io/docs/scrape-api/dns)
- [Cache](https://scrapfly.io/docs/scrape-api/cache)
- [Batch (Multi-URL Scraping)](https://scrapfly.io/docs/scrape-api/batch)
- [Session](https://scrapfly.io/docs/scrape-api/session)
- [Webhook](https://scrapfly.io/docs/scrape-api/webhook)
- [Schedule](https://scrapfly.io/docs/scrape-api/schedule)
- [Screenshot](https://scrapfly.io/docs/scrape-api/screenshot)
- [Errors](https://scrapfly.io/docs/scrape-api/errors)
- [Timeout](https://scrapfly.io/docs/scrape-api/understand-timeout)
- [Throttling](https://scrapfly.io/docs/throttling)
- [Troubleshoot](https://scrapfly.io/docs/scrape-api/troubleshoot)
- [Billing](https://scrapfly.io/docs/scrape-api/billing)
- [FAQ](https://scrapfly.io/docs/scrape-api/faq)

#### Crawler API

- [Getting Started](https://scrapfly.io/docs/crawler-api/getting-started)
- [API Specification]()
- [Retrieving Results](https://scrapfly.io/docs/crawler-api/results)
- [WARC Format](https://scrapfly.io/docs/crawler-api/warc-format)
- [Data Extraction](https://scrapfly.io/docs/crawler-api/extraction-rules)
- [Search](https://scrapfly.io/docs/crawler-api/search)
- [Prompt & Extract](https://scrapfly.io/docs/crawler-api/prompt)
- [Auto Refresh](https://scrapfly.io/docs/crawler-api/refresh)
- [Webhook](https://scrapfly.io/docs/crawler-api/webhook)
- [Schedule](https://scrapfly.io/docs/crawler-api/schedule)
- [Billing](https://scrapfly.io/docs/crawler-api/billing)
- [Errors](https://scrapfly.io/docs/crawler-api/errors)
- [Troubleshoot](https://scrapfly.io/docs/crawler-api/troubleshoot)
- [FAQ](https://scrapfly.io/docs/crawler-api/faq)

#### Screenshot API

- [Getting Started](https://scrapfly.io/docs/screenshot-api/getting-started)
- [API Specification]()
- [Accessibility Testing](https://scrapfly.io/docs/screenshot-api/accessibility)
- [Webhook](https://scrapfly.io/docs/screenshot-api/webhook)
- [Schedule](https://scrapfly.io/docs/screenshot-api/schedule)
- [Billing](https://scrapfly.io/docs/screenshot-api/billing)
- [Errors](https://scrapfly.io/docs/screenshot-api/errors)

#### Extraction API

- [Getting Started](https://scrapfly.io/docs/extraction-api/getting-started)
- [API Specification]()
- [Rules Template](https://scrapfly.io/docs/extraction-api/rules-and-template)
- [LLM Extraction](https://scrapfly.io/docs/extraction-api/llm-prompt)
- [AI Auto Extraction](https://scrapfly.io/docs/extraction-api/automatic-ai)
- [Webhook](https://scrapfly.io/docs/extraction-api/webhook)
- [Billing](https://scrapfly.io/docs/extraction-api/billing)
- [Errors](https://scrapfly.io/docs/extraction-api/errors)
- [FAQ](https://scrapfly.io/docs/extraction-api/faq)

#### Data API


#### Proxy Saver

- [Getting Started](https://scrapfly.io/docs/proxy-saver/getting-started)
- [Fingerprints](https://scrapfly.io/docs/proxy-saver/fingerprints)
- [Optimizations](https://scrapfly.io/docs/proxy-saver/optimizations)
- [SSL Certificates](https://scrapfly.io/docs/proxy-saver/certificates)
- [Protocols](https://scrapfly.io/docs/proxy-saver/protocols)
- [Pacfile](https://scrapfly.io/docs/proxy-saver/pacfile)
- [Secure Credentials](https://scrapfly.io/docs/proxy-saver/security)
- [Billing](https://scrapfly.io/docs/proxy-saver/billing)

#### Cloud Browser API

- [Getting Started](https://scrapfly.io/docs/cloud-browser-api/getting-started)
- [Proxy & Geo-Targeting](https://scrapfly.io/docs/cloud-browser-api/proxy)
- [Unblock API](https://scrapfly.io/docs/cloud-browser-api/unblock)
- [Captcha Solver](https://scrapfly.io/docs/cloud-browser-api/captcha-solver)
- [File Downloads](https://scrapfly.io/docs/cloud-browser-api/file-downloads)
- [Session Resume](https://scrapfly.io/docs/cloud-browser-api/session-resume)
- [Human-in-the-Loop](https://scrapfly.io/docs/cloud-browser-api/human-in-the-loop)
- [Debug Mode](https://scrapfly.io/docs/cloud-browser-api/debug-mode)
- [Browser Extensions](https://scrapfly.io/docs/cloud-browser-api/extensions)
- [Native Browser MCP](https://scrapfly.io/docs/cloud-browser-api/mcp)
- [DevTools Protocol](https://scrapfly.io/docs/cloud-browser-api/cdp-reference)
##### Integrations

- [Puppeteer](https://scrapfly.io/docs/cloud-browser-api/puppeteer)
- [Playwright](https://scrapfly.io/docs/cloud-browser-api/playwright)
- [Selenium](https://scrapfly.io/docs/cloud-browser-api/selenium)
- [Vercel Agent Browser](https://scrapfly.io/docs/cloud-browser-api/agent-browser)
- [Browser Use](https://scrapfly.io/docs/cloud-browser-api/browser-use)
- [Stagehand](https://scrapfly.io/docs/cloud-browser-api/stagehand)

- [Billing](https://scrapfly.io/docs/cloud-browser-api/billing)
- [Errors](https://scrapfly.io/docs/cloud-browser-api/errors)


### Tools

- [Antibot Detector](https://scrapfly.io/docs/tools/antibot-detector)

### SDK

- [Golang](https://scrapfly.io/docs/sdk/golang)
- [Python](https://scrapfly.io/docs/sdk/python)
- [Rust](https://scrapfly.io/docs/sdk/rust)
- [TypeScript](https://scrapfly.io/docs/sdk/typescript)
- [Scrapy](https://scrapfly.io/docs/sdk/scrapy)

### Integrations

- [Getting Started](https://scrapfly.io/docs/integration/getting-started)
- [LangChain](https://scrapfly.io/docs/integration/langchain)
- [LlamaIndex](https://scrapfly.io/docs/integration/llamaindex)
- [CrewAI](https://scrapfly.io/docs/integration/crewai)
- [Zapier](https://scrapfly.io/docs/integration/zapier)
- [Make](https://scrapfly.io/docs/integration/make)
- [n8n](https://scrapfly.io/docs/integration/n8n)

### Academy

- [Overview](https://scrapfly.io/academy)
- [Web Scraping Overview](https://scrapfly.io/academy/scraping-overview)
- [Tools](https://scrapfly.io/academy/tools-overview)
- [Reverse Engineering](https://scrapfly.io/academy/reverse-engineering)
- [Static Scraping](https://scrapfly.io/academy/static-scraping)
- [HTML Parsing](https://scrapfly.io/academy/html-parsing)
- [Dynamic Scraping](https://scrapfly.io/academy/dynamic-scraping)
- [Hidden API Scraping](https://scrapfly.io/academy/hidden-api-scraping)
- [Headless Browsers](https://scrapfly.io/academy/headless-browsers)
- [Hidden Web Data](https://scrapfly.io/academy/hidden-web-data)
- [JSON Parsing](https://scrapfly.io/academy/json-parsing)
- [Data Processing](https://scrapfly.io/academy/data-processing)
- [Scaling](https://scrapfly.io/academy/scaling)
- [Walkthrough Summary](https://scrapfly.io/academy/walkthrough-summary)
- [Scraper Blocking](https://scrapfly.io/academy/scraper-blocking)
- [Proxies](https://scrapfly.io/academy/proxies)

---

#  Anti-Spam Controls

 A single flapping metric can produce hundreds of notifications in an hour if the alerting system has no noise reduction. Scrapfly applies six independent, cumulative controls (sustained window, recovery window, re-notify interval, hard daily cap, snooze, auto-snooze on edit) to keep your inbox quiet and your on-call rotation from burning out.

 **All controls are server-enforced.** You cannot accidentally disable them by misconfiguring a client. The hard daily cap applies even if your `renotify_minutes` is set to 1.

## 1. Sustained window (`sustained_minutes`)

 An alert does not fire the moment a threshold is crossed. It enters a **PENDING** state and waits for the breach to persist continuously for the full `sustained_minutes` window before transitioning to **TRIGGERED** and firing the first notification.

 If the metric recovers before the sustained window elapses, the alert returns directly to **OK** without firing any notification. This is the primary filter against transient spikes.

###### Example

 Your block rate spikes to 40% for 3 minutes, then drops back to 8%. With `sustained_minutes = 5`, no notification fires. If the spike had lasted 5 minutes or more, you would have received one.

 **Recommendation:** Start with the registry default (5 minutes for most metrics). If you are still seeing false positives, increase to 10 or 15 minutes. If you need faster response, decrease to 1 or 2 minutes, but expect more noise.

## 2. Recovery window (`recovery_minutes`)

 After an alert is **TRIGGERED**, it enters a **RECOVERING** state once the metric is back within threshold. The alert does not return to **OK** (and fire the "resolved" notification) until the metric stays within threshold continuously for `recovery_minutes`.

 This prevents flapping: if a metric oscillates just around the threshold, the alert holds in RECOVERING rather than bouncing between TRIGGERED and OK and sending a notification on every flip.

 Default is 0 (instant recovery, same as V1.0 behavior). Set it to the same value as `sustained_minutes` for symmetric debouncing.

## 3. Re-notify interval (`renotify_minutes`)

 While an alert stays in **TRIGGERED**, Scrapfly can send periodic reminders. Set `renotify_minutes` to the minimum number of minutes between successive notifications for the same ongoing breach.

 Setting `renotify_minutes = 0` disables re-notifications entirely: the alert notifies once and stays quiet for as long as the breach lasts. That is the value the API applies when a create request omits the field. The dashboard create form starts from a different value: it pre-selects **Every hour** (60 minutes), so choose **Never (notify once only)** there if you want a single notification per breach.

 **Note:** The first notification fires when the alert transitions to TRIGGERED. Subsequent notifications fire every `renotify_minutes` *after the first one*, not from when the breach started.

## 4. Hard daily cap (6 notifications/day)

 Regardless of your `renotify_minutes` setting, a single alert cannot fire more than **6 notifications in one calendar day**. This is a hard server-side limit, not configurable.

 The counter resets at midnight UTC. You can see how many notifications have fired today in the stat strip on the alert detail page, which reads "3 notifications today (cap 6)".

 The intent is to provide a circuit-breaker: even if your metric is genuinely misbehaving and you have set an aggressive re-notify interval, your inbox receives at most 6 messages per alert per day.

## 5. Snooze

 You can manually snooze any alert from the dashboard. While snoozed:

- The evaluator continues running on its normal cadence.
- State transitions are still recorded in the audit log.
- No notifications are sent, regardless of the metric value.
- When the snooze expires, normal operation resumes. If the alert is still in TRIGGERED state when the snooze lifts, the next evaluation that sees a breach will re-notify.

Snooze buttons available in the dashboard:

- 30 minutes
- 2 hours
- Until resolved (the snooze clears automatically when the alert returns to OK)

 For any other duration, call the API directly: `POST /alert/{alert_uuid}/snooze` with body `{"minutes": 1440}` (1 day) or `{"until_resolved": true}`.

## 6. Auto-snooze on edit

 When you change an alert's **rule** (the comparator, `threshold`, `sustained_minutes`, `evaluation_window_m`, or the metric dimensions), Scrapfly automatically snoozes it for the full `sustained_minutes` window.

 Editing any other field does not snooze the alert: the name, description, `enabled` flag, notification channels, `renotify_minutes`, `eval_cadence_seconds` and `no_data_policy` all take effect immediately. In particular, re-enabling an alert you have just finished fixing does not mute it.

 An auto-snooze never shortens a snooze that is already running. If the alert is snoozed until resolved, or is under a manual snooze that outlasts `sustained_minutes`, that snooze is left in place.

 This prevents the common scenario where you tune a threshold and immediately receive a flood of notifications because the evaluator picks up the new rule mid-breach.

 The auto-snooze is visible on the alert detail page as a timed snooze entry in the event log. It lifts automatically once the snooze duration elapses.

## Controls at a glance

 | Control | Configurable? | Default | What it prevents |
|---|---|---|---|
| Sustained window | Yes (per alert) | 5 min | Notifications for transient spikes |
| Recovery window | Yes (per alert) | 0 min | Rapid OK/TRIGGERED flapping on threshold oscillation |
| Re-notify interval | Yes (per alert) | 0 (notify once) via the API, 60 min pre-selected in the dashboard form | Notification spam during a long-running breach |
| Hard daily cap | **No** (server-enforced) | 6/day | Any alert exceeding 6 notifications in a day |
| Snooze | Yes (manual, per alert) | Off | Notifications during planned maintenance or known incidents |
| Auto-snooze on edit | **No** (applied on rule changes only) | `sustained_minutes` | Post-tuning notification storm |

 [ Error Reference ](https://scrapfly.io/docs/alerting/error-reference) [ State Machine ](https://scrapfly.io/docs/alerting/state-machine)
