Skip to content

New AI assistant answers: ChatGPT, Gemini, Copilot and AI Mode by API

SerpKite
Get API key

Google /goto links in SERP APIs: getting the real URL

Google holds some result links back for seconds. What SERP APIs do about it, the delays we measured, and how SerpKite gets 99.9% of real URLs at once.

SerpKite team 4 min read

On this page

Since August 2026, every link on a Google results page has been an opaque google.com/goto?url=… redirect. A SERP API has to look up each one to give you the page that ranks. Most of the time Google answers at once. For a few results per page it doesn’t: it tells the caller to come back later.

What a SERP API does with those few links decides whether your rank tracker sees example.com in position 5, a Google URL in position 5, or nothing at all. This post covers what we measured and what SerpKite now returns.

Google answers some lookups later

Each /goto lookup either gets a redirect to the destination or a “checking your request” page. That page only lets the caller through after a delay; ask too early and you get an error instead of the destination.

The delays follow a pattern across one results page. The first lookups are answered immediately. After that Google schedules them later and later, roughly doubling: 0.56 s, 1.2 s, 2.4 s, 4.8 s, 9.6 s… Google started doing this around October 30 and tightened it again in early November.

In our production traffic on the morning of November 5, Google scheduled 6% to 11% of lookups. Most delays fit inside a normal request. The ones that didn’t averaged 8–10 seconds. Across three samples (220 searches), between 2% and 14% of searches had at least one result whose destination wasn’t released within the ~4 s a search request budgets for lookups. That’s about 3% of all result links.

What we changed on November 5

We found what was behind most of these delays and changed how SerpKite looks links up, so Google now answers nearly all of them at once.

Before the change After the change
Link lookups measured (production) 6,973 over 6.5 h 6,622 over the first 24 min
Real URL in the first response 93.3% 99.97%
Our 60-query benchmark, 12 countries n/a 505 of 505 links

Search speed didn’t change: the median stayed between 1.2 and 1.5 seconds in our tests. The benchmarks page has the full run.

Four ways to handle it

  1. Wait for every link. Correct, but a search that answers in 1 s now sometimes takes 10–40 s.
  2. Drop the result. Fast, and it looks clean, but every result below it moves up one position. A rank tracker records a drop that never happened. Until this week, this is what SerpKite did, and it flagged the response partial.
  3. Return the Google link. The position is right, but the link is google.com, so domain matching and deduplication break quietly.
  4. Keep the result, flag it, resolve it later. The position is right, the domain is usually right, and the destination arrives a few seconds later.

You’ll find each of these among SERP APIs today. The difference rarely shows up in a demo. It shows up as phantom rank drops a week later.

What SerpKite returns

Every result’s link is the destination page. In the rare case Google holds one back past the request, the result keeps its position and says so:

{
  "position": 5,
  "title": "Best Espresso Machines of 2026, Tested",
  "link": "https://www.google.com/goto?url=CAESmQEB…",
  "link_resolved": false,
  "domain": "example.com",
  "displayed_link": "https://www.example.com › reviews › espresso"
}
  • domain is the host Google displayed for the result. On November 5 it matched the real destination for 25 of 25 held-back results. It’s empty when Google shows no address, for example on a forum result that shows “4 comments · 1 year ago”.
  • meta.unresolved_links counts such results, and meta.resolved_urls is false while there are any. They no longer make the response partial.
  • SerpKite keeps following those links after Google’s delay, for up to two minutes. POST /v1/resolve returns their destinations, with retry_after while they’re pending. It’s free.
  • Batch jobs and monitor runs wait for them before they finish, so their results carry every destination Google releases. In our check, 40 batch searches came back with zero unresolved links. The jobs that waited took about 15 seconds longer.
  • A live response is cached once all its links resolve, so a later request with max_age gets the full set.

In the first hour after release, the background follow resolved 127 of 127 held-back links. In our tests, /v1/resolve returned every held-back destination within 5 to 20 seconds of the search.

Getting the destinations in code

With the Python SDK (pip install serpkite, 0.9.0 or later):

import time
from serpkite import SerpKite

sk = SerpKite()  # reads SERPKITE_API_KEY
res = sk.search("best espresso machine")

held = [r.link for r in res.results if r.link_resolved is False]
dest = {}
while held:
    out = sk.resolve(held)
    dest.update({r.link: r.destination for r in out.results if r.status == "resolved"})
    held = [r.link for r in out.results if r.status == "pending"]
    if held:
        time.sleep(out.retry_after or 5)

for r in res.results:
    print(r.position, dest.get(r.link, r.link))

If you only need positions per domain, you don’t have to wait at all: match on domain, which is already there. For large keyword sets, queue them with POST /v1/batches at half price and every link arrives resolved.

Tracking ranks

Store domain and position, and treat link_resolved: false as “destination pending”, not as a missing result. The rank tracking guide covers the other flags worth checking: missing_pages and similar_results_hidden.

We log Google changes like this one on the Google SERP changelog. The original /goto rollout and how to detect it in your own parser are covered in Google /goto links broke your rank tracker.

Written by the SerpKite team. Questions or corrections: support@serpkite.com. Subscribe via RSS.

Related posts

Start building

Get your API key in 30 seconds

2,500 free credits, then 1,000 every month. No credit card.