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.
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
- In the app, open Settings and go to Agent & MCP.
- Under "Or set it up by hand", click Create API key. If you already have one, the button is Rotate key, which replaces it.
- Copy the key from the Your new API key dialog. It is shown only once; afterwards you see just its prefix.
- 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:
export SEOFIX_API_KEY="sk_..."
npx seofix connect also creates a key, for an AI agent on your machine. See API keys.
2. Authenticate
Send the key in the Authorization header on every request:
curl -s https://api.seofix.ai/v1/ping \
-H "Authorization: Bearer $SEOFIX_API_KEY"
{"user_id": 42}
A missing or wrong key answers 401:
{"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
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:
{"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
curl -s https://api.seofix.ai/v1/crawls/4821 \
-H "Authorization: Bearer $SEOFIX_API_KEY"
{
"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:
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.
5. Get the report
curl -s https://api.seofix.ai/v1/crawls/4821/report \
-H "Authorization: Bearer $SEOFIX_API_KEY"
{
"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. Requests are limited to 60 per minute per key; see Errors and rate limits.
Related
More in REST API
Still stuck? Email [email protected] with your site and what you expected to see.