> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appeeky.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Site Audit

> Crawl your app's website and find the on-page problems that cost rankings, from broken pages to missing titles and slow responses.

**Site audit** crawls your website and checks every page for the problems that hold rankings back: broken pages and links, missing or duplicate titles and descriptions, heading structure, noindex, canonicals, redirects, and slow or heavy pages. You get a health score and a list of issues with the page each one is on.

> [!NOTE]
>
> Requires a **Startup** or **Agentic Scale** plan and an [SEO project](https://docs.appeeky.com/docs/seo-overview.md). Site audits cost **0 credits**. In the dashboard: **SEO for Apps → Site audit**.

***

## How it works

1. **Crawl.** Appeeky starts at your project's website, or a URL you give, and follows links on that site. URLs listed in your sitemap are included. Links to other sites are not followed.
2. **Check.** Each HTML page is checked against the rules below. Your `robots.txt` and sitemap are checked once for the whole site.
3. **Score.** The health score is 0–100: the share of pages without issues. A page with an error counts fully against the score; a page with only warnings counts half. Notices don't lower it.

An audit takes a minute or two. One audit can run per project at a time.

***

## Issues

| Severity | Code | What it means |
| - | - | - |
| Error | `http_4xx`, `http_5xx` | The page returned a 4xx or 5xx status |
| Error | `fetch_failed` | The page couldn't be loaded |
| Error | `broken_internal_link` | A page links to another page on your site that returns 4xx or 5xx |
| Error | `missing_title` | No `<title>` |
| Warning | `duplicate_title` | Same title as another page |
| Warning | `title_too_long`, `title_too_short` | Title over 60 or under 10 characters |
| Warning | `missing_meta_description` | No meta description |
| Warning | `duplicate_meta_description` | Same description as another page |
| Warning | `missing_h1` | No H1 heading |
| Warning | `noindex` | The page asks search engines not to index it |
| Warning | `slow_response` | Response took over 1.5 seconds |
| Warning | `large_page` | Page is over 2 MB |
| Warning | `missing_viewport` | No viewport meta tag, so it may not render well on phones |
| Warning | `insecure_url` | An `http://` page on a site that starts on `https://` |
| Notice | `meta_description_too_long` | Description over 160 characters |
| Notice | `multiple_h1` | More than one H1 |
| Notice | `missing_canonical`, `canonical_elsewhere` | No canonical tag, or it points to another URL |
| Notice | `redirect` | The URL redirects |
| Notice | `thin_content` | Fewer than 200 words |
| Notice | `images_missing_alt` | Images without alt text |
| Notice | `missing_lang` | No `lang` attribute on the page |
| Notice | `missing_robots_txt`, `missing_sitemap` | No `robots.txt` or sitemap found |

Pages marked `noindex` skip the title, description, heading, canonical and word-count checks, since they aren't competing in search.

***

## API

| Method | Endpoint | Description |
| - | - | - |
| POST | `/v1/seo/audits` | Start an audit |
| GET | `/v1/seo/audits?project=` | Audit history, newest first (`?limit=`, 1–50, default `20`) |
| GET | `/v1/seo/audits/:id` | One audit with every issue and crawled page |
| DELETE | `/v1/seo/audits/:id` | Delete an audit |

### Start an audit

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://api.appeeky.com/v1/seo/audits \
  -H "X-API-Key: $APPEEKY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "projectId": "PROJECT_ID", "maxPages": 200 }'
```

| Field | Type | Description |
| - | - | - |
| `projectId` | string | Required |
| `url` | string | Start URL. Default: the project's website |
| `maxPages` | number | Pages to crawl, 1–500. Default `100` |

Response (`201`):

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "audit": {
      "id": "AUDIT_ID",
      "projectId": "PROJECT_ID",
      "startUrl": "https://focustimer.app/",
      "status": "running",
      "maxPages": 200,
      "pagesCrawled": 0,
      "healthScore": null,
      "issueCounts": { "error": 0, "warning": 0, "notice": 0 },
      "summary": [],
      "error": null
    }
  }
}
```

### Read the results

Poll `GET /v1/seo/audits/:id` until `status` is `done` or `failed`. `pagesCrawled` updates while it runs. When it is done you get:

* `healthScore` and `issueCounts` by severity
* `summary`: each issue type with the number of pages it affects, errors first
* `issues`: every issue with its `url` and a short `detail`, like the broken link target or the measured title length
* `pages`: every crawled page with status, response time, size, title, meta description, H1, word count, canonical and issue count

If an audit stops before it finishes, it is marked `failed`. Start it again.

### Errors

| Status | Code | When |
| - | - | - |
| 400 | `invalid_url` | The project has no website and no `url` was given, or the URL isn't valid |
| 404 | `not_found` | The audit or project doesn't exist |
| 409 | `already_running` | An audit is already running for this project |

***

## MCP

| Tool | Description |
| - | - |
| `seo_site_audit_start` | Start an audit (`project_id`, `url`, `max_pages`) |
| `seo_site_audits_list` | Audit history with health scores |
| `seo_site_audit_get` | Results of one audit |

Example prompt: *"Audit focustimer.app and list the errors I should fix first, grouped by page."*

***

## Tips

* Fix errors first. Broken pages and links waste the visits search engines make to your site.
* Run an audit after a redesign or a migration to catch new redirects and lost titles.
* Write the pages you're missing with [page briefs](https://docs.appeeky.com/docs/seo-playbook.md) in the playbook.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.