The Python client for SEO Score API hit 1.3.0 today. It picks up everything we shipped through the latest sprint: side-by-side URL comparison, the /history and /history/domains endpoints, and webhook alerts (Slack-formatted by default) on the monitor system.
If you already have seoscoreapi installed, upgrade with:
pip install --upgrade seoscoreapi
Then the rest of this post is a tour of what the new functions actually do.
What's in 1.3
| Function | Endpoint | Tier |
|---|---|---|
compare(urls, api_key) |
POST /compare |
Basic+ |
history(url, api_key, limit=100, since=None) |
GET /history |
Starter+ |
history_domains(api_key) |
GET /history/domains |
Starter+ |
add_monitor(..., webhook_url, alert_threshold) |
POST /monitors |
Paid |
competitive_audit() and report_url() were already in 1.2 — they're listed here for completeness because they pair well with the new history functions.
1. Compare your page against competitors in one call
Before 1.3, doing a head-to-head comparison meant calling /audit for each URL and computing diffs yourself. Now compare() does it server-side and returns a structured diff block:
import os
from seoscoreapi import compare
result = compare(
[
"https://acme.com/pricing",
"https://competitor-a.com/pricing",
"https://competitor-b.com/pricing",
],
api_key=os.environ["SEOSCORE_API_KEY"],
)
for url_data in result["urls"]:
print(f"{url_data['url']}: {url_data['score']} ({url_data['grade']})")
print("\nGap analysis:")
for entry in result["diff"]["category_gaps"]:
print(f" {entry['category']}: leader is {entry['leader']} (+{entry['gap']:.1f})")
compare() accepts 2–5 URLs in a single request and returns each URL's full audit, plus the diff object that tells you who is ahead in every category. It's Basic plan ($15/mo) and up.
This is the hook agency people have been asking for — drop it into a Streamlit or Slack-bot and you've got a "where do we stand against the top 3 competitors?" tool in 30 lines.
2. Pull the full audit history for any URL
If you've been auditing a URL on a paid plan, every audit's score breakdown is already in our database. history() returns the full timeseries plus a summary block:
from seoscoreapi import history
data = history("https://acme.com", api_key=os.environ["SEOSCORE_API_KEY"])
print(f"Tracked: {data['count']} audits")
print(f" First: {data['summary']['first_score']}")
print(f" Latest: {data['summary']['latest_score']}")
print(f" Total delta: {data['summary']['total_delta']:+.1f}")
print(f" Min/Max: {data['summary']['min_score']}/{data['summary']['max_score']}")
# Plot it
import matplotlib.pyplot as plt
ts = [p["timestamp"] for p in data["history"]]
scores = [p["score"] for p in data["history"]]
plt.plot(ts, scores)
plt.savefig("acme-trend.png")
history() accepts limit and since parameters if you want to scope the response. The retention windows are tied to your tier:
| Plan | Retention |
|---|---|
| Starter ($5/mo) | 30 days |
| Basic ($15/mo) | 90 days |
| Pro ($39/mo) | 1 year |
| Ultra ($99/mo) | Unlimited |
For a deeper write-up on what's in the history block, see the historical comparison post.
3. Get a one-shot view of every domain you track
history_domains() is the "all your stuff at a glance" call:
from seoscoreapi import history_domains
domains = history_domains(api_key=os.environ["SEOSCORE_API_KEY"])
# Sort by 30-day trend, worst first
domains.sort(key=lambda d: d.get("trend_30d", 0))
for d in domains[:10]:
arrow = "↓" if d.get("trend_30d", 0) < 0 else "↑"
print(f"{d['domain']:40} {d['latest_score']:>3} {arrow}{abs(d.get('trend_30d', 0)):.1f}")
One call, one row per domain you've ever audited. Use it for an agency-wide "who needs attention this week?" dashboard or a Slack digest.
4. Get alerted in Slack when a score drops
add_monitor() now takes webhook_url and alert_threshold. If the webhook URL is a Slack incoming-webhook, the payload is auto-formatted as Block Kit:
from seoscoreapi import add_monitor
add_monitor(
"https://acme.com",
api_key=os.environ["SEOSCORE_API_KEY"],
frequency="daily",
webhook_url="https://hooks.slack.com/services/T0/B0/xxxx",
alert_threshold=5, # alert when the score drops 5+ points
)
A 5-point drop on Acme's homepage now pings your #seo-alerts channel within minutes of the next scheduled audit run. Other https endpoints get the raw event JSON, so you can route alerts into PagerDuty, Discord, your own SIEM — anything that takes a webhook.
The alert_threshold is in score points, not percent. Five points is a reasonable starting value: small enough to catch real regressions, large enough to ignore the kind of noise that comes from a slow Core Web Vitals reading on a single audit.
A complete worked example: the 30-line agency monitor
Putting it together, here's the entire script we run for a small in-house team. It uses every new function in 1.3:
import os
from seoscoreapi import history_domains, history, compare
API_KEY = os.environ["SEOSCORE_API_KEY"]
# 1. Find URLs that dropped 2+ points this month
domains = history_domains(API_KEY)
dropped = [d for d in domains if d.get("trend_30d", 0) <= -2.0]
dropped.sort(key=lambda d: d["trend_30d"])
print(f"## {len(dropped)} URLs to investigate\n")
# 2. For each, pull the timeseries to see when the drop happened
for d in dropped[:5]:
h = history(f"https://{d['domain']}", API_KEY, limit=20)
points = h["history"][-5:]
print(f"### {d['domain']}")
for p in points:
print(f" {int(p['timestamp'])}: {p['score']}")
# 3. Compare your worst one against two competitors
worst = dropped[0]
result = compare(
[
f"https://{worst['domain']}",
"https://competitor-a.com",
"https://competitor-b.com",
],
API_KEY,
)
for u in result["urls"]:
print(f"\n{u['url']}: {u['score']} ({u['grade']})")
That's a daily report that used to take a half-day in spreadsheets, in 30 lines, billable as a fixed-price retainer add-on. The full SDK reference is in the README and the auto-generated API docs.
Upgrading from 1.2
Nothing breaks. add_monitor() gets two new optional kwargs, but every existing call works as-is. The new functions (compare, history, history_domains) were either new in this release or added in 1.2 — if you've been on 1.2 already, this is a strict additive update.
pip install --upgrade seoscoreapi
If you don't have a key yet, grab a free one or start on Starter for $5/mo to get historical tracking on day one.