seoscoreapi 1.4.0__tar.gz → 1.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- seoscoreapi-1.6.0/PKG-INFO +225 -0
- seoscoreapi-1.6.0/README.md +207 -0
- {seoscoreapi-1.4.0 → seoscoreapi-1.6.0}/pyproject.toml +1 -1
- seoscoreapi-1.6.0/seoscoreapi/__init__.py +687 -0
- seoscoreapi-1.6.0/seoscoreapi.egg-info/PKG-INFO +225 -0
- {seoscoreapi-1.4.0 → seoscoreapi-1.6.0}/seoscoreapi.egg-info/SOURCES.txt +3 -1
- seoscoreapi-1.6.0/tests/test_deep_audit.py +114 -0
- seoscoreapi-1.6.0/tests/test_endpoints.py +204 -0
- seoscoreapi-1.4.0/PKG-INFO +0 -117
- seoscoreapi-1.4.0/README.md +0 -99
- seoscoreapi-1.4.0/seoscoreapi/__init__.py +0 -230
- seoscoreapi-1.4.0/seoscoreapi.egg-info/PKG-INFO +0 -117
- {seoscoreapi-1.4.0 → seoscoreapi-1.6.0}/seoscoreapi.egg-info/dependency_links.txt +0 -0
- {seoscoreapi-1.4.0 → seoscoreapi-1.6.0}/seoscoreapi.egg-info/requires.txt +0 -0
- {seoscoreapi-1.4.0 → seoscoreapi-1.6.0}/seoscoreapi.egg-info/top_level.txt +0 -0
- {seoscoreapi-1.4.0 → seoscoreapi-1.6.0}/setup.cfg +0 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seoscoreapi
|
|
3
|
+
Version: 1.6.0
|
|
4
|
+
Summary: Python client for SEO Score API — audit any URL for SEO issues with one function call
|
|
5
|
+
Author-email: SEO Score API <info@seoscoreapi.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://seoscoreapi.com
|
|
8
|
+
Project-URL: Documentation, https://seoscoreapi.com/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/avansledright/seoscoreapi.com
|
|
10
|
+
Keywords: seo,audit,api,seo-score,website-audit,seo-checker
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: requests>=2.20
|
|
18
|
+
|
|
19
|
+
# seoscoreapi
|
|
20
|
+
|
|
21
|
+
Python client for [SEO Score API](https://seoscoreapi.com) — audit any URL for SEO issues with one function call.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install seoscoreapi
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from seoscoreapi import audit, signup
|
|
33
|
+
|
|
34
|
+
# Get a free API key (2 audits/day, no credit card)
|
|
35
|
+
key = signup("you@example.com")
|
|
36
|
+
|
|
37
|
+
# Run an audit
|
|
38
|
+
result = audit("https://example.com", api_key=key)
|
|
39
|
+
print(f"Score: {result['score']}/100 ({result['grade']})")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Functions
|
|
43
|
+
|
|
44
|
+
| Function | Description |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `signup(email)` | Get a free API key |
|
|
47
|
+
| `audit(url, api_key)` | Run SEO audit on a URL |
|
|
48
|
+
| `batch_audit(urls, api_key)` | Audit up to 10 URLs in one call (paid) |
|
|
49
|
+
| `compare(urls, api_key)` | Compare 2–5 URLs with a structured diff (Basic+) |
|
|
50
|
+
| `competitive_audit(url, competitor_url, keyword, api_key)` | Head-to-head audit with gap score (Pro+) |
|
|
51
|
+
| `history(url, api_key, limit=100, since=None)` | Full audit timeseries + summary for a URL (Starter+) |
|
|
52
|
+
| `history_domains(api_key)` | Every domain audited by this key with latest score and 30-day trend (Starter+) |
|
|
53
|
+
| `usage(api_key)` | Check usage and limits |
|
|
54
|
+
| `add_monitor(url, api_key, frequency="daily", webhook_url=None, alert_threshold=5)` | Set up score monitoring with optional Slack/webhook alerts (paid) |
|
|
55
|
+
| `list_monitors(api_key)` | List active monitors |
|
|
56
|
+
| `remove_monitor(url, api_key)` | Remove a monitor |
|
|
57
|
+
| `scoreboard_opt_out(api_key, opt_out=True)` | Opt in or out of the public scoreboard |
|
|
58
|
+
| `report_url(domain)` | Get shareable report URL |
|
|
59
|
+
| `accessibility_audit(url, api_key, include=None)` | ADA / WCAG 2.1 AA audit (paid; own monthly allowance). `include="trackers"` adds the tracker inventory |
|
|
60
|
+
| `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 |
|
|
61
|
+
| `ai_readability(url, api_key)` | How well AI/LLM systems can consume the page |
|
|
62
|
+
| `trackers(url, api_key)` | Third-party trackers and pixels the page loads |
|
|
63
|
+
| `conversion(url, api_key, page_type=None)` | Conversion score: headline, CTA, trust, forms, objections |
|
|
64
|
+
| `quick_wins(api_key, rows=None, csv=None, **options)` | Page-2 quick wins from your own Search Console export (every plan) |
|
|
65
|
+
| `backlinks(domain, api_key, limit=50)` | Observed backlinks, an audit-fed sample (Basic+) |
|
|
66
|
+
| `generate_llms_txt(domain, api_key=None)` | llms.txt for a domain; returns `str`. Curated version on Basic+ |
|
|
67
|
+
| `geo_audit(url, api_key)` | GEO audit: visibility to LLMs (Basic+) |
|
|
68
|
+
| `geo_brand_probe(brand, domain, prompts, api_key, models=None, runs_per_prompt=None)` | How often LLMs mention your brand (Basic+) |
|
|
69
|
+
| `add_geo_monitor(url, api_key, frequency="weekly", alert_threshold=-5, webhook_url=None)` | Create a GEO monitor (Basic+) |
|
|
70
|
+
| `list_geo_monitors(api_key)` / `remove_geo_monitor(url, api_key)` | List / remove GEO monitors |
|
|
71
|
+
| `geo_monitor_history(monitor_id, api_key, page=1, per_page=20)` | Score history for a GEO monitor |
|
|
72
|
+
| `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) |
|
|
73
|
+
| `wait_for_crawl(job_id, api_key, ...)` / `crawl(url, api_key, max_pages=None, ...)` | Poll a crawl to completion / start one and wait |
|
|
74
|
+
| `citation_starter_prompts(topic, api_key, ...)` / `citation_suggest_prompts(domain, api_key)` | Prompts to track for AI citations (not metered) |
|
|
75
|
+
| `create_citation_tracker(brand, api_key, **fields)` | Track a brand in AI answers (Starter+) |
|
|
76
|
+
| `list_citation_trackers(api_key)` / `get_citation_tracker(id, api_key)` | Trackers plus the month's check usage / one tracker |
|
|
77
|
+
| `update_citation_tracker(id, api_key, **fields)` / `delete_citation_tracker(id, api_key)` | Edit / stop a tracker |
|
|
78
|
+
| `run_citation_tracker(id, api_key)` / `get_citation_run(run_id, api_key)` | Run a tracker now / read a run's results |
|
|
79
|
+
| `citation_tracker_history(id, api_key, days=90)` | Mention rate, citation rate, share of voice, position over time |
|
|
80
|
+
| `citation_check(brand, prompt, api_key, **fields)` | One-off citation check, metered per check (paid) |
|
|
81
|
+
| `citation_topups(api_key)` / `citation_topup_checkout(pack, api_key)` | Top-up packs and balance / Stripe Checkout URL for a pack |
|
|
82
|
+
| `citation_auto_reload(api_key)` | Read the auto-reload setting (read-only; change it on the dashboard) |
|
|
83
|
+
|
|
84
|
+
Errors are `requests.HTTPError` (from `raise_for_status()`); the API's message is in
|
|
85
|
+
`err.response.json()["detail"]`.
|
|
86
|
+
|
|
87
|
+
## Historical tracking
|
|
88
|
+
|
|
89
|
+
Every audit on a paid plan returns a `history` block on the `/audit` response:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
result = audit("https://example.com", api_key=key)
|
|
93
|
+
delta = result["history"].get("delta")
|
|
94
|
+
if delta:
|
|
95
|
+
print(f"Score change: {delta['score']:+.1f} ({delta.get('grade_change') or 'no grade change'})")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
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.
|
|
99
|
+
|
|
100
|
+
## Webhook alerts on score drops
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
add_monitor(
|
|
104
|
+
"https://example.com",
|
|
105
|
+
api_key=key,
|
|
106
|
+
frequency="daily",
|
|
107
|
+
webhook_url="https://hooks.slack.com/services/T0/B0/xxxx",
|
|
108
|
+
alert_threshold=5,
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Slack incoming-webhook URLs are auto-formatted as Block Kit messages; any other https endpoint receives the raw event JSON.
|
|
113
|
+
|
|
114
|
+
## Accessibility audit and report files
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
import seoscoreapi as seo
|
|
118
|
+
|
|
119
|
+
ada = seo.accessibility_audit("https://example.com", API_KEY)
|
|
120
|
+
print(ada["score"], len(ada["violations"]))
|
|
121
|
+
|
|
122
|
+
# PDF, Markdown ("md") or CSV. Returns the file's bytes.
|
|
123
|
+
pdf = seo.audit_export("https://example.com", API_KEY, "pdf", brand_name="Acme Agency")
|
|
124
|
+
open("report.pdf", "wb").write(pdf)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
ADA audits are on paid plans and have their own monthly allowance, separate from the
|
|
128
|
+
audit quota (`usage()` reports `ada_remaining`). `audit_export` counts as one audit; the
|
|
129
|
+
white-label parameters need Pro or Ultra.
|
|
130
|
+
|
|
131
|
+
## Site crawl
|
|
132
|
+
|
|
133
|
+
Asynchronous, like Deep Site Audit. Pro and Ultra include crawls; any other plan spends
|
|
134
|
+
one Deep Audit credit per crawl.
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
job = seo.crawl("https://example.com", API_KEY, max_pages=25,
|
|
138
|
+
on_progress=lambda j: print(j["status"], j.get("pages_done")))
|
|
139
|
+
print(job["result"]["summary"], job["site_map"])
|
|
140
|
+
|
|
141
|
+
# Or drive it yourself:
|
|
142
|
+
started = seo.start_crawl("https://example.com", API_KEY) # POST /crawl
|
|
143
|
+
job = seo.get_crawl(started["job_id"], API_KEY) # GET /crawl/{job_id}
|
|
144
|
+
job = seo.wait_for_crawl(started["job_id"], API_KEY, timeout=600)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`wait_for_crawl` and `crawl` return the whole completed job (`result`, `site_map`,
|
|
148
|
+
`pages_done`), raise `TimeoutError` on timeout and `RuntimeError` if the crawl fails.
|
|
149
|
+
|
|
150
|
+
## AI citations
|
|
151
|
+
|
|
152
|
+
Do ChatGPT, Gemini, Perplexity and Claude mention and cite you? A tracker is a brand plus
|
|
153
|
+
the prompts buyers type. A check is one prompt on one engine, sampled once.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
starter = seo.citation_starter_prompts("SEO audit API", API_KEY, brand="Acme",
|
|
157
|
+
competitors=["Rival"], audience="marketing agencies")
|
|
158
|
+
|
|
159
|
+
tracker = seo.create_citation_tracker("Acme", API_KEY, domains=["acme.com"],
|
|
160
|
+
prompts=starter["prompts"], cadence="weekly")
|
|
161
|
+
run = seo.run_citation_tracker(tracker["id"], API_KEY) # waits for the engines
|
|
162
|
+
history = seo.citation_tracker_history(tracker["id"], API_KEY, days=90)
|
|
163
|
+
|
|
164
|
+
seo.list_citation_trackers(API_KEY)["usage"] # checks_limit, checks_used, checks_available, ...
|
|
165
|
+
seo.citation_topups(API_KEY) # packs, balance, can_buy
|
|
166
|
+
url = seo.citation_topup_checkout("500", API_KEY) # Stripe Checkout URL; nothing is charged until it is paid
|
|
167
|
+
seo.citation_auto_reload(API_KEY) # read-only
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
A run needs all of its checks up front (the month's allowance plus any top-up balance);
|
|
171
|
+
if that is short the API answers 429 and nothing is spent. Auto-reload can only be turned
|
|
172
|
+
on or changed from the dashboard, never with an API key, so this client has no setter.
|
|
173
|
+
|
|
174
|
+
## Search Console quick wins
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
wins = seo.quick_wins(API_KEY, csv=open("Queries.csv").read(), exclude_terms=["acme"])
|
|
178
|
+
for w in wins["quick_wins"]:
|
|
179
|
+
print(w["query"], w["position"], w["estimated_extra_clicks"])
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
We do not connect to your Search Console: you send the export (or `rows=[...]`).
|
|
183
|
+
|
|
184
|
+
## Deep Site Audit (Pro/Ultra, or credits)
|
|
185
|
+
|
|
186
|
+
A deep, AI-assisted audit scoring a URL across 9 dimensions (thousands of catalog
|
|
187
|
+
checks plus up to 150 AI checks). It runs asynchronously, so start a job and poll it,
|
|
188
|
+
or use `deep_audit` to block for the result:
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
import seoscoreapi as seo
|
|
192
|
+
|
|
193
|
+
# One call, waits for the result (handles the queue + backpressure for you):
|
|
194
|
+
result = seo.deep_audit(
|
|
195
|
+
"https://yoursite.com", API_KEY,
|
|
196
|
+
business_type="saas", # tunes which checks apply
|
|
197
|
+
on_progress=lambda s: print(s["status"], s.get("queue_position", s.get("progress"))),
|
|
198
|
+
)
|
|
199
|
+
print(result["scores"]["lai_score"], result["scores"]["section_scores"])
|
|
200
|
+
|
|
201
|
+
# Or drive the job yourself:
|
|
202
|
+
job = seo.site_audit("https://yoursite.com", API_KEY) # POST /site-audit
|
|
203
|
+
status = seo.get_site_audit(job["job_id"], API_KEY) # GET /site-audit/{job_id}
|
|
204
|
+
# status["status"] -> queued | running | completed | failed
|
|
205
|
+
# queued -> {"queue_position", "eta_seconds"}
|
|
206
|
+
# completed -> {"result"}
|
|
207
|
+
result = seo.wait_for_site_audit(job["job_id"], API_KEY, timeout=600)
|
|
208
|
+
|
|
209
|
+
seo.deep_audit_usage(API_KEY) # GET /deep-audit/usage -> {"site_audit": {"used", "remaining"}, ...}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Deep audits are included on **Pro** ($39/mo, 20/mo) and **Ultra** ($99/mo, 100/mo);
|
|
213
|
+
any other key can run them on purchased credits.
|
|
214
|
+
|
|
215
|
+
Since 1.5.0 the SDK calls the main host, `https://seoscoreapi.com`, like every other
|
|
216
|
+
endpoint. To point Deep Audit somewhere else (a proxy, staging, or the legacy
|
|
217
|
+
`engine.seoscoreapi.com` host, which still works), pass `base_url=` to any Deep Audit
|
|
218
|
+
function, assign `seoscoreapi.DEEP_AUDIT_URL`, or set `SEOSCORE_DEEP_AUDIT_URL`.
|
|
219
|
+
`engine_usage()` is kept as an alias of `deep_audit_usage()`.
|
|
220
|
+
|
|
221
|
+
Docs: [seoscoreapi.com/docs](https://seoscoreapi.com/docs) (Deep Site Audit section).
|
|
222
|
+
|
|
223
|
+
## Full Documentation
|
|
224
|
+
|
|
225
|
+
[seoscoreapi.com/docs](https://seoscoreapi.com/docs)
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# seoscoreapi
|
|
2
|
+
|
|
3
|
+
Python client for [SEO Score API](https://seoscoreapi.com) — audit any URL for SEO issues with one function call.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install seoscoreapi
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from seoscoreapi import audit, signup
|
|
15
|
+
|
|
16
|
+
# Get a free API key (2 audits/day, no credit card)
|
|
17
|
+
key = signup("you@example.com")
|
|
18
|
+
|
|
19
|
+
# Run an audit
|
|
20
|
+
result = audit("https://example.com", api_key=key)
|
|
21
|
+
print(f"Score: {result['score']}/100 ({result['grade']})")
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Functions
|
|
25
|
+
|
|
26
|
+
| Function | Description |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `signup(email)` | Get a free API key |
|
|
29
|
+
| `audit(url, api_key)` | Run SEO audit on a URL |
|
|
30
|
+
| `batch_audit(urls, api_key)` | Audit up to 10 URLs in one call (paid) |
|
|
31
|
+
| `compare(urls, api_key)` | Compare 2–5 URLs with a structured diff (Basic+) |
|
|
32
|
+
| `competitive_audit(url, competitor_url, keyword, api_key)` | Head-to-head audit with gap score (Pro+) |
|
|
33
|
+
| `history(url, api_key, limit=100, since=None)` | Full audit timeseries + summary for a URL (Starter+) |
|
|
34
|
+
| `history_domains(api_key)` | Every domain audited by this key with latest score and 30-day trend (Starter+) |
|
|
35
|
+
| `usage(api_key)` | Check usage and limits |
|
|
36
|
+
| `add_monitor(url, api_key, frequency="daily", webhook_url=None, alert_threshold=5)` | Set up score monitoring with optional Slack/webhook alerts (paid) |
|
|
37
|
+
| `list_monitors(api_key)` | List active monitors |
|
|
38
|
+
| `remove_monitor(url, api_key)` | Remove a monitor |
|
|
39
|
+
| `scoreboard_opt_out(api_key, opt_out=True)` | Opt in or out of the public scoreboard |
|
|
40
|
+
| `report_url(domain)` | Get shareable report URL |
|
|
41
|
+
| `accessibility_audit(url, api_key, include=None)` | ADA / WCAG 2.1 AA audit (paid; own monthly allowance). `include="trackers"` adds the tracker inventory |
|
|
42
|
+
| `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 |
|
|
43
|
+
| `ai_readability(url, api_key)` | How well AI/LLM systems can consume the page |
|
|
44
|
+
| `trackers(url, api_key)` | Third-party trackers and pixels the page loads |
|
|
45
|
+
| `conversion(url, api_key, page_type=None)` | Conversion score: headline, CTA, trust, forms, objections |
|
|
46
|
+
| `quick_wins(api_key, rows=None, csv=None, **options)` | Page-2 quick wins from your own Search Console export (every plan) |
|
|
47
|
+
| `backlinks(domain, api_key, limit=50)` | Observed backlinks, an audit-fed sample (Basic+) |
|
|
48
|
+
| `generate_llms_txt(domain, api_key=None)` | llms.txt for a domain; returns `str`. Curated version on Basic+ |
|
|
49
|
+
| `geo_audit(url, api_key)` | GEO audit: visibility to LLMs (Basic+) |
|
|
50
|
+
| `geo_brand_probe(brand, domain, prompts, api_key, models=None, runs_per_prompt=None)` | How often LLMs mention your brand (Basic+) |
|
|
51
|
+
| `add_geo_monitor(url, api_key, frequency="weekly", alert_threshold=-5, webhook_url=None)` | Create a GEO monitor (Basic+) |
|
|
52
|
+
| `list_geo_monitors(api_key)` / `remove_geo_monitor(url, api_key)` | List / remove GEO monitors |
|
|
53
|
+
| `geo_monitor_history(monitor_id, api_key, page=1, per_page=20)` | Score history for a GEO monitor |
|
|
54
|
+
| `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) |
|
|
55
|
+
| `wait_for_crawl(job_id, api_key, ...)` / `crawl(url, api_key, max_pages=None, ...)` | Poll a crawl to completion / start one and wait |
|
|
56
|
+
| `citation_starter_prompts(topic, api_key, ...)` / `citation_suggest_prompts(domain, api_key)` | Prompts to track for AI citations (not metered) |
|
|
57
|
+
| `create_citation_tracker(brand, api_key, **fields)` | Track a brand in AI answers (Starter+) |
|
|
58
|
+
| `list_citation_trackers(api_key)` / `get_citation_tracker(id, api_key)` | Trackers plus the month's check usage / one tracker |
|
|
59
|
+
| `update_citation_tracker(id, api_key, **fields)` / `delete_citation_tracker(id, api_key)` | Edit / stop a tracker |
|
|
60
|
+
| `run_citation_tracker(id, api_key)` / `get_citation_run(run_id, api_key)` | Run a tracker now / read a run's results |
|
|
61
|
+
| `citation_tracker_history(id, api_key, days=90)` | Mention rate, citation rate, share of voice, position over time |
|
|
62
|
+
| `citation_check(brand, prompt, api_key, **fields)` | One-off citation check, metered per check (paid) |
|
|
63
|
+
| `citation_topups(api_key)` / `citation_topup_checkout(pack, api_key)` | Top-up packs and balance / Stripe Checkout URL for a pack |
|
|
64
|
+
| `citation_auto_reload(api_key)` | Read the auto-reload setting (read-only; change it on the dashboard) |
|
|
65
|
+
|
|
66
|
+
Errors are `requests.HTTPError` (from `raise_for_status()`); the API's message is in
|
|
67
|
+
`err.response.json()["detail"]`.
|
|
68
|
+
|
|
69
|
+
## Historical tracking
|
|
70
|
+
|
|
71
|
+
Every audit on a paid plan returns a `history` block on the `/audit` response:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
result = audit("https://example.com", api_key=key)
|
|
75
|
+
delta = result["history"].get("delta")
|
|
76
|
+
if delta:
|
|
77
|
+
print(f"Score change: {delta['score']:+.1f} ({delta.get('grade_change') or 'no grade change'})")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
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.
|
|
81
|
+
|
|
82
|
+
## Webhook alerts on score drops
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
add_monitor(
|
|
86
|
+
"https://example.com",
|
|
87
|
+
api_key=key,
|
|
88
|
+
frequency="daily",
|
|
89
|
+
webhook_url="https://hooks.slack.com/services/T0/B0/xxxx",
|
|
90
|
+
alert_threshold=5,
|
|
91
|
+
)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Slack incoming-webhook URLs are auto-formatted as Block Kit messages; any other https endpoint receives the raw event JSON.
|
|
95
|
+
|
|
96
|
+
## Accessibility audit and report files
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
import seoscoreapi as seo
|
|
100
|
+
|
|
101
|
+
ada = seo.accessibility_audit("https://example.com", API_KEY)
|
|
102
|
+
print(ada["score"], len(ada["violations"]))
|
|
103
|
+
|
|
104
|
+
# PDF, Markdown ("md") or CSV. Returns the file's bytes.
|
|
105
|
+
pdf = seo.audit_export("https://example.com", API_KEY, "pdf", brand_name="Acme Agency")
|
|
106
|
+
open("report.pdf", "wb").write(pdf)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
ADA audits are on paid plans and have their own monthly allowance, separate from the
|
|
110
|
+
audit quota (`usage()` reports `ada_remaining`). `audit_export` counts as one audit; the
|
|
111
|
+
white-label parameters need Pro or Ultra.
|
|
112
|
+
|
|
113
|
+
## Site crawl
|
|
114
|
+
|
|
115
|
+
Asynchronous, like Deep Site Audit. Pro and Ultra include crawls; any other plan spends
|
|
116
|
+
one Deep Audit credit per crawl.
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
job = seo.crawl("https://example.com", API_KEY, max_pages=25,
|
|
120
|
+
on_progress=lambda j: print(j["status"], j.get("pages_done")))
|
|
121
|
+
print(job["result"]["summary"], job["site_map"])
|
|
122
|
+
|
|
123
|
+
# Or drive it yourself:
|
|
124
|
+
started = seo.start_crawl("https://example.com", API_KEY) # POST /crawl
|
|
125
|
+
job = seo.get_crawl(started["job_id"], API_KEY) # GET /crawl/{job_id}
|
|
126
|
+
job = seo.wait_for_crawl(started["job_id"], API_KEY, timeout=600)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`wait_for_crawl` and `crawl` return the whole completed job (`result`, `site_map`,
|
|
130
|
+
`pages_done`), raise `TimeoutError` on timeout and `RuntimeError` if the crawl fails.
|
|
131
|
+
|
|
132
|
+
## AI citations
|
|
133
|
+
|
|
134
|
+
Do ChatGPT, Gemini, Perplexity and Claude mention and cite you? A tracker is a brand plus
|
|
135
|
+
the prompts buyers type. A check is one prompt on one engine, sampled once.
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
starter = seo.citation_starter_prompts("SEO audit API", API_KEY, brand="Acme",
|
|
139
|
+
competitors=["Rival"], audience="marketing agencies")
|
|
140
|
+
|
|
141
|
+
tracker = seo.create_citation_tracker("Acme", API_KEY, domains=["acme.com"],
|
|
142
|
+
prompts=starter["prompts"], cadence="weekly")
|
|
143
|
+
run = seo.run_citation_tracker(tracker["id"], API_KEY) # waits for the engines
|
|
144
|
+
history = seo.citation_tracker_history(tracker["id"], API_KEY, days=90)
|
|
145
|
+
|
|
146
|
+
seo.list_citation_trackers(API_KEY)["usage"] # checks_limit, checks_used, checks_available, ...
|
|
147
|
+
seo.citation_topups(API_KEY) # packs, balance, can_buy
|
|
148
|
+
url = seo.citation_topup_checkout("500", API_KEY) # Stripe Checkout URL; nothing is charged until it is paid
|
|
149
|
+
seo.citation_auto_reload(API_KEY) # read-only
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
A run needs all of its checks up front (the month's allowance plus any top-up balance);
|
|
153
|
+
if that is short the API answers 429 and nothing is spent. Auto-reload can only be turned
|
|
154
|
+
on or changed from the dashboard, never with an API key, so this client has no setter.
|
|
155
|
+
|
|
156
|
+
## Search Console quick wins
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
wins = seo.quick_wins(API_KEY, csv=open("Queries.csv").read(), exclude_terms=["acme"])
|
|
160
|
+
for w in wins["quick_wins"]:
|
|
161
|
+
print(w["query"], w["position"], w["estimated_extra_clicks"])
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
We do not connect to your Search Console: you send the export (or `rows=[...]`).
|
|
165
|
+
|
|
166
|
+
## Deep Site Audit (Pro/Ultra, or credits)
|
|
167
|
+
|
|
168
|
+
A deep, AI-assisted audit scoring a URL across 9 dimensions (thousands of catalog
|
|
169
|
+
checks plus up to 150 AI checks). It runs asynchronously, so start a job and poll it,
|
|
170
|
+
or use `deep_audit` to block for the result:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
import seoscoreapi as seo
|
|
174
|
+
|
|
175
|
+
# One call, waits for the result (handles the queue + backpressure for you):
|
|
176
|
+
result = seo.deep_audit(
|
|
177
|
+
"https://yoursite.com", API_KEY,
|
|
178
|
+
business_type="saas", # tunes which checks apply
|
|
179
|
+
on_progress=lambda s: print(s["status"], s.get("queue_position", s.get("progress"))),
|
|
180
|
+
)
|
|
181
|
+
print(result["scores"]["lai_score"], result["scores"]["section_scores"])
|
|
182
|
+
|
|
183
|
+
# Or drive the job yourself:
|
|
184
|
+
job = seo.site_audit("https://yoursite.com", API_KEY) # POST /site-audit
|
|
185
|
+
status = seo.get_site_audit(job["job_id"], API_KEY) # GET /site-audit/{job_id}
|
|
186
|
+
# status["status"] -> queued | running | completed | failed
|
|
187
|
+
# queued -> {"queue_position", "eta_seconds"}
|
|
188
|
+
# completed -> {"result"}
|
|
189
|
+
result = seo.wait_for_site_audit(job["job_id"], API_KEY, timeout=600)
|
|
190
|
+
|
|
191
|
+
seo.deep_audit_usage(API_KEY) # GET /deep-audit/usage -> {"site_audit": {"used", "remaining"}, ...}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Deep audits are included on **Pro** ($39/mo, 20/mo) and **Ultra** ($99/mo, 100/mo);
|
|
195
|
+
any other key can run them on purchased credits.
|
|
196
|
+
|
|
197
|
+
Since 1.5.0 the SDK calls the main host, `https://seoscoreapi.com`, like every other
|
|
198
|
+
endpoint. To point Deep Audit somewhere else (a proxy, staging, or the legacy
|
|
199
|
+
`engine.seoscoreapi.com` host, which still works), pass `base_url=` to any Deep Audit
|
|
200
|
+
function, assign `seoscoreapi.DEEP_AUDIT_URL`, or set `SEOSCORE_DEEP_AUDIT_URL`.
|
|
201
|
+
`engine_usage()` is kept as an alias of `deep_audit_usage()`.
|
|
202
|
+
|
|
203
|
+
Docs: [seoscoreapi.com/docs](https://seoscoreapi.com/docs) (Deep Site Audit section).
|
|
204
|
+
|
|
205
|
+
## Full Documentation
|
|
206
|
+
|
|
207
|
+
[seoscoreapi.com/docs](https://seoscoreapi.com/docs)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "seoscoreapi"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.6.0"
|
|
8
8
|
description = "Python client for SEO Score API — audit any URL for SEO issues with one function call"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|