# REST API quickstart

> Create an API key, authenticate with a bearer header, and run your first audit with curl - start it, poll it and read the report.

Source: https://seofix.ai/help/api-quickstart · Category: REST API · Updated: 2026-10-08

The SEOFix REST API lives at `https://api.seofix.ai/v1`. Create an API key in Settings → Agent & MCP, send it as `Authorization: Bearer sk_...`, then `POST /v1/crawls` to start an audit, poll `GET /v1/crawls/{id}` until `status` is `done`, and read `GET /v1/crawls/{id}/report`.

## 1. Create an API key

1. In the app, open **Settings** and go to **Agent & MCP**.
2. Under "Or set it up by hand", click **Create API key**. If you already have one, the button is **Rotate key**, which replaces it.
3. Copy the key from the **Your new API key** dialog. It is shown only once; afterwards you see just its prefix.
4. Click **I've saved it**.

Keys start with `sk_`. A key acts for the team you were viewing when you created it. Store it as a secret, for example in an environment variable:

```bash
export SEOFIX_API_KEY="sk_..."
```

`npx seofix connect` also creates a key, for an AI agent on your machine. See [API keys](https://seofix.ai/help/api-keys.md).

## 2. Authenticate

Send the key in the `Authorization` header on every request:

```bash
curl -s https://api.seofix.ai/v1/ping \
  -H "Authorization: Bearer $SEOFIX_API_KEY"
```

```json
{"user_id": 42}
```

A missing or wrong key answers 401:

```json
{"error": {"code": "unauthenticated", "message": "Valid API key required."}}
```

All requests and responses are JSON. Send `Content-Type: application/json` with a body.

## 3. Start an audit

```bash
curl -s -X POST https://api.seofix.ai/v1/crawls \
  -H "Authorization: Bearer $SEOFIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "max_pages": 500}'
```

The API answers `202 Accepted`:

```json
{"crawl_id": 4821, "estimated_credits": 500, "max_rps": 2}
```

`estimated_credits` is reserved from your balance now: the page cap. The audit is billed 1 credit per page crawled (0.2 per page unchanged since the site's previous audit, rounded up per audit), and the unused rest is refunded when it ends. If your balance is below `max_pages`, the answer is `402 insufficient_credits`.

Without `max_pages`, the cap is 10,000 pages or your plan's limit, whichever is lower, and 500 unless you have a verified site for that origin. The crawler runs at 2 requests per second by default.

## 4. Poll until it finishes

```bash
curl -s https://api.seofix.ai/v1/crawls/4821 \
  -H "Authorization: Bearer $SEOFIX_API_KEY"
```

```json
{
  "crawl_id": 4821,
  "status": "running",
  "pages_crawled": 137,
  "max_pages": 500,
  "failure_reason": null,
  "duration_s": 74,
  "pages_per_minute": 111.1
}
```

`status` moves through `queued`, `running` and `finalizing` to `done`, `failed` or `cancelled`. Poll every 10 to 30 seconds. A shell loop:

```bash
while :; do
  status=$(curl -s https://api.seofix.ai/v1/crawls/4821 \
    -H "Authorization: Bearer $SEOFIX_API_KEY" | jq -r .status)
  echo "$status"
  case "$status" in done|failed|cancelled) break ;; esac
  sleep 10
done
```

Instead of polling, you can pass `webhook_url` when you start the audit. See [Webhooks](https://seofix.ai/help/webhooks.md).

## 5. Get the report

```bash
curl -s https://api.seofix.ai/v1/crawls/4821/report \
  -H "Authorization: Bearer $SEOFIX_API_KEY"
```

```json
{
  "crawl_id": 4821,
  "health_score": 87,
  "partial": false,
  "totals": {"pages": 500, "ok": 471, "redirects": 18, "broken": 9, "fetch_errors": 2, "blocked": 0},
  "issue_counts": {"error": 41, "warning": 230, "notice": 96},
  "issues": [
    {"check_code": "TITLE_MISSING", "severity": "error", "count": 23, "fix": "..."}
  ],
  "coverage_warning": null
}
```

If the report is not written yet, the answer is `404 report_not_ready`. It can appear a few seconds after `status` is `done`: wait and retry.

## 6. Go further

| To | Call |
| --- | --- |
| List the issues, filtered | `GET /v1/crawls/{id}/issues?severity=error&check=TITLE_MISSING` |
| See issues by page template | `GET /v1/crawls/{id}/templates` |
| Get a fix prompt for a coding agent | `GET /v1/crawls/{id}/fix-prompt` |
| Register a site for repeat audits | `POST /v1/sites` |
| Re-audit a registered site | `POST /v1/sites/{id}/crawls` |
| Compare with the previous audit | `GET /v1/crawls/{id}/diff` |
| Get fix tasks ranked by impact | `GET /v1/sites/{id}/tasks` |
| Verify a fix in seconds | `POST /v1/sites/{id}/recheck` |

Every endpoint is in the [API reference](https://seofix.ai/help/api-reference.md). Requests are limited to 60 per minute per key; see [Errors and rate limits](https://seofix.ai/help/errors-and-rate-limits.md).

## Related

- [API reference](https://seofix.ai/help/api-reference.md)
- [API keys](https://seofix.ai/help/api-keys.md)
- [Webhooks](https://seofix.ai/help/webhooks.md)
- [Errors and rate limits](https://seofix.ai/help/errors-and-rate-limits.md)
