Short answer: yes, there is a free SEO API you can call from code. SEO Score API has a free tier of 2 audits per day with no credit card: send GET /audit?url=... with an X-API-Key header and you get back JSON with a 0-100 score, a letter grade, per-category scores and a list of fixes. The free tier runs 55 checks per URL; paid plans run 83 and start at $5 a month.
I'm Aaron, the solo developer who built it, so read this as a tutorial from the person with the bias. I've tried to be plain about what the free tier leaves out and when you should use something else.
How do I check a website's SEO score programmatically?
Three steps: get a key, make one GET request, read the JSON.
Sign up on the homepage or do it from the terminal. Signup is two calls because the key is tied to a verified email address:
curl -s -X POST https://seoscoreapi.com/signup \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com"}'
# a 6-digit code arrives by email
curl -s -X POST https://seoscoreapi.com/verify \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "code": "123456"}'
Then audit a URL:
curl -s --max-time 120 -H "X-API-Key: YOUR_API_KEY" \
"https://seoscoreapi.com/audit?url=https://example.com" \
| jq '{score, grade, issues: (.priorities | length)}'
With a paid key, that printed this when I ran it for this post:
{
"score": 65.567,
"grade": "C",
"issues": 8
}
Note that score is a decimal, not an integer. Compare it as a number.
What does the SEO audit API return?
Here is an excerpt of the real response for https://example.com, trimmed to one check per category and one fix. I removed items; I did not rename or add any field.
{
"url": "https://example.com",
"score": 65.567,
"grade": "C",
"response_code": 200,
"response_time": "0.50s",
"audit": {
"meta": {
"score": 52.75,
"checks": [
{
"name": "title",
"status": "warning",
"value": "Example Domain",
"score": 50,
"recommendation": "Title is short (14 chars). Aim for 50-60 characters."
}
]
},
"technical": {
"score": 70.0,
"checks": [
{ "name": "response_time", "status": "pass", "value": "0.50s", "score": 100 }
]
}
},
"priorities": [
{
"severity": "high",
"category": "meta",
"issue": "Missing meta description",
"fix": "Add a meta description (150-160 chars)",
"plain_english": "The page has no summary for search results, so Google picks a random snippet that may not make people click.",
"who_fixes_it": "content"
}
],
"ai_readability": {
"ai_readability_score": 43,
"ai_readability_grade": "F"
}
}
The audit object has five categories: meta, technical, social, performance and accessibility. Each has a score and a checks array, and each check has a name, a status (pass, warning, fail or info), the value found and usually a recommendation. priorities is the fix list sorted by severity, and who_fixes_it is developer, content or marketing. The response also carries a core_web_vitals block, which can come back with "status": "unavailable" when the upstream lookup fails, so don't assume it is populated.
How do I call it from Python?
There is an official client on PyPI (pip install seoscoreapi). It is a thin wrapper over requests:
import os
import sys
from seoscoreapi import audit
url = sys.argv[1] if len(sys.argv) > 1 else "https://example.com"
result = audit(url, api_key=os.environ["SEOSCORE_API_KEY"])
print(f"{result['url']}: {result['score']}/100 ({result['grade']})")
for name, category in result["audit"].items():
print(f" {name:<14} {category['score']}")
for p in result["priorities"]:
print(f" [{p['severity']}] {p['issue']} ({p['who_fixes_it']})")
Output from my run:
https://example.com: 65.567/100 (C)
meta 52.75
technical 70.0
social 50.0
performance 96.25
accessibility 66.667
[high] Missing meta description (content)
[high] No H1 tag found (content)
[medium] Thin content (133 words) (content)
...
audit() raises requests.HTTPError on a non-2xx response, so a 401 (bad key) or 429 (out of quota, or too many requests per minute) surfaces as an exception.
How do I call it from Node.js?
Same idea with the npm package (npm install seoscoreapi). It uses the built-in fetch, so you need Node 18 or later:
const { audit } = require("seoscoreapi");
async function main() {
const url = process.argv[2] || "https://example.com";
try {
const result = await audit(url, process.env.SEOSCORE_API_KEY);
console.log(`${result.url}: ${result.score}/100 (${result.grade})`);
for (const p of result.priorities) {
console.log(` [${p.severity}] ${p.issue} -> ${p.fix}`);
}
} catch (err) {
// err.status is the HTTP status: 401 bad key, 429 out of quota or too fast
console.error(`Audit failed (${err.status || "network"}): ${err.message}`);
process.exit(1);
}
}
main();
If you'd rather not add a dependency, the curl call above translates directly to fetch or requests.get. There is nothing else to the protocol.
What does the free tier not include?
The free tier is real (no trial clock, no card), but it is small, and the response is trimmed. From the pricing table and the API docs:
- 2 audits per day and 2 requests per minute. Enough to test the API or watch one page. Not enough to audit a sitemap.
-
55 checks, not 83. The SXO, AEO and AIO scoring blocks are paid. A free response has an
_extended_gatedplaceholder where they would be. -
A capped fix list and capped check detail. The overall score, grade and category scores are complete, but the
prioritieslist and the per-categorychecksarrays are shortened on free keys. A_priorities_gatedor_gatedfield tells you how many more there are. -
No history, batch or monitoring. Score deltas,
POST /audit/batchand scheduled monitoring start on the $5 Starter plan. - No accessibility (WCAG) audit, GEO audit or AI citation tracking. Those are paid endpoints.
-
One URL per call.
/auditscores a page. It does not crawl a site.
Two more things worth knowing before you build on it. Audits add the audited domain to a public scoreboard unless you opt your key out with PUT /scoreboard/opt-out?opt_out=true. And set a client timeout of a minute or two: the site says most pages finish in about two seconds, but in my runs for this post one call took under 7 seconds and another took about a minute.
Paid plans, for reference: Starter $5/month (200 audits), Basic $15 (1,000), Pro $39 (5,000), Ultra $99 (25,000).
Which free SEO API should I use?
It depends on what you are measuring. I'd pick a different tool in several of these cases.
| Tool | Cost | What you get | Better choice when |
|---|---|---|---|
| SEO Score API (free tier) | $0, 2 audits/day | One score plus on-page, technical, social and AI-readability checks as JSON | You want a single number and a fix list from one HTTP call, with nothing to host |
| Google PageSpeed Insights API | Free | Lighthouse lab data plus real-user Core Web Vitals where Google has them | Performance is the question. It is Google's own data and I can't match it |
| Lighthouse CI | Free, open source | Lighthouse runs on your own machine or CI runner | You need to test a local build or a page behind a login, or you want no third party and no quota |
| Open-source crawlers (Scrapy, advertools) | Free, you host it | Whatever you program it to collect, across a whole site | You need site-wide crawling, broken-link checks or custom rules, and can maintain it |
None of these, mine included, do keyword research or rank tracking. That is what Ahrefs, Semrush and Moz are for.
FAQ
Is there a free SEO API for developers?
Yes. SEO Score API's free tier gives 2 audits per day and 2 requests per minute, with no credit card. Google's PageSpeed Insights API is also free and is the better choice for performance data.
How many checks does the free tier run?
55 per URL, across meta and content, technical SEO, social tags, performance, accessibility and AI readability. Paid plans add 28 SXO, AEO and AIO checks for 83.
Do I need a credit card?
No. Signup is an email address and a 6-digit verification code.
Can I audit a whole site?
Not with one free call. /audit takes one URL. Batch audits (up to 10 URLs per request) and multi-page crawls are on paid plans.
Can I use it in CI?
Yes. There is an official GitHub Action, SeoScoreAPI/seo-audit-action, that fails a build when the score drops below a threshold. On the free tier, budget for 2 runs a day.
Where are the full docs?
The OpenAPI reference is at seoscoreapi.com/docs.
Top comments (0)