Browser-extension SERP overlay
The VisibilityIQ SEO Toolbar is a Manifest V3 browser extension (Chrome 102+,
Firefox 115+) that acts as a thin client over the public /v1 API.
It has two surfaces: a free on-page panel and a paid, API-backed SERP overlay. This
page documents the integration behind the paid overlay so you can understand — or
rebuild — the same call against your own key.
What the extension does
Section titled “What the extension does”The extension ships two independent features:
-
On-page panel (free, no API credits). A popup that parses the active tab’s raw HTML and headers: title, meta description, the H1–H6 outline, canonical, robots (meta +
X-Robots-Tag), hreflang, word count, Open Graph, viewport, and language. It also includes a redirect-chain tracer, a broken-outbound-link checker, a SERP locale switcher, and an AI-crawler-access check that evaluates GPTBot / ClaudeBot / PerplexityBot / Google-Extended / OAI-SearchBot allow-vs-deny from the site’srobots.txt— including the selective-block flag (AI-blocked but Googlebot-allowed). None of this touches the API. -
SERP overlay (paid,
/v1-backed). A content script injected on Google search results (*://www.google.com/search*) that annotates each organic result with keyword and traffic metrics drawn from your VisibilityIQ project data. This is the feature that calls the API and spends credits.
The endpoint it calls
Section titled “The endpoint it calls”The overlay reads from the live own-data endpoint:
GET https://visibilityiq365.com/api/v1/serp/overlay?url=<result-url>&projectId=<projectId>| Query param | Required | Notes |
|---|---|---|
url | yes | A full, valid URL (a result observed on the SERP). |
projectId | yes | A project in the key’s organization. |
It returns the top ranking keywords your project already tracks for the URL’s
hostname, plus the URL’s last-known crawl status. Because it serves your own data from
D1, it is the same cost tier as rankings.get: 1 credit base, cacheable (a cache
hit costs 0).
Authentication
Section titled “Authentication”The overlay authenticates with the user’s Bearer key, stored in the extension’s
options page and sent only in the Authorization header — never in the URL or a log:
Authorization: Bearer viq_live_xxxxxxxxxxxxxxxxxxxxxxxxThe key must carry the rankings:read scope (the same scope that unlocks
/v1/rankings/{projectId}). Mint one at Developer API (/dashboard/developer) — see
the Quickstart. When no key is configured, the
extension skips the network call entirely and only the free panel works; the overlay
never blocks the page.
Request and response
Section titled “Request and response”A single overlay call for one result URL:
curl "https://visibilityiq365.com/api/v1/serp/overlay?url=https://uscoinshows.com/shows&projectId=uscoinshows" \ -H "Authorization: Bearer $VIQ_KEY"The response follows the standard /v1 envelope. The handler returns up to five
top-ranking keywords (position ≤ 100, ordered by position) for the URL’s hostname, with
a per-keyword CTR and estimated traffic, plus the rolled-up totals and the URL’s crawl
status:
{ "success": true, "data": { "url": "https://uscoinshows.com/shows", "domain": "uscoinshows.com", "keywords": [ { "keyword": "coin shows near me", "position": 3, "volume": 8100, "ctr": 0.1031, "impressions": 8100, "estimatedTraffic": 835 }, { "keyword": "coin show schedule", "position": 7, "volume": 2400, "ctr": 0.0288, "impressions": 2400, "estimatedTraffic": 69 } ], "topKeyword": "coin shows near me", "estimatedTraffic": 904, "crawlStatus": 200 }}When the domain has no ranking data yet, the call still returns 200 with an empty
keywords array and topKeyword: null — the extension renders a “no data yet” state
rather than an error. crawlStatus is null when the URL has not been crawled in the
project.
Per-keyword fields
Section titled “Per-keyword fields”position— current organic rank (1–100) fromorganic_keywords_current.volume— monthly search volume (the impression pool).ctr— estimated click-through rate for that position, to four decimals.impressions— monthly impression estimate (equal tovolume).estimatedTraffic—traffic_estimatefrom the data when present, otherwiseround(volume × ctr).
Status codes the overlay handles
Section titled “Status codes the overlay handles”The content script maps the documented /v1 status codes to render states so a SERP is
never broken by an API hiccup:
| Status | Overlay behavior |
|---|---|
200 | Render the metrics (or “no data yet” on empty keywords). |
401 / 403 | Key missing, revoked, or lacking rankings:read — fall back to the free panel. |
402 (credit_exhausted) | Show an over-budget badge; stop spending. |
429 | Back off for Retry-After seconds before the next SERP. |
404 | Project not found or not in the key’s organization. |
The overlay reads X-Credits-Cost and X-Credits-Remaining off every response to
track budget, and aggressively caches successful results so revisiting a SERP does not
re-spend credits.
Related
Section titled “Related”- Quickstart — mint a
rankings:readkey. - Full API reference — every endpoint, scope, and credit cost.
- Rank tracking — pull the same ranking data in
bulk via
/v1/rankings/{projectId}.