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.