API & MCP
Read your audits from code, or let an assistant read them for you
A read-only REST API over crawls, findings and rankings, and an MCP server that puts the same data inside Claude.
- REST endpoints
- 10REST endpoints
- MCP tools
- 6MCP tools
- nothing spends a credit
- Read-onlynothing spends a credit
- on the MCP server, both spec eras
- OAuth 2.1on the MCP server, both spec eras
Ten endpoints
GET /v1/meThe account, its plan and what the plan allows.
GET /v1/sitesYour sites. Audited competitors are deliberately absent - they are crawl targets, not sites you own.
GET /v1/sites/{id}/crawlsCrawl history with status, pages, credits and the health score.
GET /v1/crawls/{id}One crawl, with the summary it was scored from.
GET /v1/crawls/{id}/findingsFindings, filterable by severity and status, each one named rather than only identified.
GET /v1/crawls/{id}/accessibilityThe WCAG 2.2 panel by success criterion: what failed, on how many pages, the elements, and what a machine cannot decide.
GET /v1/crawls/{id}/pagesEvery URL the crawl fetched, with its status, word count and how many findings sit on it - including the pages with none.
GET /v1/crawls/{id}/segmentsPer-segment scores, with the pattern each was matched by.
GET /v1/sites/{id}/rankingsPositions over time for the keywords you track.
GET /v1/sites/{id}/searchSearch Console clicks, impressions and CTR, with the top queries and pages. The same data the MCP server has always had.
$ curl -H "Authorization: Bearer sk_…" \
https://api.seodar.io/v1/sites
{
"items": [
{
"id": "…",
"root_url": "https://example.com",
"crawls": 12
}
]
}Six MCP tools
The MCP server puts the same data inside an assistant. Ask what regressed since last week and the answer comes from your crawls rather than from the model’s idea of what usually regresses.
list_sites, get_audit, get_accessibility, list_findings, list_rankings, search_console, get_account
Webhooks, signed
Point a channel at your own endpoint and each event arrives as JSON rather than as a sentence in someone else’s chat format. Five events today: a scan finished, the health score fell, new criticals appeared, a scheduled scan was skipped, and a Google connection was removed.
Every delivery is signed. The header is an HMAC-SHA256 over timestamp + "." + body under a secret shown to you once - the timestamp is inside the signed string, so a captured request stops verifying within minutes rather than being replayable for ever.
X-Seodar-Event- which event this isX-Seodar-Delivery- one id per event per channel, the same across retries, so you can deduplicateX-Seodar-TimestampandX-Seodar-Signature- Three attempts, one second apart, on a timeout or a 5xx or a 429. A 4xx is not retried. Ten consecutive failures switch the channel off and tell you.
POST /your/endpoint
X-Seodar-Event: score_drop
X-Seodar-Signature: v1=9f86d0…
X-Seodar-Timestamp: 1754668800
{"event":"score_drop",
"title":"Health score fell 7 points",
"site":"https://example.com",
"link":"https://seodar.io/crawls/…",
"occurred_at":"2026-08-08T…",
"delivery_id":"…"}import hmac, hashlib, time
def valid(secret, headers, raw):
ts = int(headers["X-Seodar-Timestamp"])
if abs(time.time() - ts) > 300:
return False
mine = hmac.new(secret.encode(),
f"{ts}.".encode() + raw,
hashlib.sha256).hexdigest()
return hmac.compare_digest(
"v1=" + mine,
headers["X-Seodar-Signature"])Scan on deploy
A deploy key starts one scan of one site and can do nothing else - it cannot read a finding, list your sites, or see a score. Which is why the key above stays read-only: the two jobs need different amounts of trust, so they get different credentials.
Not a Vercel or Netlify webhook, on purpose. It is a plain POST with a bearer token, so it works from anything that runs a command after a deploy - and you can debug it with curl rather than with a vendor’s event log.
- 202 - queued, with the crawl id
- 200 - a scan for this site was already running, so that one is returned rather than a second started
- 429 - this key has used its scans for today. Four by default, adjustable to 24
- 402 / 403 - not enough credits, or the account’s email is not verified
# after your build, anywhere
curl -sS -X POST https://api.seodar.io/v1/deploys \
-H "Authorization: Bearer $SEODAR_DEPLOY_KEY"
{"crawl_id":"…","status":"queued",
"started":true,"pages_limit":500,
"credits_estimate":50,
"scans_left_today":3}Create the key on a site’s Integrations page. It is shown once, scans that site only, and is revocable.
How it behaves
Keys shown once
Created on the API page in your account, scoped to that account, revocable, and never shown again after the first screen.
Rate limited per plan
The allowance is on the pricing page, and the API tells you what is left rather than only refusing.
Nothing private leaves
Internal notes on findings never appear in the public API, whatever the caller asks for.
Seat scoping enforced server-side
A client seat sees what that seat is scoped to, decided on the server rather than filtered in the response.
What is deliberately not in it
Nothing that writes. No endpoint starts a crawl, changes a plan, or spends a credit - which is why a leaked key is an embarrassment rather than an invoice.
Questions
- Yes. Nothing in it starts a crawl or spends a credit, so a key that leaks cannot cost you money.
- A bearer key you create on the API page in your account. Keys are shown once, scoped to the account, and revocable.
- It lets an assistant query your account directly - 'what regressed on this site since last week' answered from your own data rather than from the model's guess. It speaks OAuth 2.1, and works with clients on the current spec and the previous one.
- Any plan with an API request allowance. The plan page states the number.
Start free
One site and 100 credits - up to 200 pages a scan, about 5 scans, and the whole report. No card. Paid plans add more sites, bigger crawls and the AI rewrites.