Skip to main content

seoscoreapi

Python client for SEO Score API — audit any URL for SEO issues with one function call.

Install

pip install seoscoreapi

Quick Start

from seoscoreapi import audit, signup

# Get a free API key (2 audits/day, no credit card)
key = signup("you@example.com")

# Run an audit
result = audit("https://example.com", api_key=key)
print(f"Score: {result['score']}/100 ({result['grade']})")

Functions

Function Description
signup(email) Get a free API key
audit(url, api_key) Run SEO audit on a URL
batch_audit(urls, api_key) Audit up to 10 URLs in one call (paid)
compare(urls, api_key) Compare 2–5 URLs with a structured diff (Basic+)
competitive_audit(url, competitor_url, keyword, api_key) Head-to-head audit with gap score (Pro+)
history(url, api_key, limit=100, since=None) Full audit timeseries + summary for a URL (Starter+)
history_domains(api_key) Every domain audited by this key with latest score and 30-day trend (Starter+)
usage(api_key) Check usage and limits
add_monitor(url, api_key, frequency="daily", webhook_url=None, alert_threshold=5) Set up score monitoring with optional Slack/webhook alerts (paid)
list_monitors(api_key) List active monitors
remove_monitor(url, api_key) Remove a monitor
scoreboard_opt_out(api_key, opt_out=True) Opt in or out of the public scoreboard
report_url(domain) Get shareable report URL
accessibility_audit(url, api_key, include=None) ADA / WCAG 2.1 AA audit (paid; own monthly allowance). include="trackers" adds the tracker inventory
audit_export(url, api_key, format="pdf", brand_name=None, brand_color=None, logo_url=None) Audit as a PDF / Markdown / CSV file; returns bytes. White-label on Pro and Ultra
ai_readability(url, api_key) How well AI/LLM systems can consume the page
trackers(url, api_key) Third-party trackers and pixels the page loads
conversion(url, api_key, page_type=None) Conversion score: headline, CTA, trust, forms, objections
quick_wins(api_key, rows=None, csv=None, **options) Page-2 quick wins from your own Search Console export (every plan)
backlinks(domain, api_key, limit=50) Observed backlinks, an audit-fed sample (Basic+)
generate_llms_txt(domain, api_key=None) llms.txt for a domain; returns str. Curated version on Basic+
geo_audit(url, api_key) GEO audit: visibility to LLMs (Basic+)
geo_brand_probe(brand, domain, prompts, api_key, models=None, runs_per_prompt=None) How often LLMs mention your brand (Basic+)
add_geo_monitor(url, api_key, frequency="weekly", alert_threshold=-5, webhook_url=None) Create a GEO monitor (Basic+)
list_geo_monitors(api_key) / remove_geo_monitor(url, api_key) List / remove GEO monitors
geo_monitor_history(monitor_id, api_key, page=1, per_page=20) Score history for a GEO monitor
start_crawl(url, api_key, max_pages=None) / get_crawl(job_id, api_key) Start / poll a multi-page site crawl (Pro/Ultra, or a Deep Audit credit)
wait_for_crawl(job_id, api_key, ...) / crawl(url, api_key, max_pages=None, ...) Poll a crawl to completion / start one and wait
citation_starter_prompts(topic, api_key, ...) / citation_suggest_prompts(domain, api_key) Prompts to track for AI citations (not metered)
create_citation_tracker(brand, api_key, **fields) Track a brand in AI answers (Starter+)
list_citation_trackers(api_key) / get_citation_tracker(id, api_key) Trackers plus the month's check usage / one tracker
update_citation_tracker(id, api_key, **fields) / delete_citation_tracker(id, api_key) Edit / stop a tracker
run_citation_tracker(id, api_key) / get_citation_run(run_id, api_key) Run a tracker now / read a run's results
citation_tracker_history(id, api_key, days=90) Mention rate, citation rate, share of voice, position over time
citation_check(brand, prompt, api_key, **fields) One-off citation check, metered per check (paid)
citation_topups(api_key) / citation_topup_checkout(pack, api_key) Top-up packs and balance / Stripe Checkout URL for a pack
citation_auto_reload(api_key) Read the auto-reload setting (read-only; change it on the dashboard)

Errors are requests.HTTPError (from raise_for_status()); the API's message is in err.response.json()["detail"].

Historical tracking

Every audit on a paid plan returns a history block on the /audit response:

result = audit("https://example.com", api_key=key)
delta = result["history"].get("delta")
if delta:
    print(f"Score change: {delta['score']:+.1f} ({delta.get('grade_change') or 'no grade change'})")

Pull the full timeseries with history() or a one-shot per-domain summary with history_domains(). Retention windows: Starter 30 days, Basic 90 days, Pro 1 year, Ultra unlimited.

Webhook alerts on score drops

add_monitor(
    "https://example.com",
    api_key=key,
    frequency="daily",
    webhook_url="https://hooks.slack.com/services/T0/B0/xxxx",
    alert_threshold=5,
)

Slack incoming-webhook URLs are auto-formatted as Block Kit messages; any other https endpoint receives the raw event JSON.

Accessibility audit and report files

import seoscoreapi as seo

ada = seo.accessibility_audit("https://example.com", API_KEY)
print(ada["score"], len(ada["violations"]))

# PDF, Markdown ("md") or CSV. Returns the file's bytes.
pdf = seo.audit_export("https://example.com", API_KEY, "pdf", brand_name="Acme Agency")
open("report.pdf", "wb").write(pdf)

ADA audits are on paid plans and have their own monthly allowance, separate from the audit quota (usage() reports ada_remaining). audit_export counts as one audit; the white-label parameters need Pro or Ultra.

Site crawl

Asynchronous, like Deep Site Audit. Pro and Ultra include crawls; any other plan spends one Deep Audit credit per crawl.

job = seo.crawl("https://example.com", API_KEY, max_pages=25,
                on_progress=lambda j: print(j["status"], j.get("pages_done")))
print(job["result"]["summary"], job["site_map"])

# Or drive it yourself:
started = seo.start_crawl("https://example.com", API_KEY)     # POST /crawl
job = seo.get_crawl(started["job_id"], API_KEY)               # GET  /crawl/{job_id}
job = seo.wait_for_crawl(started["job_id"], API_KEY, timeout=600)

wait_for_crawl and crawl return the whole completed job (result, site_map, pages_done), raise TimeoutError on timeout and RuntimeError if the crawl fails.

AI citations

Do ChatGPT, Gemini, Perplexity and Claude mention and cite you? A tracker is a brand plus the prompts buyers type. A check is one prompt on one engine, sampled once.

starter = seo.citation_starter_prompts("SEO audit API", API_KEY, brand="Acme",
                                       competitors=["Rival"], audience="marketing agencies")

tracker = seo.create_citation_tracker("Acme", API_KEY, domains=["acme.com"],
                                      prompts=starter["prompts"], cadence="weekly")
run = seo.run_citation_tracker(tracker["id"], API_KEY)        # waits for the engines
history = seo.citation_tracker_history(tracker["id"], API_KEY, days=90)

seo.list_citation_trackers(API_KEY)["usage"]   # checks_limit, checks_used, checks_available, ...
seo.citation_topups(API_KEY)                   # packs, balance, can_buy
url = seo.citation_topup_checkout("500", API_KEY)   # Stripe Checkout URL; nothing is charged until it is paid
seo.citation_auto_reload(API_KEY)              # read-only

A run needs all of its checks up front (the month's allowance plus any top-up balance); if that is short the API answers 429 and nothing is spent. Auto-reload can only be turned on or changed from the dashboard, never with an API key, so this client has no setter.

Search Console quick wins

wins = seo.quick_wins(API_KEY, csv=open("Queries.csv").read(), exclude_terms=["acme"])
for w in wins["quick_wins"]:
    print(w["query"], w["position"], w["estimated_extra_clicks"])

We do not connect to your Search Console: you send the export (or rows=[...]).

Deep Site Audit (Pro/Ultra, or credits)

A deep, AI-assisted audit scoring a URL across 9 dimensions (thousands of catalog checks plus up to 150 AI checks). It runs asynchronously, so start a job and poll it, or use deep_audit to block for the result:

import seoscoreapi as seo

# One call, waits for the result (handles the queue + backpressure for you):
result = seo.deep_audit(
    "https://yoursite.com", API_KEY,
    business_type="saas",                      # tunes which checks apply
    on_progress=lambda s: print(s["status"], s.get("queue_position", s.get("progress"))),
)
print(result["scores"]["lai_score"], result["scores"]["section_scores"])

# Or drive the job yourself:
job = seo.site_audit("https://yoursite.com", API_KEY)       # POST /site-audit
status = seo.get_site_audit(job["job_id"], API_KEY)         # GET  /site-audit/{job_id}
# status["status"] -> queued | running | completed | failed
#   queued    -> {"queue_position", "eta_seconds"}
#   completed -> {"result"}
result = seo.wait_for_site_audit(job["job_id"], API_KEY, timeout=600)

seo.deep_audit_usage(API_KEY)   # GET /deep-audit/usage -> {"site_audit": {"used", "remaining"}, ...}

Deep audits are included on Pro ($39/mo, 20/mo) and Ultra ($99/mo, 100/mo); any other key can run them on purchased credits.

Since 1.5.0 the SDK calls the main host, https://seoscoreapi.com, like every other endpoint. To point Deep Audit somewhere else (a proxy, staging, or the legacy engine.seoscoreapi.com host, which still works), pass base_url= to any Deep Audit function, assign seoscoreapi.DEEP_AUDIT_URL, or set SEOSCORE_DEEP_AUDIT_URL. engine_usage() is kept as an alias of deep_audit_usage().

Docs: seoscoreapi.com/docs (Deep Site Audit section).

Full Documentation

seoscoreapi.com/docs

Metadata

Release files for seoscoreapi 1.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for seoscoreapi 1.6.0
File Size Uploaded
seoscoreapi-1.6.0.tar.gz 18.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for seoscoreapi 1.6.0
File Interpreter ABI Platform
seoscoreapi-1.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.1 kB

Release files / seoscoreapi-1.6.0.tar.gz

Download URL seoscoreapi-1.6.0.tar.gz
Size 18.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f8dafed543f383d6e6f3d0769d884024cbb5b49ecc235d29458926aca389bcad
BLAKE2b-256 checksum
How to use checksums
a57ac74b89aceb0f6fbff40090b480b316c23d86db035fcea5cc5fd94a861b0d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / seoscoreapi-1.6.0-py3-none-any.whl

Download URL seoscoreapi-1.6.0-py3-none-any.whl
Size 13.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f49fd1bc607b07cc8e7e9e592ddfdaaaee0fab26228965b7d493220fb33c5f1d
BLAKE2b-256 checksum
How to use checksums
d4917d0e1df70cbe325bcbe487d053cb5b75586e29c5366d3479cafa0f255a93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

1.7.1

2 release files

1.7.0

2 release files

1.6.1

2 release files

This release

1.6.0 This release

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page