example

Find backlink donors

Mine competitors' referring domains into a ranked candidate list for vetting.

Three of these four steps are seofetch API calls with a fixed JSON envelope; the middle step runs locally against the saved responses — a few lines in whichever language you're reading this in, just narrowing competitors' donor lists down to the domains they share.

language
prerequisites

Export your key once.

$ setupcurl
export SEOFETCH_KEY=sof_live_…
# the scripts below use jq -- brew install jq / apt-get install jq
step 1

Pull the referring domains for each of 2–3 competitors.

→ requestcurl
curl https://api.seofetch.com/v1/backlinks/domains \
  -H "Authorization: Bearer $SEOFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target": "competitor1.com", "limit": 100, "offset": 0}' \
  -o comp1.json
← response200
{
  "id": "refe_spkai6b7z5fioovpnu5magzj",
  "request_id": "req_6majcv6pmjecnfgzvgjfrr4zoe",
  "object": "referring_domains",
  "created_at": "2026-08-09T09:58:37Z",
  "elapsed_ms": 180,
  "cache": "miss",
  "credits": {
    "charged": 50,
    "balance": 9857
  },
  "data": {
    "target": "competitor1.com",
    "total_count": 3160,
    "limit": 100,
    "offset": 0,
    "items": [
      {
        "domain": "caglrc.cc",
        "backlinks": 526,
        "first_seen": "2023-11-02",
        "lost_at": null,
        "authority": 27,
        "spam_score": 0
      },
      "…"
    ]
  }
}

Run it once per competitor (50 credits each) and save each response to a file. You get the first 100 domains per call — check total_count and page with offset if you want the rest.

step 2

Intersect the lists — a domain linking to two or more competitors is far likelier to be a niche linker than a one-off friend-of-the-founder link.

$ localrun locally
jq -s '[.[].data.items[].domain] | group_by(.) | map(select(length > 1) | .[0])' comp1.json comp2.json comp3.json

The intersection is your candidate list — candidates, not vetted donors. Directories and link networks intersect too; the next two steps are the filter.

step 3

Qualify each candidate before outreach: real organic footprint or not?

→ requestcurl
curl https://api.seofetch.com/v1/domains/overview \
  -H "Authorization: Bearer $SEOFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "donorsite.io", "location": 2840, "language": "en"}'
← response200
{
  "id": "doma_hixpevdimian2jkhz7k6levn",
  "request_id": "req_b3iyr66tfjcgxmpq4u3ys5pse4",
  "object": "domain_overview",
  "created_at": "2026-08-09T09:58:37Z",
  "elapsed_ms": 180,
  "cache": "miss",
  "credits": {
    "charged": 10,
    "balance": 9857
  },
  "data": {
    "organic": {
      "keywords_count": 101,
      "traffic_estimate": 70.17,
      "traffic_value": 704.38,
      "positions": {
        "top_3": 0,
        "top_10": 3,
        "top_20": 11,
        "top_100": 101
      }
    },
    "paid": {
      "keywords_count": 0,
      "traffic_estimate": 0,
      "traffic_value": 0,
      "positions": {
        "top_3": 0,
        "top_10": 0,
        "top_20": 0,
        "top_100": 0
      }
    }
  }
}

Filter by keyword count, traffic estimate, and ranking spread (10 credits per candidate) — the cheap call that decides who's worth the expensive one.

step 4

Profile the donor you're about to pitch: the anchors pointing at them sketch what they publish and what gets cited.

→ requestcurl
curl https://api.seofetch.com/v1/backlinks/anchors \
  -H "Authorization: Bearer $SEOFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target": "donorsite.io", "limit": 100, "offset": 0}'
← response200
{
  "id": "back_4m2ae2mkqavdd3rpzzftgluc",
  "request_id": "req_p7cz32xo6jbgrpfa7vygsvedva",
  "object": "backlink_anchors",
  "created_at": "2026-08-09T09:58:37Z",
  "elapsed_ms": 180,
  "cache": "miss",
  "credits": {
    "charged": 50,
    "balance": 9857
  },
  "data": {
    "target": "donorsite.io",
    "total_count": 3316,
    "limit": 100,
    "offset": 0,
    "items": [
      {
        "anchor": "running shoes",
        "backlinks": 597726,
        "referring_domains": 247,
        "first_seen": "2023-05-14"
      },
      {
        "anchor": null,
        "backlinks": 1201,
        "referring_domains": 88,
        "first_seen": "2024-01-09"
      },
      "…"
    ]
  }
}

Commercial anchors usually mean listicles and comparisons; brand anchors lean news and mentions. A signal about what to pitch, not a guarantee of the page type.

script

Run the whole thing.

Each language below is the full pipeline — swap in your competitors, run it after exporting SEOFETCH_KEY: every candidate lands in donors.csv, sorted by estimated organic traffic — a triage order, not a donor-quality score, and the anchors pull is queued up for the donor you pick.

→ rundonors.sh
#!/usr/bin/env bash
# donors.sh -- competitor referring domains -> shared candidates -> qualified list.
set -euo pipefail
: "${SEOFETCH_KEY:?export SEOFETCH_KEY first}"
COMPETITORS=("competitor1.com" "competitor2.com" "competitor3.com")   # swap in yours
api() { curl -sS --fail-with-body "https://api.seofetch.com$1" \
  -H "Authorization: Bearer $SEOFETCH_KEY" \
  -H "Content-Type: application/json" \
  -d "$2"; }

# 1. referring domains per competitor -- first 100 each; page with offset
#    toward .data.total_count when you want the full lists
i=0
for c in "${COMPETITORS[@]}"; do
  i=$((i+1))
  api /v1/backlinks/domains \
    "$(jq -cn --arg t "$c" '{target: $t, limit: 100, offset: 0}')" > "comp$i.json"
done

# 2. the intersection is the candidate list
jq -s '[.[].data.items[].domain] | group_by(.) | map(select(length > 1) | .[0])' \
  comp*.json > candidates.json

# 3. qualify every candidate: organic keywords + traffic estimate, sorted by
#    estimated organic traffic -- a triage order, not a donor-quality score
: > donors.csv
jq -r '.[]' candidates.json | while IFS= read -r d; do
  api /v1/domains/overview \
    "$(jq -cn --arg d "$d" '{domain: $d, location: 2840, language: "en"}')" > "overview-$d.json"
  jq -r --arg d "$d" \
    '[$d, (.data.organic.keywords_count // 0), (.data.organic.traffic_estimate // 0)] | @csv' \
    "overview-$d.json" >> donors.csv
done
sort -t, -k3 -rn donors.csv -o donors.csv
echo "donors.csv: domain, organic keywords, traffic estimate -- sorted by estimated organic traffic, a triage order not a donor-quality score"

# 4. before writing the pitch, see how your pick gets linked
d="donorsite.io"   # a top row of donors.csv
api /v1/backlinks/anchors \
  "$(jq -cn --arg t "$d" '{target: $t, limit: 100, offset: 0}')" > "anchors-$d.json"
jq '.data.items[:5]' "anchors-$d.json"