v1.0
OpenAPI 3.1.0

AccuSERP API

Introduction

Welcome to the AccuSERP documentation. If you are looking for the AccuRanker API docs, please see here. AccuSERP is a dedicated API product for on-demand Google search results.

AccuSERP lets you queue keywords for Google search scraping and retrieve parsed JSON results or raw HTML. Results are delivered asynchronously, either via a callback URL you provide or by polling the GET /results endpoint with the request ID. Heavy polling is throttled, so we recommend callbacks (see Callbacks).

Try it out! Click the Test Request button on any endpoint to send a live request directly from this page. If you're logged in, your API token is pre-filled automatically.

Recommended Flow

  1. Call GET /engines to pick a supported Google locale.
  2. Submit a search with POST /keywords with a callback URL.
  3. Wait for the callback and GET /results with the returned id.
  4. Save the result on your side before the storage TTL expires.

Authentication

AccuSERP uses API tokens for authentication. Your token must be included in every request.

Pass the token in the Authorization header:

Authorization: Bearer your-auth-token

This is the recommended method!

Query Parameter (Legacy)

For backward compatibility, you can also pass the token as a query parameter:

/status?auth_token=your-auth-token

If both the header and query parameter are present, the header takes precedence.


You can find your token on the AccuSERP dashboard.

If the token is missing or invalid, the API returns a 401 response:

{
    "detail": "Unauthorized"
}

Throughput

Your plan has a throughput limit: the maximum number of keyword requests you can submit within a rolling time window. The window is 1 hour unless your plan says otherwise. Your usage is counted across activity inside the current window. You can see your plan's throughput on the AccuSERP dashboard.

Certain endpoints do not count against your throughput. For example, you can call GET /status to check your current usage without affecting your limit.

All rate-limited endpoints include the following response headers:

Header Description
X-RateLimit-Limit Your throughput limit for the current window
X-RateLimit-Remaining Requests remaining in the current window

Use these to keep an eye on your usage and slow down before you hit the limit.

If you exceed the throughput limit, the API returns a 429 response with a Retry-After header telling you how many seconds to wait before retrying. Please honor it — many HTTP clients can do so automatically:

{
    "detail": "You have hit the rate limit of your requests"
}

Targeting a location

By default, AccuSERP queries Google with the locale you submit (e.g. en-us). For finer control, you can override the search domain and language, or pin the search to a specific city or coordinates. Pick one strategy at a time. Mixing incompatible ones returns a 400.

Locale (default)

Pass a locale value from GET /engines. This sets the Google country domain, language, and TLD as a single bundle. Most use cases stop here.

locale=en-us

Country, language, and TLD overrides

If you need a combination not in the locale list, override all three together:

gl=US&hl=en&tld=com

All three must be specified together. The tld must be a supported Google TLD. When set, this combination takes precedence over locale.

City or region

Pass a free-form geolocation string. Use this when the SERP should reflect a specific market.

geo=New York, NY, USA

geo cannot be combined with latitude/longitude or uule.

Precise coordinates

Pin the search to a latitude and longitude pair. Use this when you need sub-city precision.

latitude=40.7128&longitude=-74.0060

Both must be supplied together. Cannot be combined with geo or uule.

UULE

If you already have a Google UULE-encoded location string, pass it directly:

uule=w+CAIQICINTmV3IFlvcmssIE5ZLCBVU0E

uule cannot be combined with geo or latitude/longitude.

Credits

Credits & base requests. Your plan is sold in base requests on the AccuSERP dashboard, but the API charges in credits. The conversion is fixed: 1 base request = 10 credits. The dashboard, billing, and plan pages talk in base requests; everything below — including the cost object returned by POST /keywords — talks in credits.

A basic single-page scrape costs 10 credits (= 1 base request). Enabling options adds a per-page surcharge; surcharges add together and then the total is multiplied by num_pages:

Option Per-page surcharge
js_rendering=true + 10 credits per page
priority=true + 5 credits per page

Formula: credits = 10 × num_pages × (1 + sum of enabled fractional surcharges), where js_rendering contributes +1.0 and priority contributes +0.5 to the per-page multiplier.

js_rendering defaults to false. Pass js_rendering=true to opt into the +10 credit per-page surcharge in exchange for browser-rendered. This will for instance make sure images, AI Overview, and hidden elements are displayed.

Examples:

  • 1 page, no options → 10 credits (1 base request)
  • 5 pages, no options → 50 credits (5 base requests)
  • 1 page, priority=true → 10 × (1 + 0.5) = 15 credits (1.5 base requests)
  • 4 pages, js_rendering=true → 4 × 10 × (1 + 1) = 80 credits (8 base requests)
  • 4 pages, js_rendering=true + priority=true → 4 × 10 × (1 + 1 + 0.5) = 100 credits (10 base requests)

The POST /keywords response includes a cost object with the exact charge in credits.

AccuSERP plans are prepaid with a fixed credit balance per billing period (expressed as base requests on the plan / billing pages — e.g. a plan advertised as "100,000 base requests" carries 1,000,000 credits). Your balance resets on each plan renewal. Check GET /status for your current credit balance, or visit the AccuSERP dashboard for the equivalent in base requests.

If you have no credits remaining, the API returns 403:

{
    "detail": "You have used up all your available credits"
}

Priority queueing

Each request goes to one of two queues:

  • Standard queue (default, when priority=false). Requests are dispatched in order. During peak load they may wait behind other traffic.
  • Priority queue (when priority=true). Priority requests are dispatched ahead of any standard-queue requests waiting on the same workers. See Credits for the cost surcharge.

When to use which

  • The standard queue is the right default for bulk processing, scheduled monitoring, batch imports, and anywhere a wait of a few seconds (or longer during peak load) is acceptable.
  • The priority queue is for user-facing real-time lookups, time-sensitive automations, or workflows where a stale result is no longer useful.

Callbacks

When a search completes, AccuSERP POSTs a notification to the URL you supplied as callback. We recommend callbacks over polling GET /results; they're cheaper for both sides and not subject to fair-usage throttling.

Best practice: Always provide a callback URL. This eliminates the need to poll and ensures you receive results as soon as they're available.

Callback URL requirements

  • HTTPS is required in production. HTTP URLs are rejected.
  • Allowed ports: 443 and 80 only. Custom ports are rejected.
  • Public hostnames only. URLs that resolve to private IP ranges (RFC 1918, link-local, loopback) are rejected.
  • The body is sent as application/x-www-form-urlencoded (not JSON).

Delivery behavior

  • We make up to 2 delivery attempts: one initial attempt plus one retry on failure. If both attempts fail, the callback is dropped.
  • A failed callback does not affect the result. You can still fetch it via GET /results?id=<id> until the storage TTL expires.
  • If the search exceeds its wait window before a worker picks it up, you receive a timeout callback instead (see below) and the credits charged for the request are refunded automatically.

Securing the inbound callback

Callback payloads are not signed. To verify an inbound callback came from AccuSERP, embed a shared secret in the URL when you submit the request:

callback=https://your-server.example.com/accuserp?secret=<your-shared-secret>

Your server then checks for that query parameter on every incoming POST.

The json_callback and html_callback URLs in the payload point at our /results endpoint. Authenticate those GET calls with your usual Authorization: Bearer header (recommended) or ?auth_token=<token> query parameter.

Success payload

Field Type Description
status string "success" or "failed"
status_code integer HTTP status code of the scrape
status_description string Human-readable status message
id string The request ID (same as returned by POST /keywords)
rank_date string Date (UTC) of the search
json_callback string URL to retrieve the parsed JSON result (present when save_html is false)
html_callback string URL to retrieve the raw HTML result (present when save_html is true; points at format=html_per_page when html_per_page is true)
keyword string The keyword that was searched
engine string The search engine used
locale string The locale used
geo string The geolocation of the search
mobile string "true" or "false"

The callback includes either json_callback or html_callback, not both.

Timeout payload

Field Type Description
status string "timeout"
status_code integer 408
status_description string "Request timed out"
id string The request ID

Response Format

Metadata

The JSON response from GET /results includes the following top-level metadata fields alongside the result arrays:

Field Type Description
engine string The search engine used
locale string The locale used
keyword string The keyword searched for
set_location string The geolocation of the search
rank_date string Date of the search (ISO format)
requested_at string Time the search was requested (ISO format, UTC)
mobile boolean Whether the search was performed on a mobile device
total_number_of_results integer Total results reported by the search engine
auto_corrected boolean Whether the keyword was auto-corrected by Google
auto_corrected_to string The auto-corrected keyword (empty string if none)
related_searches array/null Related search suggestions
related_questions array/null "People Also Ask" questions
maps boolean Whether the SERP contains a maps result
video boolean Whether the SERP contains video results
serp_count integer Number of organic results
ad_count integer Number of ad results
shopping_count integer Number of shopping carousel results

Organic Results

Organic results are returned in the serp object, keyed by rank position (1-indexed). Each result contains:

Field Type Description
url string URL of the result
title string Title of the result
description string Snippet/description
base_url string Subdomain + domain
base_domain string Domain only
local boolean Whether this is a local result
video boolean Whether this is a video result
features object SERP feature flags (keys present = true)

Possible features: app, breadcrumbs, faq, featured_snippet, featured_video, forum_post, gmb_cid, hotel_result, https, image_in_pack, image_in_product_pack, interesting_finds, knowledge_panel_result, maps_local_teaser, maps_local, news_article, one_line_site_links, organic_store, popular_store, recipe, related_questions, research_product, reviews, rich_product_info, shop_style_item, site_links_links, site_links_searchbox, site_links, things_to_do_result, thumbnails, tweet, video_in_carousel, video.

Ad & Shopping Results

The ads and shopping objects share the same structure, keyed by position:

Field Type Description
ad_location string "top_ad", "ad_within_organic", or "bottom_ad"
destination_url string Clean destination URL
dirty_destination_url string URL with tracking parameters
display_url string Human-readable display URL
headline string Ad headline
description string Ad description

The ad_location value is determined by the ad's position relative to organic results on the SERP.

Storage TTLs

Results are stored temporarily and automatically deleted after expiry:

  • JSON results: stored for 2 days
  • HTML results: stored for 3 hours, also page by page (html_per_page)

Make sure to retrieve your results before the TTL expires. If you need results for longer, save them to your own storage upon retrieval.

Server:https://api.accuserp.com
No authentication selected
Client Libraries

Keywords & Results

​
Keywords & Results Operations

Submit Keyword to Queue

​

Submit a keyword for Google search scraping. The result will be delivered asynchronously to your callback URL, or you can poll GET /results with the returned id.

Parameters can be sent as query parameters or form-encoded POST body.

Parameters

Parameter Required Default Description
keyword yes The keyword to search for (UTF-8 encoded).
engine no google Search engine. Currently only google is supported.
locale no en-us Search locale. Use GET /engines to list available locales. Can be overridden by supplying all of gl, hl, and tld.
callback no URL that will receive a POST when the search completes.
geo no Geolocation for the search (e.g. "New York, NY, USA"). Cannot be combined with latitude/longitude or uule.
latitude no Latitude of the search location. Must be used with longitude. Cannot be combined with geo or uule.
longitude no Longitude of the search location. Must be used with latitude. Cannot be combined with geo or uule.
uule no Google UULE location parameter. Cannot be combined with geo or latitude/longitude.
mobile no false Search as a mobile device.
save_html no false Save the full HTML output as returned by Google (JavaScript and styles intact).
no_autocorrect no false Disable Google autocorrect.
strict no false Enable Google SafeSearch.
gl no Google country code override (requires hl and tld too).
hl no Google language override (requires gl and tld too).
tld no Google TLD override, e.g. co.uk (requires gl and hl too).
lr no Language restrict filter. Use lang_ prefix, e.g. lang_en.
cr no Country restrict filter. Use country prefix, e.g. countryUS.
tbm no Google "To Be Matched" param (isch, nws, app, bks, vid, lcl). Cannot be combined with udm.
udm no Google "Unified Data Model" param. Set udm=1 for Google Places results. Cannot be combined with tbm.
start no 0 Starting result offset (0–90).
num_pages no 1 Number of result pages to scrape (1–10).
js_rendering no false Render JavaScript on the page before parsing. Set to true for browser-rendered output that will for instance make sure images, AI Overview, and hidden elements are displayed, in exchange for the +10 credit per-page surcharge.
priority no false Use the priority queue. Without this flag, requests use the standard queue and may wait behind other traffic during peak load. See Priority queueing.
expand_ai_overview no false If an AI Overview block is present on the result page, expand it before returning. Requires js_rendering=true.
gs_lcrp no The search statistics Chrome adds when a person types into the address bar. auto builds a value; any other value is sent as given. Google can return a different page 1 when it is present, closer to what people see in Chrome; in our tests only when the search left from an IP in the target country. Results with and without it are not comparable. Cannot be combined with url, udm, tbm or start.
resolve_redirects no false Resolve Google's redirect links (e.g. /goto?url=) to their destination URLs, in both the JSON and the saved HTML. Google serves most result links as redirects; without this flag url holds the redirect.
html_per_page no false Save the HTML of each result page as its own document. Implies save_html=true. Fetch the pages with GET /results?format=html_per_page.

Cost

Each option above affects the cost. See Credits for the surcharge table and worked examples. The response includes a cost object with the exact breakdown in credits.

Body

application/json

Keyword search parameters. Send as query parameters or form-encoded POST body.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/v1/keywords
curl https://api.accuserp.com/v1/keywords \
  --request POST \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data-urlencode 'keyword=best running shoes' \
  --data-urlencode 'url=' \
  --data-urlencode 'engine=google' \
  --data-urlencode 'locale=en-us' \
  --data-urlencode 'callback=' \
  --data-urlencode 'geo=New York, NY, USA' \
  --data-urlencode 'latitude=' \
  --data-urlencode 'longitude=' \
  --data-urlencode 'uule=' \
  --data-urlencode 'mobile=false' \
  --data-urlencode 'save_html=false' \
  --data-urlencode 'no_autocorrect=false' \
  --data-urlencode 'strict=false' \
  --data-urlencode 'gl=' \
  --data-urlencode 'hl=' \
  --data-urlencode 'tld=' \
  --data-urlencode 'lr=' \
  --data-urlencode 'cr=' \
  --data-urlencode 'tbm=' \
  --data-urlencode 'udm=' \
  --data-urlencode 'start=0' \
  --data-urlencode 'num_pages=1' \
  --data-urlencode 'js_rendering=false' \
  --data-urlencode 'priority=false' \
  --data-urlencode 'expand_ai_overview=false' \
  --data-urlencode 'resolve_redirects=false' \
  --data-urlencode 'html_per_page=false' \
  --data-urlencode 'gs_lcrp='
{
  "id": "string",
  "keyword": "string",
  "engine": "string",
  "locale": "string",
  "latitude": 1,
  "longitude": 1,
  "callback": "string",
  "geo": "string",
  "uule": "string",
  "mobile": true,
  "save_html": true,
  "no_autocorrect": true,
  "strict": true,
  "cr": "string",
  "lr": "string",
  "tld": "string",
  "tbm": "string",
  "udm": "string",
  "start": 1,
  "num_pages": 1,
  "js_rendering": true,
  "priority": true,
  "expand_ai_overview": true,
  "resolve_redirects": true,
  "html_per_page": true,
  "gs_lcrp": "string",
  "cost": {
    "base": 1,
    "num_pages": 1,
    "surcharges": {
      "additionalProperty": 1
    },
    "cost": 1
  }
}

Get Search Result

​

Retrieve the search result for a previously queued keyword.

Returns parsed JSON by default, raw HTML if format=html is specified, or the HTML page by page if format=html_per_page is specified.

Parameters

Parameter Required Default Description
id yes The request ID returned when the keyword was queued.
format no json Return format: json (parsed results), html (raw HTML) or html_per_page (raw HTML of each result page, for a request queued with html_per_page=true).

JSON response

The JSON response contains serp (organic results), ads, shopping, metadata fields, related searches/questions, and counts. See the Response Format section in the API description for full details.

HTML response

Returns the raw HTML of the search result page. If gzip-compressed, the response will include Content-Encoding: gzip when the client accepts it.

HTML pages response

For a request queued with html_per_page=true, returns a JSON object with the raw HTML of each result page under its own key, in page order: {"page1": "<html>...", "page2": "<html>...", ...}. The response includes Content-Encoding: gzip when the client accepts it. The json and html results of such a request may not be stored, and then format=json and format=html answer 404.

Storage TTLs

  • JSON results are stored for 2 days
  • HTML results, also page by page, are stored for 3 hours

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/v1/results
curl https://api.accuserp.com/v1/results \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{
  "serp": {
    "additionalProperty": {
      "url": "string",
      "title": "string",
      "description": "string",
      "base_url": "string",
      "base_domain": "string",
      "local": true,
      "video": true,
      "features": {
        "additionalProperty": "anything"
      }
    }
  },
  "ads": {
    "additionalProperty": {
      "ad_location": "string",
      "destination_url": "string",
      "dirty_destination_url": "string",
      "display_url": "string",
      "headline": "string",
      "description": "string"
    }
  },
  "shopping": {
    "additionalProperty": {
      "ad_location": "string",
      "destination_url": "string",
      "dirty_destination_url": "string",
      "display_url": "string",
      "headline": "string",
      "description": "string"
    }
  },
  "engine": "string",
  "locale": "string",
  "keyword": "string",
  "set_location": "string",
  "total_number_of_results": 1,
  "rank_date": "string",
  "requested_at": "string",
  "mobile": true,
  "video": true,
  "auto_corrected_to": "string",
  "auto_corrected": true,
  "related_searches": [
    "string"
  ],
  "related_searches_rank": 1,
  "related_questions": [
    "string"
  ],
  "related_questions_rank": 1,
  "maps": true,
  "serp_count": 1,
  "ad_count": 1,
  "shopping_count": 1
}

Search Engines

​
Search Engines Operations

List Search Engines

​

List all supported search engines and their supported locales.

Use the engine and locale values from this response when submitting keywords. Only Google is currently supported. For example, to search Google in the United States: engine=google and locale=en-us.

Responses

  • application/json
Request Example for get/v1/engines
curl https://api.accuserp.com/v1/engines \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
[
  {
    "engine": "string",
    "supported": true,
    "locales": {
      "additionalProperty": {
        "tld": "string",
        "description": "string"
      }
    }
  }
]

Account

​
Account Operations

Get Account Status

​

Get current rate limits and remaining credit balance.

Response

Field Description
limits.get Maximum GET requests per rate-limit window
limits.post Maximum POST requests per rate-limit window
limits.current.get Remaining GET requests in current window
limits.current.post Remaining POST requests in current window
credits_remaining Available credits in your balance (1 base request = 10 credits)

Responses

  • application/json
Request Example for get/v1/status
curl https://api.accuserp.com/v1/status \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
{}

Models

​
​
​
​
​
​
​
​
​