BETA · DEEP SEARCH · DESKTOP 1366×768 · US

The Cheapest Pixel Position API for Developers

Rank counts results. Pixel position measures the page: pixel_position=true on Deep Search adds every element’s y-coordinate.

Get an API Key Run a Live Request
Google · Bing · Yahoo · DuckDuckGo No price increase Integer y + full {x, y, w, h} Opt-in flag, default off

Run a live Deep Search request

One real call against the API, no signup and no key. Flip Pixel positions on and run it.

What an anonymous run shows you. Anonymous calls are served from the free allowance and the pixel fields are a paid feature, so the search runs normally and metadata.pixelPositionUnavailable comes back as free_tier in place of the two fields. On a key of your own the same request adds pixel_position and pixel_box alongside the ordinary fields, and nothing else about the response changes. Both keys are optional — an item deep in the response can arrive without them, so branch on whether the field is there.

Rank counts results. Nobody scrolls a count.

A rank number answers “how many organic results are ahead of me?”, never “how far down the page am I?” Here is one keyword's page, top to bottom, with the pixel_position of each block.

Rank #1, one and a half screens down

Three ads, an AI Overview and a People Also Ask block sit above the first organic result on this page. Its position is 1. Its pixel_position is 1082 — and the viewport it is measured against is 768 px tall.

1082
px from the top of the page to the first organic result
1.41×
screens the visitor scrolls before it exists (1082 ÷ 768)

That is the number your rank report cannot show you, and it is the number that explains the traffic. Nothing about the page changed the ranking — it changed the distance. When the AI Overview grows by 200 px next month, rank stays at 1 and the distance grows to 1,282. Only pixel position moves.

Note the AI Overview row: it starts at 398, above the fold, and is 428 px tall, so it ends at 826 — below it. pixel_position is the element's top edge; pixel_box.h is what tells you it crosses the fold rather than fitting inside the first screen.

The stack above is a worked example, drawn to show how the fields fit together and how the arithmetic runs — not a measurement of any one live page. Run the call on your own keyword and the response gives you the same fields with your numbers in them.

Two keywords. Both “rank 3”. One report.

This is the reason the field exists. An ordinal rank collapses two completely different commercial outcomes into the same cell of a spreadsheet. A pixel value pulls them apart, and it does it with one integer you can sort, threshold and chart like any other metric.

Informational keyword

"how to tie a tie"

position
3
pixel_position
402
above it
2 organic rows
fold (768 px)
Above
On screen the moment the page paints. No scroll, no competition for attention from a feature block.
Commercial keyword

"car insurance quotes"

position
3
pixel_position
1830
above it
3 ads, AI Overview, PAA, 2 organic rows
fold (768 px)
2.4 screens below
Same cell in the rank report. A visitor has to scroll past 1,830 px of other people's content to reach it.

Both cards are worked examples using the response fields as they ship. The point is the shape of the comparison, not the two specific numbers — and the shape is what you can only build once every item in the response carries a coordinate.

One flag on the search you already pay for

Pixel position is not a separate product with its own rate card. It is an opt-in parameter on Deep Search, billed in the Web category exactly like a call without it.

Quick Search

/api/search/quick

from $0.03
/1K calls (Scale tier) — same Web category price
  • Organic results only, built for speed
  • No pixel fields, on any engine
  • The pixel_position flag is accepted, never an error
  • Returns metadata.pixelPositionUnavailable
  • …and a pixelPositionHint naming /api/search
  • Use it for ordinal rank; use Deep Search when you need pixels
Default$0.60/1K calls
Growth$0.06/1K calls
Scale$0.03/1K calls
Rank tracking →

Growth pricing applies from $100 deposited, Scale from $500. New accounts get free calls shared across every free-eligible endpoint — those are free-tier calls, so they return the free_tier marker rather than pixel fields.

Four engines carry pixel fields. Brave does not.

Read this table before you write the job, because the difference is silent: a Brave request with pixel_position=true is accepted and answers normally — it simply has no pixel fields on any item. If your code assumes the key is there, that is where it breaks.

Engine Deep Search /api/search Quick Search /api/search/quick What to read
Google engine=googlePixel fieldsNonepixel_position, pixel_box
Bing engine=bingPixel fieldsNonepixel_position, pixel_box
Yahoo engine=yahooPixel fieldsNonepixel_position, pixel_box
DuckDuckGo engine=ddgPixel fieldsNonepixel_position, pixel_box
Brave engine=braveNoneNonethe ordinal position field

Deep Search on the four supported engines covers desktop results in the US locale, measured against a 1366 × 768 viewport. Mobile viewports are on the roadmap and are not available today — if your reporting is mobile-first, that is a real gap and you should know it before you buy. On Quick Search the parameter is accepted on every engine and no engine returns pixel fields; the response says so in metadata.pixelPositionUnavailable.

One flag, then two extra fields per item

Add pixel_position=true to a /api/search call. The request is otherwise unchanged, and a call without the flag returns exactly the bytes it returned before the feature existed.

cURL — Deep Search with pixel positions
curl "https://apiserpent.com/api/search?q=car+insurance+quotes&engine=google&country=us&pixel_position=true" \
  -H "X-API-Key: YOUR_API_KEY"
Python — how far below the fold am I, and what is pushing me down?
import requests

FOLD = 768            # the viewport height the page is measured against
DOMAIN = "example.com"

r = requests.get(
    "https://apiserpent.com/api/search",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"q": "car insurance quotes", "engine": "google",
            "country": "us", "pixel_position": "true"},
).json()["results"]

mine = next((o for o in r["organic"] if DOMAIN in o["url"]), None)
y = mine and mine.get("pixel_position")     # may be absent — never assume it
print(f"rank {mine['position']}, opens at {y}px, {round(y / FOLD, 2)} screens down")
# → rank 1, opens at 1082px, 1.41 screens down

# Everything the SERP put above you, with the height each one takes.
blocks = []
for key in ("aiOverview", "featuredSnippet", "knowledgePanel"):
    b = r.get(key)
    if b and b.get("pixel_position") is not None:
        blocks.append((key, b["pixel_position"], (b.get("pixel_box") or {}).get("h")))
for name, items in (("ad", (r.get("ads") or {}).get("top") or []),
                    ("paa", r.get("peopleAlsoAsk") or [])):
    for it in items:
        if it.get("pixel_position") is not None:
            blocks.append((name, it["pixel_position"], (it.get("pixel_box") or {}).get("h")))

above = sorted(b for b in blocks if b[1] < y)
print(len(above), "blocks above you,",
      sum(h or 0 for _, _, h in above), "px of them")
Node.js — which results survive the fold
const FOLD = 768;

const res = await fetch(
  "https://apiserpent.com/api/search?q=mortgage+rates+today&engine=google&country=us&pixel_position=true",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const { results } = await res.json();

// pixel_position is the TOP edge. A row is fully visible only if its box ends
// above the fold too — that is what pixel_box.h is for.
const visible = results.organic.filter(o =>
  o.pixel_position != null && o.pixel_position + ((o.pixel_box && o.pixel_box.h) || 0) <= FOLD
);
console.log(`${visible.length} organic results fit on the first screen`);

// Share of the first screen taken by everything that is not an organic result.
const area = b => (b && b.pixel_box) ? b.pixel_box.w * b.pixel_box.h : 0;
const featureArea = area(results.aiOverview) + area(results.featuredSnippet)
  + (results.ads?.top || []).reduce((s, a) => s + area(a), 0);
console.log("feature pixels above the fold:", featureArea);
JSON Response (annotated)
{
  "success": true,
  "engine": "google",
  "results": {
    "organic": [
      {
        "position": 1,                 // ordinal — 1st organic result
        "title": "",
        "url": "https://example.com",
        "pixel_position": 1082,        // y of the element's top edge
        "pixel_box": { "x": 126, "y": 1082, "w": 652, "h": 118 }
      }                                 // pixel_box.y === pixel_position, always
    ],
    "ads": {
      "top": [
        { "title": "", "pixel_position": 120, "pixel_box": { "x": 126, "y": 120, "w": 652, "h": 82 } }
      ]
    },
    "aiOverview": {
      "text": "",
      "pixel_position": 398,
      "pixel_box": { "x": 125, "y": 398, "w": 1100, "h": 428 }
    },                                  // 398 + 428 = 826 → crosses the 768px fold
    "peopleAlsoAsk": [
      { "question": "", "pixel_position": 842, "pixel_box": { "x": 126, "y": 842, "w": 652, "h": 52 } }
    ],
    "featuredSnippet": null,          // not on this page — the key is still here
    "knowledgePanel": null
  }
}
JSON — the two responses that carry no pixel fields
// (a) the call was served from your free allowance
{ "metadata": { "pixelPositionUnavailable": "free_tier" } }

// (b) you sent the flag to /api/search/quick
{ "metadata": {
    "pixelPositionUnavailable": "not_supported_on_quick",
    "pixelPositionHint": "Pixel positions are available on /api/search (Deep Search)."
} }

// Both still return the search itself. Branch on the marker, not on an error:
// neither of these is a 4xx, and neither changes the rest of the response.

What you get, precisely

Two sibling fields on every item the measurement matched, in one consistent shape across every result type and every supported engine. No per-block variants, no source flags.

Parameter
pixel_position=true on GET /api/search (Deep Search). Defaults to false; a response with the flag omitted is byte-identical to one from before the feature shipped.
Engines
google, yahoo, bing and ddg. engine=brave returns no pixel fields — the request still succeeds, so read the ordinal position field there.
Endpoint limits
Deep Search only. /api/search/quick accepts the flag on every engine and returns none of the fields; News, Images and Videos do not take the parameter at all.
Viewport
1366 × 768, desktop, US locale. The 768 in every “above the fold” calculation on this page is that viewport height. Mobile is on the roadmap.
pixel_position
Integer. The y-coordinate of the element's top edge, measured in pixels from the top-left origin of the rendered page. Smaller is higher up. An item with pixel_position < 768 starts on the first screen — use pixel_box.h to know whether it also finishes there.
pixel_box
Object: { x, y, w, h } — left offset, top offset, width and height, all integers in the same coordinate space. pixel_box.y equals pixel_position by construction. Use it for element area, centre point, fold crossing and share-of-voice scoring.
Where the fields appear
Every organic[] row, plus aiOverview, featuredSnippet, knowledgePanel, peopleAlsoAsk[], ads.top[], localPack[], videos[], shopping[] and relatedSearches[] — on each of those blocks when the results page actually contains it.
Tier
Paid calls. A call served out of your free allowance returns metadata.pixelPositionUnavailable: 'free_tier' and no pixel fields, so budget a pixel job against paid credit.
Price
Unchanged. The flag adds nothing to the bill: $0.60 per 1,000 calls by default, $0.06 on Growth, $0.03 on Scale — the same Web-category rate as a search without it.
Depth
Up to 100 results across up to 10 pages in one call. Deeper items are the likeliest to arrive without pixel fields; treat both keys as optional and fall back to position.
Stability
BETA. The values describe a standard desktop rendering of the page rather than one person's screen, and the contract may change as SERP layouts do. A field that cannot be produced is simply absent — the rest of the response is unaffected and the shape never varies.

What teams build with a coordinate

Every one of these needs a distance, not an ordinal. None of them can be built from a rank number alone.

Above-the-fold reporting

Threshold on pixel_position < 768 and you have a column no rank tracker ships: which of a client's keywords are actually on the first screen. Add pixel_box.h and you can separate “starts on screen” from “fits on screen”.

Explaining a flat-rank traffic drop

The hardest client conversation in SEO is “rank held, traffic fell”. Chart pixel_position next to rank and the answer is usually visible on the chart: the number stayed at 3 and the distance grew by 600 px.

Share of the first screen

pixel_box gives width and height, so it gives area. Sum the area every block occupies above 768 px and you can score a SERP by who owns the screen — ads, an AI Overview, or organic results.

SERP layout change detection

Feature rollouts move pixels long before they move rankings. Store the y of each block per keyword per day and a new AI Overview shows up as a step change in one column, dated, on the day it happened.

Snippet and AI Overview audits

Owning the featured snippet only pays if the snippet is near the top. Its pixel_position tells you whether it opens the page or sits under an AI Overview and three ads — two very different assets with the same name.

Ad placement checks

Ads carry the fields too. ads.top[] comes back with a y and a box, so a paid team can see where a placement actually landed on the page rather than inferring it from a position label.

Pixel geometry across the providers that ship it

Only a handful of SERP APIs publish rectangle coordinates at all, so the honest comparison is about coverage, surcharge and device — not about who has the feature.

Capability Serpent API SerpApi.com DataForSEO
Rectangle geometry on organic resultsYes — pixel_boxYesYes — calculate_rectangles
Web-search engines it coversFour — Google, Bing, Yahoo, DuckDuckGoGoogle only (plus the Google Ads product)Google only
Single-integer y alongside the boxYes — pixel_positionRead it off the rectangleRead it off the rectangle
Extra charge to switch it onNone — same per-call priceIncluded in the plan's search countYes — documented as increasing the task cost
Mobile viewportNot yet — desktop 1366×768 onlyYesYes — configurable screen size
Entry price$0.60/1K calls, $0.03/1K at Scale$25/mo for 1,000 searchesPer-task, plus the rectangle surcharge
Free allowanceFree to start — free calls do not return pixel fields250 searches/monthTrial credits

Competitor rows above were read from their own documentation on 7 September 2026; re-check them before quoting. A fourth vendor, Authoritas, also publishes element coordinates (“the (x,y) position of all elements on the page”, read 16 September 2026) but prices in pounds only, so it is not in this dollar table — see the full provider comparison, which covers all four and names the eight vendors that publish no geometry field at all. Mobile is the row we lose on today and we would rather you read it here than find it in an integration. See the full SERP API price comparison for everything outside the pixel feature.

Pixel Position questions

Rank is an ordinal: first organic result, second, third. Pixel position is a distance: how many pixels down the rendered results page that element actually starts, measured from the very top. The two used to agree. They no longer do — ads, an AI Overview, a featured snippet and a four-question People Also Ask block all sit above the first organic result and all push it down. So one keyword's rank #1 can open at 320 px, on the first screen, while another keyword's rank #1 opens at 1,082 px and needs a scroll and a half before it exists. Same rank, different business.
Add pixel_position=true to a GET /api/search (Deep Search) call. Nothing else about the request changes, and a request without the flag is unchanged in every byte. Every item that the measurement matched then carries two sibling fields: pixel_position, an integer y-coordinate, and pixel_box, an object with x, y, w and h. Quick Search does not carry pixel fields on any engine: /api/search/quick accepts pixel_position=true, runs the search normally and returns metadata.pixelPositionUnavailable set to not_supported_on_quick plus a metadata.pixelPositionHint pointing at /api/search.
Four: engine=google, engine=yahoo, engine=bing and engine=ddg, on desktop US results at a 1366×768 viewport. engine=brave does not return pixel fields. A Brave request with pixel_position=true is still accepted and still answers normally — it simply comes back without pixel_position or pixel_box on any item, so read the ordinal position field there or send the keyword to one of the other four engines. Mobile viewports are on the roadmap and are not available today.
pixel_position is one integer: the top edge of the element. pixel_box is the whole rectangle — { x, y, w, h } — where x and y are the top-left corner measured from the page origin and w and h are the element's width and height in pixels. pixel_box.y is the same number as pixel_position by construction. Reach for pixel_box whenever the top edge alone is not enough: a block's area (w times h) for share-of-voice scoring, its centre point, or whether it crosses the fold rather than merely starting above it. An AI Overview that starts at 398 px and is 428 px tall begins above the fold and ends below it, and only the box tells you that.
No. A web search with pixel_position=true is billed exactly like a web search without it — $0.60 per 1,000 calls on the default rate, $0.06 on Growth, $0.03 on Scale. There is no separate product to buy and no upgrade to make. The one requirement is that the call be a paid one: a request served out of your free allowance comes back with metadata.pixelPositionUnavailable set to free_tier and no pixel fields, so plan a pixel job against paid credit.
All three return rectangle geometry, so the difference is coverage and price. Checked against their own documentation on 7 September 2026: SerpApi documents pixel position for its Google Search API and Google Ads API, on desktop and mobile, with its free plan at 250 searches a month and its cheapest paid plan at $25 for 1,000 searches. DataForSEO returns a rectangle when you set calculate_rectangles on a Google SERP Advanced task, and its help centre states plainly that enabling the parameter increases the cost of the task. Serpent returns pixel fields on four web-search engines rather than one, at $0.60 per 1,000 calls falling to $0.03, with no surcharge for the flag — and today only on desktop, which is the honest trade.
The feature is in BETA and you should code for a missing field. Pixel values describe a standard desktop rendering of the results page at 1366×768, not a screenshot of one particular person's browser, so treat them as a layout measurement rather than a per-user fact. Deeper items in a large multi-page call are the likeliest to arrive without pixel fields. Read the item's ordinal position field whenever pixel_position is absent, and read pixel_box with a null-check rather than assuming it: nothing about the response shape changes when a value cannot be produced, which is deliberate.

Stop reporting ordinals

Add pixel_position=true to a Google, Bing, Yahoo or DuckDuckGo /api/search call and every element comes back with the coordinate it renders at. Opt-in flag, BETA, no price increase — from $0.60 per 1,000 calls, $0.03 at Scale. Every account starts with free calls to try the endpoint; add credit when you want the pixel fields, because a free-tier call returns the free_tier marker instead.

Get an API Key

Related guides

More on measuring what a searcher actually sees.

Win Featured SnippetsTrack and win position zero — then check where it renders. Rank Tracking APIOrdinal positions across every major engine, built for speed. Local Rank TrackingHow a position changes with the place you search from. Google SERP APIThe full response object the pixel fields ride on.