Score any URL for AI search readiness. Free, open-source, no signup. Try it live → score.seoryon.com
A free tool that scores any URL on 27 signals AI search engines use to decide what to cite, and returns the top fixes — ranked by impact.
Built and maintained by Oryon — the SEO engine that writes and publishes articles built to rank AND get cited. This is the demo. Your whole site is the product.
$ oryon-score https://example.com/blog/ai-overview-guide
Oryon AI Search Readiness Score
https://example.com/blog/ai-overview-guide
The AI Overview Guide: How to Get Cited by Google AI
62/100 · Grade C
By bucket
Schema Structure ████████████████░░░░░░░░ 18.6/30
Content Format █████████████████░░░░░░░ 17.0/25
Authority ████████████░░░░░░░░░░░░ 12.0/20
Crawlability ███████████████████░░░░░ 11.4/15
Freshness ███░░░░░░░░░░░░░░░░░░░░░ 3.0/10
Top fixes (in order of impact)
✗ FAQ schema (No FAQPage schema.)
→ Wrap your FAQ section in FAQPage JSON-LD — highest-correlation signal.
✗ TL;DR / summary block near top (No TL;DR or summary block found.)
→ Add a 50-word TL;DR after the H1. AI summarizers lift these at much higher rates.
✗ Last modified date (No modification date detected.)
→ Expose a dateModified in JSON-LD or via Last-Modified header.
...
Want continuous scoring across every page on your site?
→ Try Oryon free for 3 days: seoryon.com
The market for AI citation tracking is dominated by dashboards starting at €295/mo. Most SEO teams just need to answer one question: "is my page set up to get cited at all?" That answer should be free.
This tool gives you that answer in 10 seconds. No signup. No tokens. Just paste a URL.
If you want continuous scoring across every URL on your site, plus AI citation tracking across ChatGPT / Perplexity / Gemini / Google AI, plus a writer that ships extractable articles automatically — that's Oryon. From €39/mo.
27 signals across 5 buckets that AI Overviews + LLM citation systems actually weight:
- Article / BlogPosting JSON-LD
- FAQPage schema (highest-correlation signal)
- HowTo schema
- BreadcrumbList schema
- Heading hierarchy (1 H1, ≥3 H2s)
- Definition lists (
<dl>) - Table markup
- Question-style H2s
- Word count in the 1200–3500 sweet spot
- Direct answer in the first 60 words
- TL;DR / summary block near the top
- Bold emphasis in the first section
- 3+ structured lists
- Outbound links to .gov / .edu / Wikipedia
- 5–50 internal links (healthy range)
- Named author / byline (E-E-A-T)
- Outbound link density (3–30)
<blockquote>/<cite>markup
- HTTPS
- Canonical URL
- Mobile viewport
- Open Graph (≥3 og:* tags)
llms.txtat site rootrobots.txtallows GPTBot, ClaudeBot, PerplexityBot, CCBot, Google-Extended, etc.
dateModifiedorLast-Modifiedheader- Dated phrases in body ("as of May 2026")
- Year in title
Each signal has a specific fix — what to change, where to change it, why it matters. No fluff.
Just open score.seoryon.com and paste a URL.
pip install oryon-score
oryon-score https://example.com/blog/your-best-article
oryon-score https://example.com --json
oryon-score https://example.com --out report.jsonRequires Python 3.10+.
git clone https://github.com/SEOryon/oryon-score
cd oryon-score
pip install -e .
oryon-score https://example.comfrom oryon_score import score_url
result = score_url("https://example.com/blog/post")
print(result.score, result.grade)
for fix in result.fixes:
print(" -", fix)The web/ + api/ folders deploy as a Vercel project. Two files matter:
web/index.html— the public scoring pageapi/score.py— the Python serverless endpoint
npm i -g vercel
vercelDone. Your fork is now live at your-project.vercel.app. Add a custom domain in Vercel's dashboard.
See examples/example_output.json for the full JSON shape returned by the API and the --json flag.
The web UI renders the same data with bucket bars, top fixes, and a "what's working" passlist.
A score is not a verdict. It's a snapshot of extractable signals on the page itself. Three things this tool does not measure:
- Domain authority / backlink graph. Out of scope. AI citation correlates with authority, but measuring it requires a third-party API and we kept this free.
- Whether the page is actually cited today. Use the Citation Intelligence MCP by AutomateLab for live LLM citation data.
- Brand authority signals. Wikipedia mentions, press coverage, Reddit references — they matter, and the tool flags some, but it can't grade them holistically.
For all three layers, see Oryon — that's what the paid product does.
- Runs on Vercel's free Python runtime
- No third-party APIs, no API keys to maintain
- No tracking, no telemetry, no user accounts
- Self-hostable in one click
Open source under MIT. Fork it, run it on your own infra, change it, ship it.
Both the hosted scorer and the pip CLI refuse to fetch URLs that resolve to
non-public addresses — RFC1918 / loopback / link-local (incl. 169.254.169.254
cloud metadata) / IPv6 ULA / multicast / reserved — and re-validate on every
redirect hop. Public URLs are unaffected. See SECURITY_REVIEW.md §3.1 for
the full design + test matrix.
If you wrap score_url() behind your own hosted endpoint, you inherit this
guard — don't disable it without re-reading §3.1.
The hosted endpoint at score.seoryon.com/api/score is rate-limited per IP
to protect against abuse:
| Window | Cap |
|---|---|
| Per minute | 20 requests / IP / min |
| Per day | 200 requests / IP / day |
Either threshold returns HTTP 429 with a friendly JSON message and a
Retry-After header (seconds until the next request from that IP could
succeed). A normal user evaluating the tool — or an agency auditing a whole
site in one sitting — will not hit these.
State lives in Upstash Redis via its REST API
(cross-instance — every Vercel cold-start sees the same counters). The
critical-section is an atomic INCR so concurrent requests cannot race past
the cap. Reads are best-effort: if Upstash is unreachable, the endpoint
fails OPEN (serves the request, logs the error) — availability over
strict limiting for a free public tool. The SSRF guard still applies, so
the dangerous path is protected regardless.
The limiter is off until two env vars are present. Until then, every request passes through and the function logs one warning at startup. To turn it on:
- Create an Upstash Redis database at console.upstash.com. The free tier is enough for low-volume use; if you expect non-trivial traffic, upgrade to Pay-As-You-Go ($0.20 per 100K commands). The rate limiter sends 4 commands per scored request — heavy traffic can drain the free tier's daily quota, which the limiter treats as an abuse signal (see "Quota burn" below).
- From the database's REST API tab, copy:
UPSTASH_REDIS_REST_URL(looks likehttps://us1-foo-12345.upstash.io)UPSTASH_REDIS_REST_TOKEN(long opaque string)
- In Vercel → Project → Settings → Environment Variables, add both for the Production environment (and Preview / Development if you want the same limits there). Mark the token as a Secret.
- Optional overrides — set if you want different caps without a code change:
RATE_LIMIT_PER_MINUTE(default20)RATE_LIMIT_PER_DAY(default200)
- Redeploy the project (Vercel applies env-var changes on the next deploy). The next cold start picks up the new variables and the limiter activates automatically.
Verify it's on by sending 21 requests in under a minute from the same IP — the 21st should return 429.
Each scored request sends 4 commands to Upstash. An attacker can intentionally
drain the daily Upstash quota (free-tier: 10K commands/day) and rely on the
"store-error" path silently switching the limiter OFF. The limiter prevents
this by treating Upstash's own 429 or 403 responses as an abuse signal:
when Upstash is rate-limiting us, the endpoint fails CLOSED (returns 429
to every user) instead of failing OPEN. You'll notice immediately because
every request 429s; the fix is to raise the Upstash quota (upgrade the plan
or rotate to a larger DB) — an attacker that paid for proxy traffic to burn
the quota gets no bypass for their trouble.
Transient errors (timeout, 5xx, bad token, JSON parse error) still fail-OPEN, so a real outage doesn't take the tool down.
The oryon-score CLI calls score_url() directly on your own machine —
it does NOT go through /api/score. CLI users are therefore not rate-
limited by the hosted endpoint; they are limited only by their own
machine's network and CPU.
This tool's structured-signal approach was inspired by citation-intelligence by AutomateLab — a self-hosted MCP server for measuring LLM citation visibility. Go check it out if you want programmatic citation data from inside Claude Code or Cursor. This tool solves a different layer (page readiness, not live citation queries) and is original work.
PRs welcome. Especially:
- New signals (anything with a published correlation study)
- Translations of the web UI
- WordPress / Webflow / Shopify integrations
- A GitHub Action that scores changed URLs on every PR
See CONTRIBUTING.md.
MIT — see LICENSE.
Built by Oryon · Your Organic Growth Engine. Follow @SEOryon for SEO content that doesn't lie.