DEV Community

Cover image for Build a Keyword and Backlink Report in Python With an SEO API
SerpScraper.dev
SerpScraper.dev

Posted on

Build a Keyword and Backlink Report in Python With an SEO API

If you build marketing tools, you eventually need the same three numbers over and over: how many people search a keyword, what it is worth (CPC), and how strong a competitor's backlink profile is. Keyword research tools show them in a dashboard, but copying numbers out of a dashboard does not scale.

An SEO API returns the same data as JSON, so a script can fetch it on a schedule. In this post you will build a small report that:

  1. Takes a list of keywords and returns search volume and CPC for each.
  2. Takes a list of competitor domains and returns a backlink summary for each.
  3. Writes everything to CSV files you can open in a spreadsheet or feed to a dashboard.

What you need

  • Python 3 and the requests package
  • An API key, stored in the AXIOAPI_KEY environment variable (sign up from the SEO API page; new accounts receive free credits after verification)
import os
import requests

API = "https://axioapi.com/api/v1"
HEADERS = {
    "Authorization": f"Bearer {os.environ['AXIOAPI_KEY']}",
    "Accept": "application/json",
}
Enter fullscreen mode Exit fullscreen mode

Step 1: a keyword data API call

The keyword endpoint accepts up to 10 keywords and a country code, and bills once per request, so always send full batches of 10 instead of one keyword at a time.

import csv

def keyword_metrics(keywords, country="us"):
    res = requests.post(
        f"{API}/seo/keywords/metrics",
        headers=HEADERS,
        json={"keywords": keywords, "country": country},
        timeout=60,
    )
    res.raise_for_status()
    return res.json()["data"]


def batches(items, size=10):
    for i in range(0, len(items), size):
        yield items[i:i + size]


def keyword_report(keywords, path="keywords.csv", country="us"):
    rows = []
    for batch in batches(keywords):
        rows.extend(keyword_metrics(batch, country))

    rows.sort(key=lambda r: r["search_volume"] or 0, reverse=True)
    with open(path, "w", newline="") as f:
        out = csv.writer(f)
        out.writerow(["keyword", "search_volume", "cpc"])
        for r in rows:
            out.writerow([r["keyword"], r["search_volume"], r["cpc"]])
    return rows
Enter fullscreen mode Exit fullscreen mode

Two details worth knowing:

  • Volume depends on the country. Always pass the market you actually sell in.
  • Missing metrics come back empty, not guessed. That is why the sort key uses or 0. A blank volume means the data source had no figure, not that nobody searches the keyword.

A high CPC is a quick signal of commercial intent, which helps when you pick between two keywords with similar volume.

Step 2: a backlink API call for competitors

Next, a backlink summary for each competitor. The response lists the figures of every data source that answered and says which ones did not, so you can tell a complete result from a partial one.

def backlink_summary(domain):
    res = requests.get(
        f"{API}/seo/domains/{domain}/backlinks",
        headers=HEADERS,
        timeout=60,
    )
    res.raise_for_status()
    return res.json()["data"]


def backlink_report(domains, path="backlinks.csv"):
    with open(path, "w", newline="") as f:
        out = csv.writer(f)
        out.writerow(["domain", "source", "metrics", "partial", "missing_sources"])
        for domain in domains:
            data = backlink_summary(domain)
            missing = ",".join(data["missing"])
            for source, metrics in data["sources"].items():
                out.writerow([domain, source, metrics, data["partial"], missing])
Enter fullscreen mode Exit fullscreen mode

Writing one row per source keeps the disagreement between sources visible. Backlink counts are estimates and different crawlers will not agree, so treat them as a way to compare sites, not as exact totals.

Step 3: run it

if __name__ == "__main__":
    keyword_report(
        ["seo api", "backlink checker", "keyword research tool", "domain authority"],
        country="us",
    )
    backlink_report(["example.com", "competitor.com"])
    print("Wrote keywords.csv and backlinks.csv")
Enter fullscreen mode Exit fullscreen mode

Run it with python report.py, and put it in a cron job or a scheduled CI workflow to get a fresh CSV every week.

Make it a recurring domain report

A one-off CSV answers "where do we stand today". To answer "are we growing", add the domain overview and 12 months of history for the same domain:

def get(path, **params):
    res = requests.get(f"{API}{path}", headers=HEADERS, params=params, timeout=60)
    res.raise_for_status()
    return res.json()["data"]


def domain_report(domain):
    overview = get(f"/seo/domains/{domain}", country="US")
    backlinks = get(f"/seo/domains/{domain}/backlinks")
    history = get(f"/seo/domains/{domain}/history", months=12)
    return {
        "domain": domain,
        "history": history,
        "incomplete": overview["partial"] or backlinks["partial"],
        "missing_sources": sorted(set(overview["missing"]) | set(backlinks["missing"])),
    }
Enter fullscreen mode Exit fullscreen mode

Store each run (a JSON file, SQLite, or a spreadsheet tab) and compare it with the previous one. Flag any run where incomplete is true instead of silently charting partial data. There is a longer walkthrough in the SEO report API guide and a focused one on pulling search volume and CPC in code.

Keep it reliable and cheap

  • Batch keywords. 10 per call is the maximum, and it is billed once per call.
  • Cache results. Search volume moves slowly. Re-fetching the same keyword daily wastes credits, weekly is plenty.
  • Handle partial data. If partial is true, retry later or note the gap in your report.
  • Respect the data. These are third-party estimates. Do not promise a client an exact number.

When this approach is a good fit, and when it is not

It fits when you want keyword and link data inside your own product or script: an internal dashboard, a client report generator, a content planning tool, or a quick competitor check.

It is not a replacement for everything. There are no live SERP, rank tracking or local pack endpoints, so if you need those, a SERP-focused provider is the better choice. I wrote a plain comparison here: an SEO API alternative to DataForSEO and Semrush.

If you only need to check one domain by hand, the free backlink checker needs no code and no account for a few runs per day.

Wrap-up

An SEO API turns keyword research and backlink checks into something you can schedule, version and test like any other code. The script above is about 60 lines and covers the three numbers most marketing tools need.

If you build something with it, tell me in the comments what you would add: rank history, content gap analysis, or alerts when a competitor gains links. Full endpoint list and prices are on the SEO API page.

Top comments (0)