CitationBenchTalk to Sales
API referenceResearch

Research · SERP API — Fetch & Parse Organic Results, AI Overviews, PAA, Featured Snippets & Reddit Blocks

Fetch the full SERP for any query — organic results, AI Overviews, featured snippets, People Also Ask, Reddit blocks, video carousels, local pack — parsed, persisted, and diffable over time.

Fetch the full SERP for any query — organic results, AI Overviews, featured snippet, People Also Ask, Reddit blocks, video carousels, local pack — parsed and ready to use.

SERPs are persisted; every fetch creates a SearchResult record you can read back later. Useful for diff-over-time analysis (see research · serp gap for the cliff-detection sibling).

Endpoints

MethodPathPurpose
POST/v1/research/serpFetch and parse a SERP
GET/v1/research/serpList recent SERPs
GET/v1/research/serp/{id}Get a SERP by ID
GET/v1/research/serp/diffDiff two SERPs for the same query over time

POST /v1/research/serp

Request

POST /v1/research/serp HTTP/1.1
Host: api.citationbench.com
Authorization: Bearer sk_live_***
X-Workspace-Id: ws_acme
Content-Type: application/json
Idempotency-Key: 7f3a1b18-7d8b-4f3e-9c4b-2c1a3e0a9b8f

{
  "query":     "best project management software for engineering teams",
  "device":    "desktop",
  "location":  "us",
  "language":  "en",
  "topN":      50,
  "include":   ["organic", "ai_overviews", "paa", "featured_snippet", "reddit"],
  "freshness": "now"
}

Parameters

FieldTypeRequiredDefaultNotes
querystringyesThe search query
device"desktop" | "mobile"no"desktop"
locationISO-3166noworkspace default
languageISO-639-1noworkspace default
topNnumberno50Max organic results returned
includestring[]noall parseable blocksLimit which blocks get parsed
freshness"now" | "cached"no"now"cached returns a stored SERP if one exists within cacheMaxAgeMinutes; otherwise refetches
cacheMaxAgeMinutesnumberno30

Response

HTTP/1.1 202 Accepted

{
  "invocationId": "inv_***",
  "agentId":      "agt_***",
  "skill":        "research.serp",
  "status":       "RUNNING",
  "estimatedCost": { "credits": 1, "durationSeconds": 5 }
}

Final result

GET /v1/agent/invocations/{invocationId}:

{
  "invocationId": "inv_***",
  "agentId": "agt_***",
  "skill": "research.serp",
  "status": "SUCCEEDED",
  "creditsUsed": 1,
  "result": {
    "serpId": "srp_***",
    "query": "best project management software for engineering teams",
    "device": "desktop",
    "location": "us",
    "language": "en",
    "fetchedAt": "2026-05-24T08:15:01Z",
    "organic": [
      {
        "rank": 1,
        "url": "https://wettletter.com/best-pm-tools-engineering",
        "title": "...",
        "snippet": "...",
        "domain": "wettletter.com",
        "isOwnedDomain": false
      },
      {
        "rank": 2,
        "url": "https://engineering-blog.com/best-pm-tools",
        "title": "...",
        "snippet": "...",
        "domain": "engineering-blog.com",
        "isOwnedDomain": false
      },
      // ...
      {
        "rank": 14,
        "url": "https://acme.com/engineering",
        "title": "...",
        "snippet": "...",
        "domain": "acme.com",
        "isOwnedDomain": true
      }
    ],
    "aiOverviews": {
      "present": true,
      "summary": "Engineering teams typically choose Linear, Jira, or specialized tools like ...",
      "cited": [
        { "domain": "linear.app", "url": "https://linear.app/features" },
        {
          "domain": "atlassian.com",
          "url": "https://atlassian.com/software/jira"
        }
      ]
    },
    "featuredSnippet": null,
    "paa": [
      {
        "question": "What is the best project management tool for software development?",
        "answer": "..."
      }
    ],
    "reddit": [
      {
        "url": "https://reddit.com/r/projectmanagement/comments/abc/...",
        "title": "Best PM tool for engineering teams 2026"
      }
    ],
    "videos": [],
    "localPack": null
  },
  "raw": "Fetched SERP, parsed 50 organic results. AI Overview present with 2 cited domains ...",
  "files": ["agent-workspace/serp-raw.json"]
}

GET /v1/research/serp

curl -G "https://api.citationbench.com/v1/research/serp" \
  -H "Authorization: Bearer sk_live_***" \
  --data-urlencode "query=project management software" \
  --data-urlencode "location=us" \
  --data-urlencode "since=2026-05-01T00:00:00Z" \
  --data-urlencode "limit=20"
ParamNotes
queryExact match
queryContainsSubstring match
location / language / device
since / untilISO timestamps
limit, cursorPagination

Returns the same shape as the invocation result, lighter (no organic body unless ?includeOrganic=true).


GET /v1/research/serp/{id}

curl https://api.citationbench.com/v1/research/serp/srp_*** \
  -H "Authorization: Bearer sk_live_***"

Returns the full stored SERP.


GET /v1/research/serp/diff

curl -G https://api.citationbench.com/v1/research/serp/diff \
  --data-urlencode "from=srp_old" \
  --data-urlencode "to=srp_new"

Returns the rank deltas, new entrants, lost entrants, AI-overview citation changes between two SERPs of the same query.

{
  "fromSerpId": "srp_old",
  "toSerpId": "srp_new",
  "fromFetchedAt": "2026-05-17T08:15:00Z",
  "toFetchedAt": "2026-05-24T08:15:00Z",
  "ownedDomainDelta": { "position": +3, "previous": 17, "current": 14 },
  "topDelta": [
    {
      "url": "https://engineering-blog.com/best-pm-tools",
      "previous": 4,
      "current": 2,
      "delta": -2
    },
    {
      "url": "https://wettletter.com/...",
      "previous": 6,
      "current": 1,
      "delta": -5
    }
  ],
  "newEntrants": [{ "url": "https://newentrant.io/pm-eng", "current": 9 }],
  "lostEntrants": [{ "url": "https://oldentrant.com/pm-eng", "previous": 12 }],
  "aiOverviewChanges": {
    "added": ["linear.app/features"],
    "removed": ["clickup.com/pm"]
  }
}

MCP

> Fetch the SERP for "best project management software for engineering teams" in the US, mobile.

Claude calls research.serp.fetch.

> Diff that SERP against last week's.

Claude calls research.serp.diff.


Errors

StatusCodeCause
400validation_errorMissing query
503external_unavailableDataForSEO down

Cost

ActionCredits
POST /v1/research/serp (per query)1
GET endpointsfree
GET /difffree

Use cases (string things together)

A. Trigger a SERP fetch before a content refresh

SERP=$(curl -sf -X POST .../v1/research/serp -d '{
  "query": "engineering team capacity tracking"
}' | jq -r '.invocationId')

# Pass serpId into produce.refine so the agent has fresh SERP context
curl -X POST .../v1/produce/refine -d '{
  "contentId": "cnt_***",
  "refinerId": "rfn_serp-context"
}'

B. Detect serp cliffs to find winnable queries

Use the sibling endpoint research.serp_gap, which builds on research.serp to detect a winnable gap.

C. Weekly SERP diff for top brand queries

Cron research.serp.fetch weekly on a list of brand queries; research.serp.diff against the prior week; alert on owned-domain drops.

D. Snapshot a SERP for record-keeping

curl -X POST .../v1/research/serp -d '{
  "query":     "acme.com",
  "freshness": "now"
}'

Persists a dated snapshot — useful when a client wants proof of state.

On this page