SEO data that powers your tools.

One API for search and AI visibility data — rankings, keywords, backlinks, and citations. 100TBs of data at your disposal.

No credit card required · Start with 1,500 free credits.

$ curl api.seofetch.com/v1/search -d '{"query": "best running shoes"}'

← response200 · 1 credit
{
  "object": "search",
  "credits": { "charged": 1, "balance": 9857 },
  "data": {
    "query": "best running shoes",
    "total_results": 84900000,
    "items": [
      {
        "rank": 1,
        "title": "The 12 Best Running Shoes",
        "url": "https://example.com/best-running-shoes",
        "site_name": "Example Running Co.",
        "rating": { "value": 4.6, "votes": 1284, "max": 5 },
        "sitelinks": [ { "title": "Best Trail Running Shoes" } ]
      }
    ]
  }
}
+9 more results ranks · titles · ratings · sitelinks 1 credit
how it works

Three commands to first data.

01

Get a key

Sign up and generate an API key from your dashboard.

$ export SEOFETCH_KEY=sof_live_…
02

Send a request

Every metered endpoint is one POST. Same envelope, same rules.

$ curl api.seofetch.com/v1/search -H "Authorization: Bearer $SEOFETCH_KEY"
03

Get normalized JSON

The same envelope on every endpoint: object, credits, data. One integration, all data types.

"credits": { "charged": 1, "balance": 9857 }
for agents

Give your coding agent the whole picture.

A short Markdown brief, built for pasting straight into an agent's context — what the API does, every endpoint and what it costs, a quickstart it can run, and one worked example. The preview below shows the shape; copy the full document into your agent and skip the docs crawl.

preview
# seofetch — SEO data API

seofetch is a REST API for SEO data — search results, keyword volume and difficulty, backlinks, domain overviews, site audits, Lighthouse performance, and more. All 19 endpoints return the same JSON envelope, so learning that shape once gets you every endpoint.

Base URL: `https://api.seofetch.com`. Authenticate every request with `Authorization: Bearer <your key>`. Get a key at `https://seofetch.com/accounts/signup/` — 1,500 free credits, no card required.

## Quick start

```bash
curl https://api.seofetch.com/v1/search \
  -H "Authorization: Bearer sof_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"query": "best running shoes"}'
```
show the full document
# seofetch — SEO data API

seofetch is a REST API for SEO data — search results, keyword volume and difficulty, backlinks, domain overviews, site audits, Lighthouse performance, and more. All 19 endpoints return the same JSON envelope, so learning that shape once gets you every endpoint.

Base URL: `https://api.seofetch.com`. Authenticate every request with `Authorization: Bearer <your key>`. Get a key at `https://seofetch.com/accounts/signup/` — 1,500 free credits, no card required.

## Quick start

```bash
curl https://api.seofetch.com/v1/search \
  -H "Authorization: Bearer sof_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"query": "best running shoes"}'
```

```json
{
  "id": "srch_tnq5objwpmflh2poczbwxnfr",
  "request_id": "req_c7leybmgtzholcwoyhozbqsqkq",
  "object": "search",
  "created_at": "2026-08-08T16:50:38Z",
  "elapsed_ms": 142,
  "cache": "miss",
  "credits": {
    "charged": 1,
    "balance": 9857
  },
  "data": {
    "query": "best running shoes",
    "engine": "google",
    "location": 2840,
    "language": "en",
    "device": "desktop",
    "total_results": 84900000,
    "serp_url": "https://www.google.com/search?q=best+running+shoes",
    "result_types": [
      "organic"
    ],
    "results_count": 10,
    "items": [
      {
        "type": "organic",
        "rank": 1,
        "page": 1,
        "domain": "example.com",
        "title": "The 12 Best Running Shoes",
        "url": "https://example.com/best-running-shoes",
        "description": "Our team tested 40 pairs...",
        "displayed_link": "example.com › reviews › shoes",
        "date": null,
        "site_name": "Example Running Co.",
        "rating": {
          "value": 4.6,
          "votes": 1284,
          "max": 5
        },
        "sitelinks": [
          {
            "type": "sitelink",
            "title": "Best Trail Running Shoes",
            "description": null,
            "url": "https://example.com/best-running-shoes/trail"
          },
          {
            "type": "sitelink",
            "title": "Best Budget Running Shoes",
            "description": null,
            "url": "https://example.com/best-running-shoes/budget"
          }
        ],
        "price": null
      }
    ]
  }
}
```

## What's possible

- `POST /v1/search` — Run one search query and get the parsed SERP back — ranked items, not raw HTML. — 1 credit at the default depth (10 results), 10 credits at depth=100.
- `POST /v1/keywords/volume` — Historical Google keyword search volume and competition metrics. — 20 credits per call.
- `POST /v1/keywords/difficulty` — Keyword difficulty (0-100) per keyword; unscored keywords return pending and are scored for a later call. — 110 credits per call.
- `POST /v1/backlinks/summary` — Backlink profile summary metrics for a domain or URL. — 20 credits per call.
- `POST /v1/backlinks/list` — Individual backlinks pointing at a domain or URL. — 50 credits per call.
- `POST /v1/backlinks/domains` — Domains that link to a target, with per-domain metrics. — 50 credits per call.
- `POST /v1/backlinks/anchors` — Anchor-text distribution of backlinks to a target. — 50 credits per call.
- `POST /v1/domains/overview` — Return a domain's organic and paid search overview for one market. — 10 credits per call.
- `POST /v1/page/lighthouse` — Lighthouse scores and core web vitals for a single page. — 2 credits per call.
- `POST /v1/page/crawl` — Render a single page and return a slim page-SEO snapshot. — 2 credits per call.
- `POST /v1/page/accessibility` — Axe accessibility scan of a single page — violations, keyboard-navigation checks, honest scan status. — 2 credits per call.
- `POST /v1/site/audit` — Crawl and audit a whole site; billed per delivered page (sum of enabled checks x pages delivered). — 2 credits per check per delivered page.
- `POST /v1/serp/history` — Position history for a (domain, keyword) pair from our SERP archive. — 5 credits per call.
- `POST /v1/domains/card` — Company card — identity, contacts, socials, technology from our crawl. — 10 credits per call.
- `POST /v1/keywords/questions` — People-Also-Ask questions observed for a topic, deduplicated. — 20 credits per call.
- `POST /v1/ai/visibility` — How often AI assistants mention a domain, per provider, over time. — 10 credits per call.
- `GET /v1/locations` — Look up Google Ads geotarget IDs by name — country, state/region, city, or neighborhood. — free, unmetered (`?q=` required).
- `POST /v1/domains/competitors` — Competitor discovery from the SERP archive: domains that rank for the same keywords, ranked by overlap. — 30 credits per call.
- `POST /v1/domains/gap` — Keyword gap between two domains: opportunity, shared, or unique rankings, volume-enriched. — 15 credits per call.

## What people use it for

- **Let an LLM pick what to optimize next** — An agent ranks your pages by winnable upside — positions, volume, difficulty, on-page gaps. (`/v1/search`, `/v1/keywords/volume`, `/v1/keywords/difficulty`, `/v1/page/crawl`)
- **Find backlink donors** — Mine competitors' referring domains into a ranked candidate list for vetting. (`/v1/backlinks/domains`, `/v1/backlinks/anchors`, `/v1/domains/overview`)
- **A rank tracker in a cron job** — Daily positions, diffed and alerted, for 1 credit per keyword per day. (`/v1/search`)
- **Fail the build when the site regresses** — Lighthouse + on-page checks on every deploy. (`/v1/page/lighthouse`, `/v1/page/crawl`, `/v1/site/audit`)
- **Find out who you're actually up against** — Competitors ranked by real keyword overlap from the SERP archive — not who you assume they are. (`/v1/domains/competitors`, `/v1/domains/overview`, `/v1/domains/gap`)
- **Find the content you're missing** — Keywords a competitor ranks for that you don't — volume-enriched, with the questions people actually ask. (`/v1/domains/gap`, `/v1/keywords/questions`, `/v1/keywords/difficulty`)
- **Vet a backlink donor before you pitch** — Spam score, authority, and the link-mix breakdown for any domain — 30 credits to skip a bad neighborhood. (`/v1/backlinks/summary`, `/v1/domains/overview`)
- **Track page performance over time** — Lighthouse scores and lab vitals in a CSV, with rank history sitting next to them. (`/v1/page/lighthouse`, `/v1/serp/history`)

## A worked example — A rank tracker in a cron job

Daily positions, diffed and alerted, for 1 credit per keyword per day.

```bash
#!/usr/bin/env bash
# tracker.sh -- daily rank tracker, cron-ready. keywords.txt: one keyword per line.
# cron: 15 6 * * *  cd /path/to/tracker && ./tracker.sh
set -euo pipefail
: "${SEOFETCH_KEY:?export SEOFETCH_KEY first}"
DOMAIN="${TRACK_DOMAIN:-yourdomain.com}"
TODAY=$(date -u +%F)
mkdir -p snapshots
OUT="snapshots/$TODAY.csv"
: > "$OUT"

while IFS= read -r kw; do
  [ -z "$kw" ] && continue
  # -w tacks the status code onto the last line.
  resp=$(curl -sS https://api.seofetch.com/v1/search \
    -H "Authorization: Bearer $SEOFETCH_KEY" \
    -H "Content-Type: application/json" \
    -d "$(jq -cn --arg q "$kw" '{query: $q}')" \
    -w $'\n%{http_code}')
  code=${resp##*$'\n'}
  body=${resp%$'\n'*}
  if [ "$code" != "200" ]; then
    # a 504 means the job kept running server-side past your connection --
    # the charge stands either way. Any non-2xx (401/429/504/500/...) is
    # never a "miss" -- skip it rather than parse the error body as data.
    echo "warning: $kw returned HTTP $code, skipping" >&2
    continue
  fi
  # "miss" = not in the returned results (top 10 at the default depth) --
  # the row survives so the diff below can see you drop out entirely
  rank=$(printf '%s' "$body" | jq -r --arg d "$DOMAIN" \
    '[.data.items[]? | select(.domain == $d) | .rank][0] // "miss"')
  printf '%s,%s\n' "$kw" "$rank" >> "$OUT"
done < keywords.txt

# diff against yesterday, alert on drops (macOS date -v / GNU date -d both handled)
PREV="snapshots/$(date -u -v-1d +%F 2>/dev/null || date -u -d yesterday +%F).csv"
if [ -f "$PREV" ]; then
  awk -F, 'NR==FNR { prev[$1]=$2; next }
    ($1 in prev) && prev[$1] != "miss" && $2 != "miss" && ($2+0) > (prev[$1]+0) \
      { print $1 ": " prev[$1] " -> " $2 }
    ($1 in prev) && prev[$1] != "miss" && $2 == "miss" \
      { print $1 ": " prev[$1] " -> miss (dropped out)" }' "$PREV" "$OUT" |
    sh -c "${ALERT_CMD:-cat}"   # e.g. ALERT_CMD="mail -s 'rank drops' you@example.com"
fi
```

## Going deeper

This overview is deliberately short. Every endpoint's exact request parameters (required fields, defaults, enums) and response fields are published as OpenAPI: https://api.seofetch.com/v1/openapi.json. For the whole docs corpus in one fetch — every page, the idempotency/retry contract, and a reference page per endpoint — see https://docs.seofetch.com/llms-full.txt.
endpoints

All the SEO data your tools need. Predictable credit costs.

Click any endpoint — the response shown is the real envelope, built from the live catalog.

examples

What people build with it.

pricing

Prepaid credits. No subscription.

$49
10,000 credits
$0.0049 / credit
Get started
most popular
$199
50,000 credits
$0.0040 / credit
Get started
$499
150,000 credits
$0.0033 / credit
Get started
$999
400,000 credits
$0.0025 / credit
Get started
No credit card requiredCredits don't expireUpstream failures are refunded100 req/s per orgFixed cost per request
why seofetch

Infrastructure-grade, by design.

The playbook that made payments programmable — one consistent API, idempotency everywhere, metered pricing, failures that make themselves right — applied to SEO data.

usage feedbalance 10,000
/v1/search138 ms−1200
/v1/backlinks/summary612 ms−20200
/v1/page/lighthouse5.9 s−2200
usage metering

Metered like a utility

Per-request pricing, timed and logged. Your usage feed is the invoice — no seats, no tiers to outgrow.

{ envelope — never changes
  "id", "request_id", "object", 🔒
  "created_at", "elapsed_ms", "cache", "credits", 🔒
  "data": { "query", "items[rank, title, domain]" }
}
same envelope since v1every endpoint
one envelope

One API to learn

The envelope never changes — learn it once and every endpoint behaves identically.

idempotency-key: kd-001attempt 1
POST /v1/keywords/difficulty
job running…charged 110 cr
retries are free

Idempotent by default

Same key, same result, one charge. Crashed cron, flaky network, long job — retries are always free.

POST /v1/keywords/volume — one request
"trail running shoes"#1
"running shoes for flat feet"#2
"carbon plate shoes"#3
keywords 3 / 500price 20 cr — flat
batch scale

Built for bulk

One keyword or five hundred in a single call — same envelope, one flat price.

rank · "best running shoes"#6
1 credit / keyword / daysame request_id = free re-read
daily data

Dependable enough to build on

Fresh daily, stable ids, replayable results — treat it as an input, not a report.

agent: find pages worth optimizing
/v1/searchrank 7
/v1/keywords/volume135k/mo
/v1/keywords/difficultyKD 41 — winnable
/v1/page/crawlmeta missing
→ verdict: rewrite /blog/shoes — upside 135k/mo · 133 cr spent
composable

Primitives, not features

JSON in, JSON out, fixed costs — compose them into trackers, audit gates, agents.

faq

Questions.

What is a credit?

A unit of API usage. Most endpoints cost a flat number of credits per request. /v1/search is depth-tiered (1 or 10), /v1/site/audit is billed per delivered page, /v1/locations is free. Credits don't expire.

What are the rate limits?

100 requests per second per organization.

What happens if I run out of credits?

Requests return 402 Payment Required until you top up.

Do failed requests cost credits?

Upstream failures are refunded automatically. A 504 covers two different situations — check the error's code, not just the status. connection_timeout means the job is still running and the charge stands, nothing to refund yet: reconnect with the same key you sent — or, if you called keyless, with the request_id from that response — to collect the result once it's ready. upstream_timeout means the upstream itself gave up: that's a definite failure, refunded automatically like any other.

Are requests synchronous?

Yes — you get the result on the same connection, up to each endpoint's ceiling (60s for most; /v1/search runs to 180s, /v1/site/audit to 600s — see the per-endpoint ceilings in the docs). If it's still running you get a 504; reconnect with the same key you sent — or, if you called keyless, with the request_id from that response.

$ seofetch signup — 1,500 credits granted

Start with 1,500 free credits.

No credit card required.

Get your API key