Developers
AvocadoScore API
The same checks that power the free tools, over plain HTTP. JSON in, JSON out. No account, no API key, no signup. Check whether a site is ready for ChatGPT, Claude and Perplexity, which AI crawlers it lets in, generate an llms.txt, run a full scan, or embed a live score badge.
Quick start
Every endpoint takes a JSON body and returns JSON. Send content-type: application/json. A URL can be written with or without https://.
curl -s https://avocadoscore.io/api/readiness \
-H 'content-type: application/json' \
-d '{"url":"example.com"}'That returns the site’s SEO and AI-readiness scores and every check behind them, in a few seconds. The endpoints only fetch public pages: private, internal and non-routable addresses are refused.
Readiness check
POST/api/readiness
An instant SEO and AI-readiness check of a site’s homepage (no PageSpeed run, so it answers in seconds). The same engine and checks as the full scan, applied to the homepage.
Request
{ "url": "example.com" }Response 200
{
"url": "https://example.com",
"domain": "example.com",
"seo": {
"score": 83, "passed": 10, "warned": 1, "failed": 1, "total": 12,
"checks": [ /* { id, label, status, detail? } … */ ]
},
"ai": {
"score": 71, "passed": 11, "warned": 3, "failed": 4, "total": 18,
"checks": [ { "id": "llms-txt", "label": "/llms.txt",
"status": "fail", "pillar": "comprehension" } /* … */ ],
"botPolicies": [ { "bot": "GPTBot", "vendor": "OpenAI",
"status": "unspecified", "kind": "training" } /* … */ ],
"hasLlmsTxt": false,
"hasLlmsFullTxt": false,
"pillars": { "access": { "score": 80, "passed": 4, "warned": 1, "failed": 1, "total": 6 },
"comprehension": { /* … */ }, "trust": { /* … */ } }
},
"stored": true
}Abridged, values illustrative. Scores are 0–100. A check’s status is pass, warn or fail; a check flagged bonus is a positive-only signal that isn’t counted in the score. status for a crawler is allowed, blocked (robots.txt disallows it entirely), partial (some paths) or unspecified (no rule, so it may crawl). stored says whether the result was kept for 7 days so a comparison page can show the site without checking it again.
AI bot check
POST/api/bot-check
Which AI crawlers can read the site: every major crawler’s robots.txt policy, plus a live fetch as GPTBot to see whether the content is actually served (a firewall can block a bot that robots.txt allows).
Request
{ "url": "example.com" }Response 200
{
"url": "https://example.com",
"domain": "example.com",
"robotsPresent": true,
"rows": [
{ "id": "GPTBot", "vendor": "OpenAI", "product": "ChatGPT (training)",
"kind": "training", "note": "…", "status": "blocked" } /* … */
],
"summary": { "allowed": 2, "blocked": 3, "partial": 0, "unspecified": 7, "total": 12 },
"live": {
"bot": "GPTBot", "bytesAsBot": 48211, "bytesAsBrowser": 48302,
"ratio": 0.998, "botBlocked": false, "status": "pass", "detail": "…"
}
}kind is search for crawlers that fetch pages to answer or cite, and training for ones that feed models. live is null when the live fetch itself failed; that never fails the request.
llms.txt generator
POST/api/llms-generator
Reads a site’s sitemap and returns a starter llms.txt, with the URLs grouped into sections.
Request
{ "url": "example.com" }Response 200
{
"url": "https://example.com",
"domain": "example.com",
"title": "Example",
"description": "…",
"sections": [ { "title": "Docs", "links": [ { "title": "Guide", "url": "https://example.com/guide" } ] } ],
"content": "# Example\n\n> …",
"urlCount": 128
}content is the finished Markdown, ready to save as /llms.txt. A site with no sitemap and no homepage links returns 502.
Full scans
A full scan is the free report: up to 10 pages picked from the sitemap, Core Web Vitals plus SEO and AI readiness, with every fix. It runs in the background, so you create it, poll its status, then read the report.
Create a scan
POST/api/scans
{ "url": "example.com" }201 { "id": "8c1f…", "status": "queued" }
200 { "id": "8c1f…", "status": "done", "reused": true }200 with reused: true means we already have a recent scan of that domain (one that hasn’t failed and was created in the last 10 minutes, or a free scan that finished in the last 24 hours), so you get that one back instead of a new run.
Poll the status
GET/api/scans/{id}
{
"id": "8c1f…", "url": "https://example.com", "domain": "example.com",
"tier": "free", "status": "scanning",
"progress": { "phase": "scanning", "done": 3, "total": 10, "currentUrl": "https://example.com/pricing" },
"discoveredCount": 42, "errorMessage": null, "hasData": false
}status moves through queued, discovering, scanning, aggregating, done, failed. Poll every few seconds until it is done (or failed, with errorMessage set). Responses are never cached.
Read the result
The full report is a public page at https://avocadoscore.io/r/{id}, shareable by link. For just the headline scores as JSON:
GET/api/scans/{id}/summary
{ "id": "8c1f…", "domain": "example.com", "ready": true,
"perf": 71, "seo": 88, "ai": 72 }ready: false (with no scores) until the scan finishes; a score the engine couldn’t produce is null. A private (paid) scan’s scores are not returned without access. Cached for 5 minutes.
Badges
GET/api/badge/{domain}?metric=ai
A live SVG badge you can paste once (README, site footer, blog post): it always shows the domain’s latest result. metric is ai (the default), seo, perf or verdict. The score is coloured by band: 90+ green, 50–89 amber, below 50 red.
[](https://avocadoscore.io/)- Where the numbers come from: the latest free scan of the domain and, for the AI and SEO scores, the site’s stored readiness check, whichever is newer.
perfandverdictexist only once the domain has had a full scan. Paid and monitor scans are never shown on a public badge. - A domain with nothing on file yet returns a grey “—” badge, never a broken image. An invalid domain returns
400. - Cached for about 5 minutes, so a re-scan shows up quickly.
- The report page’s “Embed this badge” card generates the snippet for you.
GET /api/scans/{id}/badge?metric=… is the older per-scan version: a snapshot of one scan, which a re-scan doesn’t change.
Errors
Errors are JSON: { "error": "…" }, with a reason when the site itself couldn’t be read. Treat the message text as for humans and branch on the status code and reason.
400: malformed JSON, a missing or implausible URL, or an address that isn’t a public website.422(creating a scan) and502(the checks): the site couldn’t be reached or read; seereasonbelow.429: over a limit. Theretry-afterheader says how many seconds to wait.500: something failed on our side. Try again.
reason values
dns- the domain doesn't resolve
refused- connection refused or reset
timeout- no response before the deadline
tls- certificate or TLS handshake problem
auth- the homepage needs a login (401)
forbidden- a firewall or CDN is blocking automated requests (403)
rate-limited- the site answered 429
not-found- the homepage is 404 or 410
client-error- another 4xx
server-error- the site answered 5xx
redirect-loop- too many redirects
redirect-invalid- a redirect we could not follow
bot-challenge- the site is behind a bot-protection challenge
login-wall- the homepage is a login page
unknown- something else went wrong
Limits and fair use
The endpoints are free and need no key, so they are rate limited per IP address. Limits are approximate: they reset over a rolling window and can vary slightly between our servers.
| Endpoint | Per IP | Per domain |
|---|---|---|
| POST /api/readiness | 30 / hour | — |
| POST /api/bot-check | 30 / hour | — |
| POST /api/llms-generator | 20 / hour | — |
| POST /api/scans | 5 / hour | 3 / day |
- The status and summary reads, and the badges, have no per-request limit of their own; the badges are cached at the edge, so embedding one is cheap.
- Check sites you own or that are public. We fetch the target server-side, so the request comes from our servers, not yours. See how our crawler behaves.
- Responses can gain new fields over time. Ignore fields you don’t recognise, and don’t depend on field order.
- Need more volume, or a bulk run? Email hello@avocadoscore.io.
Prefer a UI?
Everything above is also available without code: the readiness checker, the AI bot checker, the llms.txt generator and a full scan. Curious how sites compare? See the State of AI Readiness report.