URL: /reports

---
title: "Reports & Scoring"
description: "Understanding audit reports and health score calculation"
---

squirrelscan generates comprehensive audit reports with a health score and detailed issue breakdown.

## Health Score

The health score is calculated from 0-100 based on:

- **Rule weights** - Each rule has a weight (1-10) reflecting its importance
- **Check results** - Pass/fail/warning status of each check (warnings count as 0.5)
- **Scoring curve** - Compresses high scores to reward perfection
- **Penalties** - Applied for critical crawlability issues and high issue density

### Scoring Formula

```
Base Score = (Earned Weight / Total Weight) × 100
Curved Score = Base Score ^ 1.2
Issue Density Penalty = up to -45% when many warnings/fails (kicks in after 20+ issues)
Final Score = Curved Score × Penalty Multipliers × Issue Density Multiplier
```

### Penalties

Critical crawlability issues reduce the final score:

| Issue | Penalty | Check |
|-------|---------|-------|
| Missing robots.txt | -15% | `crawl/robots-txt` |
| Robots blocks all | -50% | `crawl/robots-txt` |
| Missing sitemap | -20% | `crawl/sitemap-exists` |
| High issue density | up to -45% | Any rules (applied when 20+ warnings/fails exist) |

Penalties are multiplicative. For example, an 80% score with missing robots.txt (-15%) and no sitemap (-20%):

```
80 × (1 - 0.15) × (1 - 0.20) = 80 × 0.85 × 0.80 = 54.4
```

### Grade Scale

| Score | Grade |
|-------|-------|
| 90-100 | A |
| 80-89 | B |
| 70-79 | C |
| 60-69 | D |
| 0-59 | F |

### Category Scores

Each category (core, content, links, etc.) receives its own score:

- Weighted by rule importance within category
- Includes pass/warning/fail counts
- Sorted by error count (most errors first)
- Perfect categories (100%, no issues) shown last

## Output Formats

squirrelscan supports multiple report formats optimized for different use cases.

### console (Default)

Human-readable terminal output with colors and formatting.

```bash
squirrel report
```

**Output:**
```
================================================================================
SQUIRRELSCAN REPORT
https://example.com • 42 pages • 87/100 (B)
================================================================================

Health Score: 87/100 (B)

Category Breakdown:
--------------------------------------------------
Core SEO             ██████████ 100%
  Passed: 45 | Warnings: 0 | Failed: 0
Links                ████████░░ 85%
  Passed: 23 | Warnings: 5 | Failed: 3
Images               ███████░░░ 72%
  Passed: 15 | Warnings: 8 | Failed: 6

Total: 83 passed, 13 warnings, 9 errors

ISSUES

Content (2 errors, 3 warnings)
  content/word-count Word Count (warning)
    ✗ Low word count: 150 words (min: 300) (3 pages)
      → /blog/post-1
      → /blog/post-2
      → /about
```

**Features:**
- Color-coded severity (red errors, yellow warnings)
- Visual progress bars for category scores
- Grouped by category
- Shows affected pages

### json

Machine-readable format for CI/CD pipelines, programmatic processing, and LLM consumption.

```bash
squirrel report -f json -o report.json
```

**Structure:**
```json
{
  "baseUrl": "https://example.com",
  "crawledAt": "2026-01-17T00:00:00Z",
  "totalPages": 42,
  "healthScore": {
    "overall": 87,
    "categories": [
      {
        "category": "core",
        "name": "Core SEO",
        "score": 100,
        "passed": 45,
        "warnings": 0,
        "failed": 0,
        "total": 45
      }
    ],
    "errorCount": 9,
    "warningCount": 13,
    "passedCount": 83
  },
  "ruleResults": [
    {
      "id": "content/word-count",
      "name": "Word Count",
      "category": "content",
      "severity": "warning",
      "checks": [
        {
          "name": "min-words",
          "status": "fail",
          "message": "Low word count: 150 words (min: 300)",
          "pages": ["/blog/post-1", "/blog/post-2"]
        }
      ]
    }
  ]
}
```

**Use Cases:**
- CI/CD pipeline integration
- Fail builds on score thresholds
- Track score trends over time
- Feed into monitoring systems
- LLM analysis

### html

Interactive HTML report that opens in a browser.

```bash
squirrel report -f html -o report.html
open report.html
```

**Features:**
- Visual dashboard with charts
- Filter by category/severity
- Sort by page/rule/severity
- Search functionality
- Export filtered results
- Responsive design

### markdown

Markdown format for documentation and README files.

```bash
squirrel report -f markdown -o report.md
```

**Output:**
```markdown
# Audit Report

**Site:** https://example.com
**Pages:** 42
**Health Score:** 87/100 (B)

## Health Score

Overall: **87/100** (B)

### Category Breakdown

| Category | Score | Passed | Warnings | Errors |
|----------|-------|--------|----------|--------|
| Core SEO | 100% | 45 | 0 | 0 |
| Links | 85% | 23 | 5 | 3 |
| Images | 72% | 15 | 8 | 6 |

## Issues

### Content (2 errors, 3 warnings)

#### ⚠️ Word Count
Low word count detected on 3 pages.
```

**Use Cases:**
- Add to repository README
- Document audit results
- Share in pull requests
- Include in technical specs

### text

Plain text format without colors or formatting (for piping and scripting).

```bash
squirrel report -f text > report.txt
```

**Use Cases:**
- Email reports
- Log files
- Plain text editors
- Grep/search processing

### llm

**Compact token-optimized format for AI agents** - hybrid XML/text structure designed for LLM consumption.

```bash
squirrel report -f llm -o report.xml
```

or pipe directly:

```bash
squirrel report -f llm | claude "analyze this audit and prioritize fixes"
```

**Format Structure:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<audit version="0.0.13">
<site url="https://example.com" crawled="42" date="2025-01-18T10:30:00Z"/>
<score overall="87" grade="B">
 <cat name="Core SEO" score="100"/>
 <cat name="Links" score="85"/>
 <cat name="Images" score="72"/>
</score>
<summary passed="83" warnings="13" failed="9"/>
<issues>
 <category name="Content" errors="2" warnings="3">
  <rule id="content/word-count" severity="warning" status="warn">
   Low word count: 150 words (min: 300)
   Desc: Pages should have sufficient content for good SEO
   Fix: Add more relevant content to improve page depth
   Pages (3): /blog/post-1, /blog/post-2, /about
  </rule>
 </category>
 <category name="Images" errors="6" warnings="0">
  <rule id="images/alt-text" severity="error" status="fail">
   Desc: All images must have descriptive alt text
   Fix: Add alt attributes to img tags
   Items (6):
    - /products/widget.png (from: /products)
    - /hero.jpg (from: /)
  </rule>
 </category>
</issues>
</audit>
```

**Key Features:**
- **40-70% smaller** than verbose XML (125KB vs 209KB for 51-page audit)
- **1-space indentation** for token efficiency
- **Inline attributes** - metadata as XML attributes, not nested elements
- **Text prefixes** - `Desc:`, `Fix:`, `Pages (n):`, `Items (n):`
- **Comma-separated lists** - pages and URLs formatted inline
- **Hybrid structure** - XML tags for parsing, text for readability

**Token Efficiency:**
The LLM format achieves significant size reduction through:
- Minimal indentation (1 space vs 2-4)
- Flattened hierarchy (fewer nesting levels)
- Inline attributes instead of nested elements
- Comma-separated lists instead of multiple elements
- Text prefixes instead of wrapping tags

**Use Cases:**
- Piping to Claude Code, Cursor, or other AI assistants
- Token-limited API contexts (Claude API, GPT)
- Cost optimization for LLM processing
- Agent-based workflows requiring structured output

See [OUTPUT-FORMAT.md](https://github.com/squirrelscan/skills/blob/main/audit-website/references/OUTPUT-FORMAT.md) for complete format specification.

### xml

**Verbose structured XML format** for enterprise integration and detailed archival.

```bash
squirrel report -f xml -o report.xml
```

**Format Structure:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<audit version="0.0.13">
  <site>
    <url>https://example.com</url>
    <crawled>42</crawled>
    <date>2025-01-18T10:30:00Z</date>
  </site>
  <score>
    <overall>87</overall>
    <grade>B</grade>
    <categories>
      <category>
        <name>Core SEO</name>
        <score>100</score>
      </category>
    </categories>
  </score>
  <issues>
    <category>
      <name>Content</name>
      <rules>
        <rule>
          <id>content/word-count</id>
          <description>Pages should have sufficient content</description>
          <solution>Add more relevant content to improve page depth</solution>
          <pages>
            <page>/blog/post-1</page>
            <page>/blog/post-2</page>
          </pages>
        </rule>
      </rules>
    </category>
  </issues>
</audit>
```

**Key Features:**
- **2-space indentation** for readability
- **Fully nested elements** - all metadata in dedicated tags
- **Explicit structure** - strict schema compliance
- **Detailed metadata** - all information preserved
- **Enterprise-ready** - suitable for XML parsers and validators

**Comparison: LLM vs XML**

| Aspect | LLM Format | XML Format |
|--------|-----------|------------|
| Size (51 pages) | 125KB | 209KB |
| Indentation | 1 space | 2 spaces |
| Structure | Hybrid XML/text | Pure XML |
| Metadata | Inline attributes | Nested elements |
| Lists | Comma-separated | Multiple elements |
| Best For | AI agents, tokens | Enterprise, archival |

**Use Cases:**
- Enterprise data integration
- Detailed audit archival
- Schema validation requirements
- XML processing pipelines
- Long-term storage with full metadata

## Filtering Reports

### By Severity

Show only errors:
```bash
squirrel report --severity error
```

Show only warnings:
```bash
squirrel report --severity warning
```

### By Category

Filter by single category:
```bash
squirrel report --category core
```

Filter by multiple categories:
```bash
squirrel report --category core,links,images
```

**Available categories:**
- `core` - Core SEO elements (title, meta, canonical)
- `content` - Content quality (word count, headings, duplicates)
- `links` - Link analysis (broken, internal, external)
- `images` - Image optimization (alt text, formats, dimensions)
- `schema` - Structured data (JSON-LD validation)
- `security` - Security headers (HTTPS, CSP, HSTS)
- `a11y` - Accessibility (ARIA, contrast, focus)
- `i18n` - Internationalization (lang, hreflang)
- `perf` - Performance (LCP, CLS, lazy loading)
- `social` - Social media (Open Graph, Twitter Cards)
- `crawl` - Crawlability (robots, sitemaps, indexability)
- `url` - URL structure (length, keywords, parameters)
- `mobile` - Mobile optimization (viewport, tap targets)
- `legal` - Legal compliance (privacy, cookies, terms)
- `local` - Local SEO (NAP, geo tags)
- `video` - Video optimization (schema, thumbnails)
- `analytics` - Analytics tracking (GTM, consent)
- `eeat` - E-E-A-T signals (author, expertise, trust)
- `adblock` - Adblock detection

### Combined Filters

Combine severity and category filters:
```bash
squirrel report --severity error --category links,images
```

## Diff Reports

Compare a baseline audit to the current report:

```bash
squirrel report --diff a7b3c2d1 --format json
```

Compare the latest report for a domain against a baseline audit:

```bash
squirrel report --regression-since example.com --format llm
```

<Note>
Diff mode supports `console`, `text`, `json`, `llm`, and `markdown`. `html` and `xml` are not supported in diff mode. Diff reports cannot be published with `--publish`.
</Note>

## CI/CD Integration

### Fail Build on Low Score

```bash
#!/bin/bash
SCORE=$(squirrel audit https://example.com -f json | jq '.healthScore.overall')
if [ "$SCORE" -lt 80 ]; then
  echo "Health score too low: $SCORE/100 (minimum: 80)"
  exit 1
fi
```

### Fail on Errors

```bash
#!/bin/bash
ERRORS=$(squirrel audit https://example.com -f json | jq '.healthScore.errorCount')
if [ "$ERRORS" -gt 0 ]; then
  echo "Audit failed with $ERRORS errors"
  exit 1
fi
```

### GitHub Actions Example

```yaml
name: SEO Audit
on: [push]
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: curl -fsSL https://install.squirrelscan.com | sh
      - run: squirrel audit https://preview.example.com -f json -o report.json
      - run: |
          SCORE=$(jq '.healthScore.overall' report.json)
          echo "Health Score: $SCORE/100"
          if [ "$SCORE" -lt 80 ]; then exit 1; fi
      - uses: actions/upload-artifact@v4
        with:
          name: audit-report
          path: report.json
```

## Report Storage

Audit reports are stored in a local SQLite database at:

```
~/.local/share/squirrel/audits.db
```

### List Stored Audits

```bash
squirrel report --list
```

**Output:**
```
Recent Audits:
================================================================================
ID       Date                   Pages    Status
--------------------------------------------------------------------------------
a7b3c2d1 1/17/2026, 10:30 AM    42       complete
  https://example.com
5e9f1a3b 1/16/2026, 3:45 PM     38       complete
  https://test.com

Total: 2 audits
```

### View Specific Audit

By ID:
```bash
squirrel report a7b3c2d1
```

By domain:
```bash
squirrel report example.com
```

### Delete Old Audits

Reports are kept indefinitely. To clean up:

```bash
# Remove specific audit
rm -rf ~/.local/share/squirrel/audits.db

# This will be regenerated on next audit
```

## Publishing Reports

Share audit reports online by publishing to `reports.squirrelscan.com`. Published reports can be shared with clients, included in documentation, or consumed programmatically by LLMs and CI pipelines.

<Note>
Publishing requires authentication. Run `squirrel auth login` first.
</Note>

### Publish from CLI

Publish directly during an audit:

```bash
squirrel audit example.com --publish
```

Or publish from a stored audit:

```bash
squirrel report --publish
squirrel report a7b3c2d1 --publish --visibility unlisted
```

The CLI prints the published URL:

```
https://reports.squirrelscan.com/SJEItpldwW
```

### Visibility

| Level | Description |
|-------|-------------|
| `public` | Listed and searchable (default) |
| `unlisted` | Accessible via direct link only |
| `private` | Only visible to you when logged in |

```bash
squirrel report --publish --visibility private
```

### Output Formats via URL

Published reports support multiple output formats. Append a file extension to the report URL to get a specific format:

| Format | URL | Use Case |
|--------|-----|----------|
| HTML | [/SJEItpldwW](https://reports.squirrelscan.com/SJEItpldwW) | Browser viewing (default) |
| JSON | [/SJEItpldwW.json](https://reports.squirrelscan.com/SJEItpldwW.json) | CI/CD, programmatic access |
| Markdown | [/SJEItpldwW.md](https://reports.squirrelscan.com/SJEItpldwW.md) | Documentation, READMEs |
| Plain Text | [/SJEItpldwW.txt](https://reports.squirrelscan.com/SJEItpldwW.txt) | Email, logs |
| XML | [/SJEItpldwW.xml](https://reports.squirrelscan.com/SJEItpldwW.xml) | Enterprise integration |
| LLM | [/SJEItpldwW.llm](https://reports.squirrelscan.com/SJEItpldwW.llm) | AI agents, token-efficient |

Without an extension, the format is determined by the `Accept` header. Browsers receive HTML, while tools like `curl` can request specific formats:

```bash
# Get JSON via Accept header
curl -H "Accept: application/json" https://reports.squirrelscan.com/SJEItpldwW

# Get JSON via extension (simpler)
curl https://reports.squirrelscan.com/SJEItpldwW.json

# Pipe LLM format to Claude
curl -s https://reports.squirrelscan.com/SJEItpldwW.llm | claude "prioritize fixes"
```

### Managing Published Reports

Visit the [dashboard](https://squirrelscan.com/dashboard) to manage published reports:

- Change visibility (public/unlisted/private)
- Delete published reports
- View report analytics (view count, last viewed)

See [Dashboard](/dashboard) for full documentation.

## Related

- [audit](/cli/audit) - Run new audit
- [report](/cli/report) - Report command reference
- [Dashboard](/dashboard) - Manage published reports
- [Rules Reference](/rules) - All audit rules
- [Configuration](/configuration) - Config file options
