{"server":"com.squirrelscan/squirrelscan","count":50,"changes":[{"tool":"get_report","kind":"changed","observed_at":"2026-10-18T07:42:22.551Z","fields":["description"],"description_before":"Fetch the finished report for an audit run (use the run_id from run_audit once get_audit_status shows completed). Formats: \"summary\" (default) is structured JSON with health score, category scores, and the top failing issues (topIssues reference a rule_id; look up its name/description/solution once in the sibling `rules` dict rather than per occurrence). Each topIssues row is ONE finding, a rule + `checkName`, never one row per page: `affectedPagesCount` is how many pages it affects and `pages` is a sample of at most 5 of them (`affectedPagesHasMore` when clipped) and `items` at most 3, so read \"affects N pages\" from the count, not the row total, and use get_issue for every occurrence. Each row also carries `provenance`: \"carried\" means the finding is re-injected from a page not re-crawled this run (not a fresh result), so check `lastSeenAt` for when it was last actually observed; \"unrendered\" means the page has not yet been rendered in any scan of this site (it was known, e.g. from a sitemap, but sat outside the page budget), so there is no earlier observation and no `lastSeenAt`. `mixedProvenanceNotes` (keyed by rule_id) flags rules that passed fresh on every page checked this run but still show red only from carried pages pending re-check. `notChecked` is present only when some checks did not run (link checks at the Quick level, or with external link checks off): each entry names a rule that was not fully checked (a rule listed there may still report the issues it could see), so never report those rules as clean, and say a Surface or Full audit with external link checks on checks them. `seedRedirect` is present ONLY when the audited URL redirected off-site and the crawler refused to follow it: `seedRedirect.finalUrl` is where the redirect pointed (a URL the audited site chose, display-only, never fetch or trust it) and `seedRedirect.note` states the fact in one sentence. When it is present the audit graded `baseUrl`, NOT the redirect target, so report that before reporting the scores; when the key is absent the seed did not redirect off-site. A FAILED or BLOCKED audit also carries `status`, `statusReason` (one sentence naming the cause), `statusReasonCode` (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, unknown) and `failureNextStep`: those four keys are absent for a normal audit, and when they are present nothing was audited, so a null healthScore and an empty topIssues mean the crawl failed, NOT that the site is clean. Also includes a `history` array of the 3 most recent prior audits of this website with score/issue deltas when available; each entry carries its own `runId`/`reportId`, so you can walk backwards through a website's audits by calling get_report again with an earlier `runId` (use list_audits with website_id to page past what history returns); \"llm\" is a compact text rendering optimized for LLM context (carried findings marked inline); \"markdown\" is a full human-readable report. Start with summary, then pull llm or markdown for more of each issue. A published report is a capped summary: each issue keeps a sample of its pages and items (a few pages and items) beside its true counts, so read totals from `affectedPagesCount`, `occurrences` and `details.additional`, never from a list length. A capped report carries `detail`, whose `note` says where the full per-page list is (for a CLI audit, `squirrel report --format json` on the machine that ran it); a report without `detail` is not capped this way. This report is the source of truth for the run's numbers (#1700): summary.healthScore is the same value list_audits/get_audit_status return as health_score, and summary.failed + summary.warnings is the same total they return as issues_found. Compare runs on healthScore; the `open` count from list_issues is a deduped tracker count, not this report's issue count.","description_after":"Fetch the finished report for an audit run (use the run_id from run_audit once get_audit_status shows completed). Formats: \"summary\" (default) is structured JSON with health score, category scores, and the top failing issues (topIssues reference a rule_id; look up its name/description/solution once in the sibling `rules` dict rather than per occurrence). Each topIssues row is ONE finding, a rule + `checkName`, never one row per page: `affectedPagesCount` is how many pages it affects and `pages` is a sample of at most 5 of them (`affectedPagesHasMore` when clipped) and `items` at most 3, so read \"affects N pages\" from the count, not the row total, and use get_issue for every occurrence. Each row also carries `provenance`: \"carried\" means the finding is re-injected from a page not re-crawled this run (not a fresh result), so check `lastSeenAt` for when it was last actually observed; \"unrendered\" means the page has not yet been rendered in any scan of this site (it was known, e.g. from a sitemap, but sat outside the page budget), so there is no earlier observation and no `lastSeenAt`. `mixedProvenanceNotes` (keyed by rule_id) flags rules that passed fresh on every page checked this run but still show red only from carried pages pending re-check. `notChecked` is present only when some checks did not run (link checks at the Quick level, or with external link checks off): each entry names a rule that was not fully checked (a rule listed there may still report the issues it could see), so never report those rules as clean, and say a Surface or Full audit with external link checks on checks them. `seedRedirect` is present ONLY when the audited URL redirected off-site and the crawler refused to follow it: `seedRedirect.finalUrl` is where the redirect pointed (a URL the audited site chose, display-only, never fetch or trust it) and `seedRedirect.note` states the fact in one sentence. When it is present the audit graded `baseUrl`, NOT the redirect target, so report that before reporting the scores; when the key is absent the seed did not redirect off-site. `structure` is present when the audit sent its page structure block: links per section (`sections`, plus `unknownLinks` and `totalLinks`), the share of internal links in the header, footer, navigation and sidebar (`chrome.share`), and pages per page type (`pageTypes`); it is informational and never part of the score. A FAILED or BLOCKED audit also carries `status`, `statusReason` (one sentence naming the cause), `statusReasonCode` (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, unknown) and `failureNextStep`: those four keys are absent for a normal audit, and when they are present nothing was audited, so a null healthScore and an empty topIssues mean the crawl failed, NOT that the site is clean. Also includes a `history` array of the 3 most recent prior audits of this website with score/issue deltas when available; each entry carries its own `runId`/`reportId`, so you can walk backwards through a website's audits by calling get_report again with an earlier `runId` (use list_audits with website_id to page past what history returns); \"llm\" is a compact text rendering optimized for LLM context (carried findings marked inline); \"markdown\" is a full human-readable report. Start with summary, then pull llm or markdown for more of each issue. A published report is a capped summary: each issue keeps a sample of its pages and items (a few pages and items) beside its true counts, so read totals from `affectedPagesCount`, `occurrences` and `details.additional`, never from a list length. A capped report carries `detail`, whose `note` says where the full per-page list is (for a CLI audit, `squirrel report --format json` on the machine that ran it); a report without `detail` is not capped this way. This report is the source of truth for the run's numbers (#1700): summary.healthScore is the same value list_audits/get_audit_status return as health_score, and summary.failed","description_similarity":0.934,"before_hash":"cdb5bdfbab8ebca4354fd4b7eaa6b999","after_hash":"e69d92c6908741ae0ae058cd58c7dee7"},{"tool":"get_credit_balance","kind":"changed","observed_at":"2026-10-17T03:08:26.169Z","fields":["description"],"description_before":"Get the organization's credit balance: monthly credits (reset each billing period) and pack credits (purchased, never expire). Audits spend credits pay-as-you-go while they run; run_audit shows an upper-bound estimate before starting. An audit costs 50 credits plus 2 per audited page, however the page is fetched, plus 1 per distinct external link the cloud checks when external link checking is on. A balance under 52 (a one-page audit) cannot start one, and a balance that covers fewer pages than requested starts a smaller audit. Read-only.","description_after":"Get the organization's credit balance: monthly credits (reset each billing period) and pack credits (purchased, never expire). Audits spend credits pay-as-you-go while they run; run_audit shows an upper-bound estimate before starting. An audit costs 50 credits plus 2 per audited page, however the page is fetched, plus 1 per distinct external link the cloud verifies when external link checking is on (a link it cannot verify costs nothing). A balance under 52 (a one-page audit) cannot start one, and a balance that covers fewer pages than requested starts a smaller audit. Read-only.","description_similarity":0.932,"before_hash":"edc745445da04906497ac2f96776e0db","after_hash":"a1dc0db99d372eab6b7b8d235e8af0e6"},{"tool":"run_audit","kind":"changed","observed_at":"2026-10-17T03:08:26.169Z","fields":["description","inputSchema"],"description_before":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps with external link checks, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Every level checks external links, quick included, unless the website's external link setting or this run's external_links turns them off; each distinct external link checked costs 1 credit, at most one per page of the page budget, and the estimate includes it. Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off. pending_first_audit: true means they switch on by themselves after this site's first successful audit, estimated_cost is the most they spend per run, week and month, and update_website_settings with schedule \"off\" turns them off.","description_after":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps with external link checks, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Every level checks external links, quick included, unless the website's external link setting or this run's external_links turns them off; each distinct external link the cloud verifies costs 1 credit (a link it cannot verify costs nothing), at most one per page of the page budget, and the estimate includes it. Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off. pending_first_audit: true means they switch on by themselves after this site's first successful audit, estimated_cost is the most they spend per run, week and month, and update_website_settings with schedule \"off\" turns them off.","description_similarity":0.978,"before_hash":"26374eac0d4e10595dd43ae501eae6b8","after_hash":"7901a7448ea7a2b96535187b70b742fa"},{"tool":"list_audits","kind":"changed","observed_at":"2026-10-16T03:36:44.914Z","fields":["description"],"description_before":"List the organization's audit runs: currently active (pending/running) plus recent runs of any status. Pass website_id (from list_websites) to get one website's full audit history, oldest runs included, and page through it with limit/offset using the returned total/has_more. This is the way to reach the preserved reports of a soft-deleted website: its runs still list under its old website_id. total/has_more describe the `recent` array only, and `recent` already includes any pending/running run, so `active` is a live view of those same runs and not extra items to add to the count. Use the run ids with get_audit_status or get_report, and website ids with list_issues. Numbers on a recent run come from its published report (#1700): health_score is that report's overall score (the same value as get_report's summary.healthScore; null when the site was blocked or down, which earns no grade) and issues_found is the report's failing + warning checks (its summary.failed + summary.warnings). health_score is the metric to compare run over run: it is the only one rescored consistently across the whole site. Do NOT compare issues_found with the `open` count from list_issues: the issue tracker folds a rule failing on many pages into one open issue and carries issues forward until they are re-checked, so its count is legitimately much smaller and moves independently.","description_after":"List the organization's audit runs: currently active (queued/pending/running; queued means waiting for a free cloud slot, and it starts by itself) plus recent runs of any status. Pass website_id (from list_websites) to get one website's full audit history, oldest runs included, and page through it with limit/offset using the returned total/has_more. This is the way to reach the preserved reports of a soft-deleted website: its runs still list under its old website_id. total/has_more describe the `recent` array only, and `recent` already includes any queued/pending/running run, so `active` is a live view of those same runs and not extra items to add to the count. Use the run ids with get_audit_status or get_report, and website ids with list_issues. Numbers on a recent run come from its published report (#1700): health_score is that report's overall score (the same value as get_report's summary.healthScore; null when the site was blocked or down, which earns no grade) and issues_found is the report's failing + warning checks (its summary.failed + summary.warnings). health_score is the metric to compare run over run: it is the only one rescored consistently across the whole site. Do NOT compare issues_found with the `open` count from list_issues: the issue tracker folds a rule failing on many pages into one open issue and carries issues forward until they are re-checked, so its count is legitimately much smaller and moves independently.","description_similarity":0.929,"before_hash":"fcf7c4052f66b9ac9efa8004fce22807","after_hash":"b71c70eb3f89cd7d5065cc00e469f0ef"},{"tool":"get_audit_status","kind":"changed","observed_at":"2026-10-16T03:36:44.914Z","fields":["description"],"description_before":"Poll a running audit by run_id (from run_audit or list_audits). Status pending/running means keep polling (every 15-30 seconds): the response includes a progress field (phase, message, page/link counts) when available. Status completed means the report is ready: call get_report with the same run_id. Status failed/cancelled includes the error and completion reason. A failed run also carries failure_reason_code (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, audit_timeout, stalled, unknown) and failure_next_step, so you can act on the cause rather than parsing the error sentence, plus failure_diagnostics: attribution (target_site, squirrelscan, mixed or unknown; never guess past it), category, stage, the observations that support it, what remains uncertain, and the bounded list of fetch attempts; legacy is true when the run predates recorded evidence. A cancelled run has none of these, because it was stopped rather than defeated by the site. Once the run has a report, health_score and issues_found are read from that published report, so they equal get_report's summary.healthScore and its failed+warnings (#1700). health_score is null for a blocked or unreachable site: that audit has no meaningful grade. A completed run also carries a schedule field describing the website's recurring audits: state is off, active, capped, unschedulable or paused, cadence_label reads as a sentence, settings_url is where the user changes the cadence or turns it off, and cap says how many scheduled sites the plan funds and how many are spent. estimated_cost is the most those runs spend per run, week and month. Recurring audits turn on by themselves after a site's first successful audit and each run costs credits, so pass that on rather than leaving the user to discover the charge.","description_after":"Poll a running audit by run_id (from run_audit or list_audits). Status queued/pending/running means keep polling (every 15-30 seconds): the response includes a progress field (phase, message, page/link counts) when available. Status queued means cloud audits are busy and the run is waiting for a slot: it starts by itself, and its queue field gives its position, a rough eta_minutes (null when unknown) and a message to pass on. Do not start the audit again. Status completed means the report is ready: call get_report with the same run_id. Status failed/cancelled includes the error and completion reason. A failed run also carries failure_reason_code (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, audit_timeout, stalled, unknown) and failure_next_step, so you can act on the cause rather than parsing the error sentence, plus failure_diagnostics: attribution (target_site, squirrelscan, mixed or unknown; never guess past it), category, stage, the observations that support it, what remains uncertain, and the bounded list of fetch attempts; legacy is true when the run predates recorded evidence. A cancelled run has none of these, because it was stopped rather than defeated by the site. Once the run has a report, health_score and issues_found are read from that published report, so they equal get_report's summary.healthScore and its failed+warnings (#1700). health_score is null for a blocked or unreachable site: that audit has no meaningful grade. A completed run also carries a schedule field describing the website's recurring audits: state is off, active, capped, unschedulable or paused, cadence_label reads as a sentence, settings_url is where the user changes the cadence or turns it off, and cap says how many scheduled sites the plan funds and how many are spent. estimated_cost is the most those runs spend per run, week and month. Recurring audits turn on by themselves after a site's first successful audit and each run costs credits, so pass that on rather than leaving the user to discover the charge.","description_similarity":0.915,"before_hash":"e36bd5c952426625c51d7dcd11fad1c4","after_hash":"6f945f80991a404cfe782d6ddc4f5711"},{"tool":"run_audit","kind":"changed","observed_at":"2026-10-16T03:36:44.914Z","fields":["description"],"description_before":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Surface and full check external links, quick does not, unless the website's external link setting or this run's external_links says otherwise; each distinct external link checked costs 1 credit, at most one per page of the page budget, and the estimate includes it. Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off. pending_first_audit: true means they switch on by themselves after this site's first successful audit, estimated_cost is the most they spend per run, week and month, and update_website_settings with schedule \"off\" turns them off.","description_after":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps with external link checks, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Every level checks external links, quick included, unless the website's external link setting or this run's external_links turns them off; each distinct external link checked costs 1 credit, at most one per page of the page budget, and the estimate includes it. Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off. pending_first_audit: true means they switch on by themselves after this site's first successful audit, estimated_cost is the most they spend per run, week and month, and update_website_settings with schedule \"off\" turns them off.","description_similarity":0.978,"before_hash":"51398023b063740dade619a6b5a99e0d","after_hash":"26374eac0d4e10595dd43ae501eae6b8"},{"tool":"list_notifications","kind":"changed","observed_at":"2026-10-15T16:06:55.058Z","fields":["description"],"description_before":"Read the organization's notification feed, newest first: what finished, what broke, and what changed since you last looked. Categories include audit_complete, issues_detected, audit_failed, schedule_paused. Use this to catch up at the start of a session (\"did last night's scheduled audit run?\", \"what failed?\") instead of polling every website. Each entry carries the category, the human-readable title and body, a data payload with the ids involved (website_id, run_id, report_id), and whether a human has read it in the dashboard. Filter with category, or unread_only to see just what nobody has looked at yet. Paginated with limit/offset, or poll for new events: every response carries next_cursor, and passing it back as after returns only notifications created since, oldest first (offset is ignored). Read-only: this never marks anything read.","description_after":"Read the organization's notification feed, newest first: what finished, what broke, and what changed since you last looked. Categories include audit_complete, issues_detected, audit_failed, broken_links, schedule_paused. Use this to catch up at the start of a session (\"did last night's scheduled audit run?\", \"what failed?\") instead of polling every website. Each entry carries the category, the human-readable title and body, a data payload with the ids involved (website_id, run_id, report_id), and whether a human has read it in the dashboard. Filter with category, or unread_only to see just what nobody has looked at yet. Paginated with limit/offset, or poll for new events: every response carries next_cursor, and passing it back as after returns only notifications created since, oldest first (offset is ignored). Read-only: this never marks anything read.","description_similarity":0.979,"before_hash":"c613a6d2f8caf31dd628a040c073344b","after_hash":"67ee5eac16e8e33760ae4ec2e52d738c"},{"tool":"update_website_settings","kind":"changed","observed_at":"2026-10-15T16:06:55.058Z","fields":["description","inputSchema"],"description_before":"Change one website's stored audit settings: level, max_pages, render, external_links, max_depth, scope, include_patterns, exclude_patterns and internal_links, and schedule (off, daily, weekly or monthly) for its recurring audits. Omitted fields are left unchanged. Values are checked the same way the dashboard's settings are and held to the organization's plan; the result reports what is stored afterwards, which fields were applied, and any plan clamp. Turning recurring audits on, changing their cadence, or a change that raises the most one audit can cost returns status \"confirmation_required\" with the estimated credit cost and changes nothing until it is sent again with the same arguments plus confirm: true. schedule: \"off\" and changes that cost nothing more apply at once.","description_after":"Change one website's stored audit settings: level, max_pages, render, external_links, max_depth, scope, include_patterns, exclude_patterns and internal_links, broken_link_alerts (Pro and Team; switching it off is allowed on every plan), and schedule (off, daily, weekly or monthly) for its recurring audits. Omitted fields are left unchanged. Values are checked the same way the dashboard's settings are and held to the organization's plan; the result reports what is stored afterwards, which fields were applied, and any plan clamp. Turning recurring audits on, changing their cadence, or a change that raises the most one audit can cost returns status \"confirmation_required\" with the estimated credit cost and changes nothing until it is sent again with the same arguments plus confirm: true. schedule: \"off\" and changes that cost nothing more apply at once.","description_similarity":0.916,"before_hash":"32faf515b506e8e12b75ce81e86ef0f0","after_hash":"a0e0449550ca2948debd8f456ff1f22d"},{"tool":"get_website_settings","kind":"changed","observed_at":"2026-10-15T16:06:55.058Z","fields":["description"],"description_before":"Read one website's stored audit settings: its audit level (quick, surface, full or custom) with the page cap, crawl strategy, rendering and external link checks it sets, the crawl depth, crawl scope, include/exclude patterns and internal link checks, and its recurring-audit schedule. runs_as is how the next audit runs on the organization's plan (a level or page cap the plan does not run is held to the plan there, with a notice) and credits_per_run_max is the most one audit of it can cost. schedule says whether recurring audits are on; pending_first_audit: true means they switch on by themselves after the site's first successful audit, and estimated_cost is the most they spend per run, week and month.","description_after":"Read one website's stored audit settings: its audit level (quick, surface, full or custom) with the page cap, crawl strategy, rendering and external link checks it sets, the crawl depth, crawl scope, include/exclude patterns and internal link checks, whether broken link alerts are on (broken_link_alerts, Pro and Team), and its recurring-audit schedule. runs_as is how the next audit runs on the organization's plan (a level or page cap the plan does not run is held to the plan there, with a notice) and credits_per_run_max is the most one audit of it can cost. schedule says whether recurring audits are on; pending_first_audit: true means they switch on by themselves after the site's first successful audit, and estimated_cost is the most they spend per run, week and month.","description_similarity":0.951,"before_hash":"826180405ead6342855cbae7973aac62","after_hash":"96f18544aad7a68d776b952e4ca5653b"},{"tool":"update_website_settings","kind":"changed","observed_at":"2026-10-13T04:01:52.814Z","fields":["description","inputSchema"],"description_before":"Change one website's stored audit settings: level, max_pages, render, external_links, max_depth, scope, include_patterns and exclude_patterns, and schedule (off, daily, weekly or monthly) for its recurring audits. Omitted fields are left unchanged. Values are checked the same way the dashboard's settings are and held to the organization's plan; the result reports what is stored afterwards, which fields were applied, and any plan clamp. Turning recurring audits on, changing their cadence, or a change that raises the most one audit can cost returns status \"confirmation_required\" with the estimated credit cost and changes nothing until it is sent again with the same arguments plus confirm: true. schedule: \"off\" and changes that cost nothing more apply at once.","description_after":"Change one website's stored audit settings: level, max_pages, render, external_links, max_depth, scope, include_patterns, exclude_patterns and internal_links, and schedule (off, daily, weekly or monthly) for its recurring audits. Omitted fields are left unchanged. Values are checked the same way the dashboard's settings are and held to the organization's plan; the result reports what is stored afterwards, which fields were applied, and any plan clamp. Turning recurring audits on, changing their cadence, or a change that raises the most one audit can cost returns status \"confirmation_required\" with the estimated credit cost and changes nothing until it is sent again with the same arguments plus confirm: true. schedule: \"off\" and changes that cost nothing more apply at once.","description_similarity":0.989,"before_hash":"f297aad6ef4853c734eed66a1950c77d","after_hash":"32faf515b506e8e12b75ce81e86ef0f0"},{"tool":"get_website_settings","kind":"changed","observed_at":"2026-10-13T04:01:52.814Z","fields":["description"],"description_before":"Read one website's stored audit settings: its audit level (quick, surface, full or custom) with the page cap, crawl strategy, rendering and external link checks it sets, the crawl depth, crawl scope and include/exclude patterns, and its recurring-audit schedule. runs_as is how the next audit runs on the organization's plan (a level or page cap the plan does not run is held to the plan there, with a notice) and credits_per_run_max is the most one audit of it can cost. schedule says whether recurring audits are on; pending_first_audit: true means they switch on by themselves after the site's first successful audit, and estimated_cost is the most they spend per run, week and month.","description_after":"Read one website's stored audit settings: its audit level (quick, surface, full or custom) with the page cap, crawl strategy, rendering and external link checks it sets, the crawl depth, crawl scope, include/exclude patterns and internal link checks, and its recurring-audit schedule. runs_as is how the next audit runs on the organization's plan (a level or page cap the plan does not run is held to the plan there, with a notice) and credits_per_run_max is the most one audit of it can cost. schedule says whether recurring audits are on; pending_first_audit: true means they switch on by themselves after the site's first successful audit, and estimated_cost is the most they spend per run, week and month.","description_similarity":0.987,"before_hash":"a02b9a167454824153039c7cb992e21a","after_hash":"826180405ead6342855cbae7973aac62"},{"tool":"run_audit","kind":"changed","observed_at":"2026-10-13T04:01:52.814Z","fields":["description","inputSchema"],"description_before":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off. pending_first_audit: true means they switch on by themselves after this site's first successful audit, estimated_cost is the most they spend per run, week and month, and update_website_settings with schedule \"off\" turns them off.","description_after":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Surface and full check external links, quick does not, unless the website's external link setting or this run's external_links says otherwise; each distinct external link checked costs 1 credit, at most one per page of the page budget, and the estimate includes it. Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off. pending_first_audit: true means they switch on by themselves after this site's first successful audit, estimated_cost is the most they spend per run, week and month, and update_website_settings with schedule \"off\" turns them off.","description_similarity":0.945,"before_hash":"852ec7b6219a3c5d97bd46fe9bb73121","after_hash":"51398023b063740dade619a6b5a99e0d"},{"tool":"list_notifications","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"7a09d23d5412f2934bde52bba144105c","after_hash":"c613a6d2f8caf31dd628a040c073344b"},{"tool":"send_feedback","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"08b1de37dc9234851c5db870a8461bcc","after_hash":"14faa3c8146afe3271c6c02a0f35b9c5"},{"tool":"create_api_key","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"20f1dfae726e1687afac8e56cbda6553","after_hash":"b2f0325942c8b9436114a0a8e756e075"},{"tool":"list_credit_transactions","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"6be1f1695acb170872dc755221fc54cb","after_hash":"9822c513e534ae68297d62b0e84947d5"},{"tool":"get_credit_balance","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"817539c9c228c1ad4334c00361a1724f","after_hash":"edc745445da04906497ac2f96776e0db"},{"tool":"whoami","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"3c95ecf90c2acb7a1352d402c21d509f","after_hash":"282e7e04a9684050c3c669daacc021ca"},{"tool":"get_rule","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"3df5bfb2f86027ae240239b518ef330f","after_hash":"a5f91365f0d1ba2793d1ad6136eb8a27"},{"tool":"list_rules","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"b16c7debd4081f4a0c43f34a070ae7f7","after_hash":"529f775cffdd7066998d7082bbefba1c"},{"tool":"get_entity_findings","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"14133f404cd1e0f63ae8e792dfa478e1","after_hash":"070e490fd1705abe8babab7dbe71435b"},{"tool":"compare_entities","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"08ac1a91a9127efe623c32d8480307ec","after_hash":"8dc3cc49d466946d15c9b3d3357d9151"},{"tool":"get_entity_graph","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"e00d1ce03c947057c30d31166a79ec9f","after_hash":"a7d6338a3e6d9966e3ee8d8502f078ea"},{"tool":"get_entity","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"74856daeadcf26f0a619cdd1916bb182","after_hash":"977595499155c4653e678d4659636ddd"},{"tool":"list_entities","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"51f619206d22826f45fe1b48e69e4ee3","after_hash":"e3a678cec046ce49046a94991f935aa0"},{"tool":"comment_on_issue","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"5b027fa6f32b79ab1c2448dac6cf3f84","after_hash":"91957e1d91f1d83f69ede4f81059c8cb"},{"tool":"get_issue","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"9700045628f12ddd81e4a174101f42b7","after_hash":"d4a1a1a997be0a9c9fe168d31433cf43"},{"tool":"list_issues","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["description","inputSchema"],"description_before":"List a website's open audit issues (like a bug tracker: each issue is one failing rule with occurrences across pages, numbered per website). Returns issues sorted by severity, plus severity and status summaries. Use the issue number with get_issue for full detail and comments. Filter by status/severity/category to narrow down. This is a per-website tracker spanning audits, not a per-run count: one rule failing on 600 pages is ONE issue here, and an issue stays open until an audit re-checks it. So the open count is expected to be far smaller than a run's issues_found (list_audits) or a report's failed+warnings, and the two are not comparable (#1700). To compare runs, use health_score from list_audits.","description_after":"List a website's open audit issues (like a bug tracker: each issue is one failing rule with occurrences across pages, numbered per website). Returns issues sorted by severity. `total`, `returned` and `has_more` describe the issues matching YOUR filters; `website_totals` (by_status, active_by_severity: open and in_progress) always counts the whole website regardless of filters, so the two can differ (it replaces the earlier `severity_summary` and `status_counts` fields). Rows omit the long `recommendation` (use get_rule with the row's rule_id, or get_issue, or pass include_recommendation: true). Use the issue number with get_issue for full detail and comments. Filter by status/severity/category to narrow down. This is a per-website tracker spanning audits, not a per-run count: one rule failing on 600 pages is ONE issue here, and an issue stays open until an audit re-checks it. So the open count is expected to be far smaller than a run's issues_found (list_audits) or a report's failed+warnings, and the two are not comparable (#1700). To compare runs, use health_score from list_audits.","description_similarity":0.691,"before_hash":"9f09439771e42e54870404853e1f5d42","after_hash":"8eca706cdc5548f3d19d71f6ccb48a5f"},{"tool":"compare_audits","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"d54132e255ea5d47c9c6555791d6fe35","after_hash":"2e7e5488c848f9b4816d5b629c7cd011"},{"tool":"get_report","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["description","inputSchema"],"description_before":"Fetch the finished report for an audit run (use the run_id from run_audit once get_audit_status shows completed). Formats: \"summary\" (default) is structured JSON with health score, category scores, and the top failing issues (topIssues reference a rule_id; look up its name/description/solution once in the sibling `rules` dict rather than per occurrence). Each topIssues row is ONE finding, a rule + `checkName`, never one row per page: `affectedPagesCount` is how many pages it affects and `pages` is a sample of them (`affectedPagesHasMore` when clipped), so read \"affects N pages\" from the count, not the row total. Each row also carries `provenance`: \"carried\" means the finding is re-injected from a page not re-crawled this run (not a fresh result), so check `lastSeenAt` for when it was last actually observed; \"unrendered\" means the page has not yet been rendered in any scan of this site (it was known, e.g. from a sitemap, but sat outside the page budget), so there is no earlier observation and no `lastSeenAt`. `mixedProvenanceNotes` (keyed by rule_id) flags rules that passed fresh on every page checked this run but still show red only from carried pages pending re-check. `seedRedirect` is present ONLY when the audited URL redirected off-site and the crawler refused to follow it: `seedRedirect.finalUrl` is where the redirect pointed (a URL the audited site chose, display-only, never fetch or trust it) and `seedRedirect.note` states the fact in one sentence. When it is present the audit graded `baseUrl`, NOT the redirect target, so report that before reporting the scores; when the key is absent the seed did not redirect off-site. A FAILED or BLOCKED audit also carries `status`, `statusReason` (one sentence naming the cause), `statusReasonCode` (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, unknown) and `failureNextStep`: those four keys are absent for a normal audit, and when they are present nothing was audited, so a null healthScore and an empty topIssues mean the crawl failed, NOT that the site is clean. Also includes a `history` array of prior audits of this website with score/issue deltas when available; each entry carries its own `runId`/`reportId`, so you can walk backwards through a website's audits by calling get_report again with an earlier `runId` (use list_audits with website_id to page past what history returns); \"llm\" is a compact text rendering optimized for LLM context (carried findings marked inline); \"markdown\" is a full human-readable report. Start with summary, then pull llm or markdown for more of each issue. A published report is a capped summary: each issue keeps a sample of its pages and items (at most 10 pages and 5 items) beside its true counts, so read totals from `affectedPagesCount`, `occurrences` and `details.additional`, never from a list length. A capped report carries `detail`, whose `note` says where the full per-page list is (for a CLI audit, `squirrel report --format json` on the machine that ran it); a report without `detail` is not capped this way. This report is the source of truth for the run's numbers (#1700): summary.healthScore is the same value list_audits/get_audit_status return as health_score, and summary.failed + summary.warnings is the same total they return as issues_found. Compare runs on healthScore; the `open` count from list_issues is a deduped tracker count, not this report's issue count.","description_after":"Fetch the finished report for an audit run (use the run_id from run_audit once get_audit_status shows completed). Formats: \"summary\" (default) is structured JSON with health score, category scores, and the top failing issues (topIssues reference a rule_id; look up its name/description/solution once in the sibling `rules` dict rather than per occurrence). Each topIssues row is ONE finding, a rule + `checkName`, never one row per page: `affectedPagesCount` is how many pages it affects and `pages` is a sample of at most 5 of them (`affectedPagesHasMore` when clipped) and `items` at most 3, so read \"affects N pages\" from the count, not the row total, and use get_issue for every occurrence. Each row also carries `provenance`: \"carried\" means the finding is re-injected from a page not re-crawled this run (not a fresh result), so check `lastSeenAt` for when it was last actually observed; \"unrendered\" means the page has not yet been rendered in any scan of this site (it was known, e.g. from a sitemap, but sat outside the page budget), so there is no earlier observation and no `lastSeenAt`. `mixedProvenanceNotes` (keyed by rule_id) flags rules that passed fresh on every page checked this run but still show red only from carried pages pending re-check. `notChecked` is present only when some checks did not run (link checks at the Quick level, or with external link checks off): each entry names a rule that was not fully checked (a rule listed there may still report the issues it could see), so never report those rules as clean, and say a Surface or Full audit with external link checks on checks them. `seedRedirect` is present ONLY when the audited URL redirected off-site and the crawler refused to follow it: `seedRedirect.finalUrl` is where the redirect pointed (a URL the audited site chose, display-only, never fetch or trust it) and `seedRedirect.note` states the fact in one sentence. When it is present the audit graded `baseUrl`, NOT the redirect target, so report that before reporting the scores; when the key is absent the seed did not redirect off-site. A FAILED or BLOCKED audit also carries `status`, `statusReason` (one sentence naming the cause), `statusReasonCode` (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, unknown) and `failureNextStep`: those four keys are absent for a normal audit, and when they are present nothing was audited, so a null healthScore and an empty topIssues mean the crawl failed, NOT that the site is clean. Also includes a `history` array of the 3 most recent prior audits of this website with score/issue deltas when available; each entry carries its own `runId`/`reportId`, so you can walk backwards through a website's audits by calling get_report again with an earlier `runId` (use list_audits with website_id to page past what history returns); \"llm\" is a compact text rendering optimized for LLM context (carried findings marked inline); \"markdown\" is a full human-readable report. Start with summary, then pull llm or markdown for more of each issue. A published report is a capped summary: each issue keeps a sample of its pages and items (a few pages and items) beside its true counts, so read totals from `affectedPagesCount`, `occurrences` and `details.additional`, never from a list length. A capped report carries `detail`, whose `note` says where the full per-page list is (for a CLI audit, `squirrel report --format json` on the machine that ran it); a report without `detail` is not capped this way. This report is the source of truth for the run's numbers (#1700): summary.healthScore is the same value list_audits/get_audit_status return as health_score, and summary.failed + summary.warnings is the same total they return as issues_found. Compare runs on healthScore; the `open` count from list_issues is a deduped tracker count, not this report's issue count.","description_similarity":0.934,"before_hash":"89200d6610257707dc19d838ac00bce3","after_hash":"cdb5bdfbab8ebca4354fd4b7eaa6b999"},{"tool":"update_website_settings","kind":"added","observed_at":"2026-10-12T15:04:36.518Z","fields":[],"description_before":null,"description_after":"Change one website's stored audit settings: level, max_pages, render, external_links, max_depth, scope, include_patterns and exclude_patterns, and schedule (off, daily, weekly or monthly) for its recurring audits. Omitted fields are left unchanged. Values are checked the same way the dashboard's settings are and held to the organization's plan; the result reports what is stored afterwards, which fields were applied, and any plan clamp. Turning recurring audits on, changing their cadence, or a change that raises the most one audit can cost returns status \"confirmation_required\" with the estimated credit cost and changes nothing until it is sent again with the same arguments plus confirm: true. schedule: \"off\" and changes that cost nothing more apply at once.","description_similarity":null,"before_hash":null,"after_hash":"f297aad6ef4853c734eed66a1950c77d"},{"tool":"get_website_settings","kind":"added","observed_at":"2026-10-12T15:04:36.518Z","fields":[],"description_before":null,"description_after":"Read one website's stored audit settings: its audit level (quick, surface, full or custom) with the page cap, crawl strategy, rendering and external link checks it sets, the crawl depth, crawl scope and include/exclude patterns, and its recurring-audit schedule. runs_as is how the next audit runs on the organization's plan (a level or page cap the plan does not run is held to the plan there, with a notice) and credits_per_run_max is the most one audit of it can cost. schedule says whether recurring audits are on; pending_first_audit: true means they switch on by themselves after the site's first successful audit, and estimated_cost is the most they spend per run, week and month.","description_similarity":null,"before_hash":null,"after_hash":"a02b9a167454824153039c7cb992e21a"},{"tool":"delete_websites","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"e285085775841cc8bbf19f29c96aaa7a","after_hash":"b4107c2afa25a02a2f70e7b380378227"},{"tool":"delete_website","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"cce78b81a83c930c279705f5e70dac31","after_hash":"13bf763491a3e7ca064d37cb878bb3fa"},{"tool":"add_website","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["description","inputSchema"],"description_before":"Register a website with the organization without running an audit (run_audit registers automatically, so this is only needed to set a site up ahead of time). Returns the website_id; idempotent per domain, so calling it again returns the existing website. Pass kind to classify it as owned or prospect up front. On a plan with scheduled audits, a NEW site is registered with recurring weekly audits already on, and each of those runs costs credits: tell the user before calling this, and point them at the site's schedule settings to turn it off. The result's scheduled_audits field reports what was actually set.","description_after":"Register a website with the organization without running an audit (run_audit registers automatically, so this is only needed to set a site up ahead of time). Returns the website_id; idempotent per domain, so calling it again returns the existing website. Pass kind to classify it as owned or prospect up front. On a plan with scheduled audits, a NEW site is registered with recurring weekly audits already on, and each of those runs costs credits: tell the user before calling this; update_website_settings with schedule \"off\" turns them off. The result's scheduled_audits field reports what was actually set.","description_similarity":0.934,"before_hash":"9a9dc237be672e9ca5f67ddd9c847296","after_hash":"a0cc026b9c8557b7543549be15aea44e"},{"tool":"list_websites","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"deddf6ad62ae2f16494b2a71dd278c48","after_hash":"85f5003342f5b313e8d35597e5f6c955"},{"tool":"list_audits","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["inputSchema"],"description_before":null,"description_after":null,"description_similarity":null,"before_hash":"79ce93d220f62cf44c95f071f76f4f19","after_hash":"fcf7c4052f66b9ac9efa8004fce22807"},{"tool":"get_audit_status","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["description","inputSchema"],"description_before":"Poll a running audit by run_id (from run_audit or list_audits). Status pending/running means keep polling (every 15-30 seconds): the response includes a progress field (phase, message, page/link counts) when available. Status completed means the report is ready: call get_report with the same run_id. Status failed/cancelled includes the error and completion reason. A failed run also carries failure_reason_code (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, audit_timeout, stalled, unknown) and failure_next_step, so you can act on the cause rather than parsing the error sentence, plus failure_diagnostics: attribution (target_site, squirrelscan, mixed or unknown; never guess past it), category, stage, the observations that support it, what remains uncertain, and the bounded list of fetch attempts; legacy is true when the run predates recorded evidence. A cancelled run has none of these, because it was stopped rather than defeated by the site. Once the run has a report, health_score and issues_found are read from that published report, so they equal get_report's summary.healthScore and its failed+warnings (#1700). health_score is null for a blocked or unreachable site: that audit has no meaningful grade. A completed run also carries a schedule field describing the website's recurring audits: state is off, active, capped, unschedulable or paused, cadence_label reads as a sentence, settings_url is where the user changes the cadence or turns it off, and cap says how many scheduled sites the plan funds and how many are spent. Recurring audits turn on by themselves after a site's first successful audit and each run costs credits, so pass that on rather than leaving the user to discover the charge.","description_after":"Poll a running audit by run_id (from run_audit or list_audits). Status pending/running means keep polling (every 15-30 seconds): the response includes a progress field (phase, message, page/link counts) when available. Status completed means the report is ready: call get_report with the same run_id. Status failed/cancelled includes the error and completion reason. A failed run also carries failure_reason_code (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, audit_timeout, stalled, unknown) and failure_next_step, so you can act on the cause rather than parsing the error sentence, plus failure_diagnostics: attribution (target_site, squirrelscan, mixed or unknown; never guess past it), category, stage, the observations that support it, what remains uncertain, and the bounded list of fetch attempts; legacy is true when the run predates recorded evidence. A cancelled run has none of these, because it was stopped rather than defeated by the site. Once the run has a report, health_score and issues_found are read from that published report, so they equal get_report's summary.healthScore and its failed+warnings (#1700). health_score is null for a blocked or unreachable site: that audit has no meaningful grade. A completed run also carries a schedule field describing the website's recurring audits: state is off, active, capped, unschedulable or paused, cadence_label reads as a sentence, settings_url is where the user changes the cadence or turns it off, and cap says how many scheduled sites the plan funds and how many are spent. estimated_cost is the most those runs spend per run, week and month. Recurring audits turn on by themselves after a site's first successful audit and each run costs credits, so pass that on rather than leaving the user to discover the charge.","description_similarity":0.951,"before_hash":"8b3142139caa3ae6bf52e94675dbd392","after_hash":"e36bd5c952426625c51d7dcd11fad1c4"},{"tool":"run_audit","kind":"changed","observed_at":"2026-10-12T15:04:36.518Z","fields":["description","inputSchema"],"description_before":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off.","description_after":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off. pending_first_audit: true means they switch on by themselves after this site's first successful audit, estimated_cost is the most they spend per run, week and month, and update_website_settings with schedule \"off\" turns them off.","description_similarity":0.918,"before_hash":"71a2f789a576a32183b90369a45b7ded","after_hash":"852ec7b6219a3c5d97bd46fe9bb73121"},{"tool":"get_issue","kind":"changed","observed_at":"2026-10-11T22:03:09.107Z","fields":["description"],"description_before":"Fetch one issue by website_id + issue number, including its full description, recommendation, affected pages, occurrence detail from the latest report (which page/image/URL, snippets), and comment thread. Use comment_on_issue to add analysis or a fix note to the thread.","description_after":"Fetch one issue by website_id + issue number, including its full description, recommendation, affected pages, occurrence detail from the latest report (which page/image/URL, snippets), and comment thread. `occurrence_count` is the true total; the listed occurrences are a sample when `occurrences_truncated` is true, and on a capped report `full_detail` says where every occurrence is. Use comment_on_issue to add analysis or a fix note to the thread.","description_similarity":0.725,"before_hash":"1bdd6bbf8d126565cb4f943b1a17e4dd","after_hash":"9700045628f12ddd81e4a174101f42b7"},{"tool":"compare_audits","kind":"changed","observed_at":"2026-10-11T22:03:09.107Z","fields":["description"],"description_before":"Compare two completed audits of one website and get what changed. Defaults to the website's latest completed audit against the one before it; pass base/head run ids to compare any two. Each finding gets one of seven kinds: new, resolved, worsened, improved, unchanged (both audits published it), still_open (the evidence store says it is still there but the newer audit did not republish it), or not_crawled (the page was not visited, so the issue is neither fixed nor still broken). resolutionEvidence says what backed the resolved verdicts; when it is \"none\" nothing is reported as fixed. Score movement is broken down by category. A website with only one audit returns first_run with an empty finding list; an audit where nothing moved returns changed: false. Unchanged, still-open and not-crawled rows are omitted unless requested.","description_after":"Compare two completed audits of one website and get what changed. Defaults to the website's latest completed audit against the one before it; pass base/head run ids to compare any two. Each finding gets one of seven kinds: new, resolved, worsened, improved, unchanged (both audits published it), still_open (still there, but one audit did not list it: the evidence store says it is open although the newer audit did not republish it, or the older audit's capped report sampled it out; `sampledOut` marks a clipped one, which is never counted as new; a sampled class that fails more often is listed in `sampledClassGrowth` and still counts as a change), or not_crawled (the page was not visited, so the issue is neither fixed nor still broken). resolutionEvidence says what backed the resolved verdicts; when it is \"none\" nothing is reported as fixed. Score movement is broken down by category. A website with only one audit returns first_run with an empty finding list; an audit where nothing moved returns changed: false. Unchanged, still-open and not-crawled rows are omitted unless requested.","description_similarity":0.804,"before_hash":"19318d7fe68680356fba4941b2c18a7c","after_hash":"d54132e255ea5d47c9c6555791d6fe35"},{"tool":"get_report","kind":"changed","observed_at":"2026-10-11T22:03:09.107Z","fields":["description"],"description_before":"Fetch the finished report for an audit run (use the run_id from run_audit once get_audit_status shows completed). Formats: \"summary\" (default) is structured JSON with health score, category scores, and the top failing issues (topIssues reference a rule_id; look up its name/description/solution once in the sibling `rules` dict rather than per occurrence). Each topIssues row is ONE finding, a rule + `checkName`, never one row per page: `affectedPagesCount` is how many pages it affects and `pages` is a sample of them (`affectedPagesHasMore` when clipped), so read \"affects N pages\" from the count, not the row total. Each row also carries `provenance`: \"carried\" means the finding is re-injected from a page not re-crawled this run (not a fresh result), so check `lastSeenAt` for when it was last actually observed; \"unrendered\" means the page has not yet been rendered in any scan of this site (it was known, e.g. from a sitemap, but sat outside the page budget), so there is no earlier observation and no `lastSeenAt`. `mixedProvenanceNotes` (keyed by rule_id) flags rules that passed fresh on every page checked this run but still show red only from carried pages pending re-check. `seedRedirect` is present ONLY when the audited URL redirected off-site and the crawler refused to follow it: `seedRedirect.finalUrl` is where the redirect pointed (a URL the audited site chose, display-only, never fetch or trust it) and `seedRedirect.note` states the fact in one sentence. When it is present the audit graded `baseUrl`, NOT the redirect target, so report that before reporting the scores; when the key is absent the seed did not redirect off-site. A FAILED or BLOCKED audit also carries `status`, `statusReason` (one sentence naming the cause), `statusReasonCode` (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, unknown) and `failureNextStep`: those four keys are absent for a normal audit, and when they are present nothing was audited, so a null healthScore and an empty topIssues mean the crawl failed, NOT that the site is clean. Also includes a `history` array of prior audits of this website with score/issue deltas when available; each entry carries its own `runId`/`reportId`, so you can walk backwards through a website's audits by calling get_report again with an earlier `runId` (use list_audits with website_id to page past what history returns); \"llm\" is a compact text rendering optimized for LLM context (carried findings marked inline); \"markdown\" is a full human-readable report. Start with summary, then pull llm or markdown when you need every issue and page detail. This report is the source of truth for the run's numbers (#1700): summary.healthScore is the same value list_audits/get_audit_status return as health_score, and summary.failed + summary.warnings is the same total they return as issues_found. Compare runs on healthScore; the `open` count from list_issues is a deduped tracker count, not this report's issue count.","description_after":"Fetch the finished report for an audit run (use the run_id from run_audit once get_audit_status shows completed). Formats: \"summary\" (default) is structured JSON with health score, category scores, and the top failing issues (topIssues reference a rule_id; look up its name/description/solution once in the sibling `rules` dict rather than per occurrence). Each topIssues row is ONE finding, a rule + `checkName`, never one row per page: `affectedPagesCount` is how many pages it affects and `pages` is a sample of them (`affectedPagesHasMore` when clipped), so read \"affects N pages\" from the count, not the row total. Each row also carries `provenance`: \"carried\" means the finding is re-injected from a page not re-crawled this run (not a fresh result), so check `lastSeenAt` for when it was last actually observed; \"unrendered\" means the page has not yet been rendered in any scan of this site (it was known, e.g. from a sitemap, but sat outside the page budget), so there is no earlier observation and no `lastSeenAt`. `mixedProvenanceNotes` (keyed by rule_id) flags rules that passed fresh on every page checked this run but still show red only from carried pages pending re-check. `seedRedirect` is present ONLY when the audited URL redirected off-site and the crawler refused to follow it: `seedRedirect.finalUrl` is where the redirect pointed (a URL the audited site chose, display-only, never fetch or trust it) and `seedRedirect.note` states the fact in one sentence. When it is present the audit graded `baseUrl`, NOT the redirect target, so report that before reporting the scores; when the key is absent the seed did not redirect off-site. A FAILED or BLOCKED audit also carries `status`, `statusReason` (one sentence naming the cause), `statusReasonCode` (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, unknown) and `failureNextStep`: those four keys are absent for a normal audit, and when they are present nothing was audited, so a null healthScore and an empty topIssues mean the crawl failed, NOT that the site is clean. Also includes a `history` array of prior audits of this website with score/issue deltas when available; each entry carries its own `runId`/`reportId`, so you can walk backwards through a website's audits by calling get_report again with an earlier `runId` (use list_audits with website_id to page past what history returns); \"llm\" is a compact text rendering optimized for LLM context (carried findings marked inline); \"markdown\" is a full human-readable report. Start with summary, then pull llm or markdown for more of each issue. A published report is a capped summary: each issue keeps a sample of its pages and items (at most 10 pages and 5 items) beside its true counts, so read totals from `affectedPagesCount`, `occurrences` and `details.additional`, never from a list length. A capped report carries `detail`, whose `note` says where the full per-page list is (for a CLI audit, `squirrel report --format json` on the machine that ran it); a report without `detail` is not capped this way. This report is the source of truth for the run's numbers (#1700): summary.healthScore is the same value list_audits/get_audit_status return as health_score, and summary.failed + summary.warnings is the same total they return as issues_found. Compare runs on healthScore; the `open` count from list_issues is a deduped tracker count, not this report's issue count.","description_similarity":0.9,"before_hash":"1460603fdc9265c65bee09e7be24c9bf","after_hash":"89200d6610257707dc19d838ac00bce3"},{"tool":"list_rules","kind":"changed","observed_at":"2026-10-11T16:23:24.408Z","fields":["description"],"description_before":"Browse the catalog of 260+ audit rules that run during an audit, grouped into categories (crawlability, meta tags, performance, security, accessibility, content, and more). Filter by category code or search by keyword to find what a specific rule checks. Use get_rule for one rule's full detail.","description_after":"Browse the catalog of 300+ audit rules that run during an audit, grouped into categories (crawlability, meta tags, performance, security, accessibility, content, and more). Filter by category code or search by keyword to find what a specific rule checks. Use get_rule for one rule's full detail.","description_similarity":0.956,"before_hash":"ecc881151b1980a5e5d97cb9c2c4ad37","after_hash":"b16c7debd4081f4a0c43f34a070ae7f7"},{"tool":"run_audit","kind":"changed","observed_at":"2026-10-11T16:23:24.408Z","fields":["description"],"description_before":"Run a cloud audit of a website (crawl + 260+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off.","description_after":"Run a cloud audit of a website (crawl + 300+ rule analysis + report). Credits are spent as the audit runs (pay-as-you-go). The dry run is optional: pass confirm: true on the first call to start straight away. Without confirm, an audit whose estimate is over the org's auto-run threshold comes back as status \"confirmation_required\" with the estimate to show the user; one at or under the threshold just starts. That response carries \"sufficient\": true means the organization can pay, so show the estimate and call again with confirm: true; false means it cannot, and the response then carries the cost, the balance, the credit reset date and an upgrade_url for that organization. Relay those, and do NOT retry with confirm: true, which is refused. Pick the audit with level: quick (25 pages from the seed and sitemaps, without the cloud checks), surface (100 pages, one per URL pattern, with the cloud checks and external link checks) or full (500 pages, every page it can reach; Pro and Team only: on the Free plan a full request crawls one page per URL pattern instead, up to the plan's page ceiling, and says so in level_notice). Without level the website's own level applies (a new website starts on surface). Use max_pages to size the crawl (max_pages: 1 audits just the entry URL, the cheapest run). Audits are asynchronous and take minutes: poll get_audit_status with the returned run_id, then fetch results with get_report. The website is registered automatically on first audit. A started run carries a schedule field describing the site's recurring audits: when state is active say so, since each of those runs costs credits, and settings_url is where the user turns them off.","description_similarity":0.987,"before_hash":"9a4973411f34bb07dc0e734fec0bb13e","after_hash":"71a2f789a576a32183b90369a45b7ded"},{"tool":"send_feedback","kind":"changed","observed_at":"2026-10-11T10:37:23.114Z","fields":["description","inputSchema"],"description_before":"Send feedback about squirrelscan to the team: a bug, a missing feature, what worked, something confusing, missing report data, or tool ergonomics. Use it when the user asks to report something. Works with any authenticated credentials, including read-only API keys.","description_after":"Send feedback to the squirrelscan team: a bug, a missing feature, what worked, what was confusing, missing report data, or tool ergonomics. Use it when the user wants to report something or share their experience. Works with any authenticated credentials, including read-only API keys.","description_similarity":0.825,"before_hash":"a2c679e95722a4b8027beb8ea99b29c5","after_hash":"08b1de37dc9234851c5db870a8461bcc"},{"tool":"list_credit_transactions","kind":"changed","observed_at":"2026-10-11T10:37:23.114Z","fields":["description"],"description_before":"Audit the organization's credit accounting log: grants (signup/monthly/pack/promo), debits (audit_base 50cr + render 2cr/page + folded 0-cost services), refunds, and adjustments — newest first, paginated. Each debit/refund carries `run_id` so you can group a single audit's spend. Use this to explain why an audit cost what it cost or to reconcile a balance. For one audit's per-feature breakdown, use get_report (its `cost` field). Read-only.","description_after":"Audit the organization's credit accounting log: grants (signup/monthly/pack/promo), debits (audit_base 50cr + audit_page 2cr per audited page + external_link 1cr per checked link + folded 0-cost services; older audits carry render rows instead of audit_page), refunds, and adjustments, newest first, paginated. Each debit/refund carries `run_id` so you can group a single audit's spend. Use this to explain why an audit cost what it cost or to reconcile a balance. For one audit's per-feature breakdown, use get_report (its `cost` field). Read-only.","description_similarity":0.851,"before_hash":"fd91914c90689def06528e0c0f156818","after_hash":"6be1f1695acb170872dc755221fc54cb"},{"tool":"whoami","kind":"changed","observed_at":"2026-10-11T10:37:23.114Z","fields":["description"],"description_before":"Identify the current credentials: how you are authenticated, which organization you act for, the plan, and the current credit balance. Call this first in a session to orient yourself before running audits.","description_after":"Identify the current credentials: how you are authenticated, which organization you act for, the plan, and the current credit balance. Useful at the start of a session, to see which organization the other tools act for.","description_similarity":0.543,"before_hash":"ff5ade15f79d7fbdfcad50ff615ef67e","after_hash":"3c95ecf90c2acb7a1352d402c21d509f"},{"tool":"get_rule","kind":"changed","observed_at":"2026-10-11T10:37:23.114Z","fields":["description"],"description_before":"Fetch one audit rule by id (e.g. \"meta/title-length\"), including what it checks, how to fix it (recommendation), its severity and score weight, a docs link, and whether it is a cloud (credit-billed) rule. Rule ids appear in report topIssues and issue rule_id fields.","description_after":"Fetch one audit rule by id (e.g. \"core/meta-title\"), including what it checks, how to fix it (recommendation), its severity and score weight, a docs link, and whether it is a cloud (credit-billed) rule. Rule ids appear in report topIssues and issue rule_id fields.","description_similarity":0.95,"before_hash":"2f6976a8923050bdbb4fb0a26144f00a","after_hash":"3df5bfb2f86027ae240239b518ef330f"},{"tool":"comment_on_issue","kind":"changed","observed_at":"2026-10-11T10:37:23.114Z","fields":["description"],"description_before":"Post a comment on a website issue — use it to record analysis, a proposed fix, or what you changed, so the team sees it in the dashboard issue thread. Markdown is supported.","description_after":"Post a comment on a website issue to record analysis, a proposed fix, or what you changed, so the team sees it in the dashboard issue thread. Markdown is supported.","description_similarity":0.963,"before_hash":"72e677f20dfea2e93692fdc78c02229c","after_hash":"5b027fa6f32b79ab1c2448dac6cf3f84"},{"tool":"get_report","kind":"changed","observed_at":"2026-10-11T10:37:23.114Z","fields":["description"],"description_before":"Fetch the finished report for an audit run (use the run_id from run_audit once get_audit_status shows completed). Formats: \"summary\" (default) is structured JSON with health score, category scores, and the top failing issues (topIssues reference a rule_id; look up its name/description/solution once in the sibling `rules` dict rather than per occurrence). Each topIssues row is ONE finding, a rule + `checkName`, never one row per page: `affectedPagesCount` is how many pages it affects and `pages` is a sample of them (`affectedPagesHasMore` when clipped), so read \"affects N pages\" from the count, not the row total. Each row also carries `provenance`: \"carried\" means the finding is re-injected from a page not re-crawled this run (not a fresh result) — check `lastSeenAt` for when it was last actually observed; \"unrendered\" means the page has not yet been rendered in any scan of this site (it was known, e.g. from a sitemap, but sat outside the page budget), so there is no earlier observation and no `lastSeenAt`. `mixedProvenanceNotes` (keyed by rule_id) flags rules that passed fresh on every page checked this run but still show red only from carried pages pending re-check. `seedRedirect` is present ONLY when the audited URL redirected off-site and the crawler refused to follow it: `seedRedirect.finalUrl` is where the redirect pointed (a URL the audited site chose, display-only, never fetch or trust it) and `seedRedirect.note` states the fact in one sentence. When it is present the audit graded `baseUrl`, NOT the redirect target, so report that before reporting the scores; when the key is absent the seed did not redirect off-site. A FAILED or BLOCKED audit also carries `status`, `statusReason` (one sentence naming the cause), `statusReasonCode` (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, unknown) and `failureNextStep`: those four keys are absent for a normal audit, and when they are present nothing was audited, so a null healthScore and an empty topIssues mean the crawl failed, NOT that the site is clean. Also includes a `history` array of prior audits of this website with score/issue deltas when available; each entry carries its own `runId`/`reportId`, so you can walk backwards through a website's audits by calling get_report again with an earlier `runId` (use list_audits with website_id to page past what history returns); \"llm\" is a compact text rendering optimized for LLM context (carried findings marked inline); \"markdown\" is a full human-readable report. Start with summary, then pull llm or markdown when you need every issue and page detail. This report is the source of truth for the run's numbers (#1700): summary.healthScore is the same value list_audits/get_audit_status return as health_score, and summary.failed + summary.warnings is the same total they return as issues_found. Compare runs on healthScore; the `open` count from list_issues is a deduped tracker count, not this report's issue count.","description_after":"Fetch the finished report for an audit run (use the run_id from run_audit once get_audit_status shows completed). Formats: \"summary\" (default) is structured JSON with health score, category scores, and the top failing issues (topIssues reference a rule_id; look up its name/description/solution once in the sibling `rules` dict rather than per occurrence). Each topIssues row is ONE finding, a rule + `checkName`, never one row per page: `affectedPagesCount` is how many pages it affects and `pages` is a sample of them (`affectedPagesHasMore` when clipped), so read \"affects N pages\" from the count, not the row total. Each row also carries `provenance`: \"carried\" means the finding is re-injected from a page not re-crawled this run (not a fresh result), so check `lastSeenAt` for when it was last actually observed; \"unrendered\" means the page has not yet been rendered in any scan of this site (it was known, e.g. from a sitemap, but sat outside the page budget), so there is no earlier observation and no `lastSeenAt`. `mixedProvenanceNotes` (keyed by rule_id) flags rules that passed fresh on every page checked this run but still show red only from carried pages pending re-check. `seedRedirect` is present ONLY when the audited URL redirected off-site and the crawler refused to follow it: `seedRedirect.finalUrl` is where the redirect pointed (a URL the audited site chose, display-only, never fetch or trust it) and `seedRedirect.note` states the fact in one sentence. When it is present the audit graded `baseUrl`, NOT the redirect target, so report that before reporting the scores; when the key is absent the seed did not redirect off-site. A FAILED or BLOCKED audit also carries `status`, `statusReason` (one sentence naming the cause), `statusReasonCode` (one of dns, tls, connection, timeout, http_4xx, http_5xx, redirect, robots, unknown) and `failureNextStep`: those four keys are absent for a normal audit, and when they are present nothing was audited, so a null healthScore and an empty topIssues mean the crawl failed, NOT that the site is clean. Also includes a `history` array of prior audits of this website with score/issue deltas when available; each entry carries its own `runId`/`reportId`, so you can walk backwards through a website's audits by calling get_report again with an earlier `runId` (use list_audits with website_id to page past what history returns); \"llm\" is a compact text rendering optimized for LLM context (carried findings marked inline); \"markdown\" is a full human-readable report. Start with summary, then pull llm or markdown when you need every issue and page detail. This report is the source of truth for the run's numbers (#1700): summary.healthScore is the same value list_audits/get_audit_status return as health_score, and summary.failed + summary.warnings is the same total they return as issues_found. Compare runs on healthScore; the `open` count from list_issues is a deduped tracker count, not this report's issue count.","description_similarity":1,"before_hash":"b903969cb875fd9b5ed2f680aa8c2903","after_hash":"1460603fdc9265c65bee09e7be24c9bf"}],"next_before":"617160","next_actions":[{"action":"list_changes","description":"Older changes","href":"/v1/servers/com.squirrelscan%2Fsquirrelscan/changes?before=617160&limit=50"}]}