Google Search API
Ranked pages with titles, links and snippets.
What is this API?
Serqo’s Google Search API retrieves a Google web results page for a query and returns its results as structured JSON. Use the google engine with type: "web"; result positions and optional SERP features describe the page returned for that request.
Common use cases
- Track organic result positions across queries, countries and languages.
- Review snippets and SERP features such as related searches or answer boxes.
- Pass normalized result data to an internal reporting or research workflow.
Request example
POST https://api.serqo.io/v1/search
| Field | Value |
|---|---|
| engine | google |
| type | web |
Request headers
Create an API key and store it on your server. Send the API key in the x-api-key header.
| Header | Value | Description |
|---|---|---|
| Content-Type | application/json | JSON request body. |
| x-api-key | YOUR_API_KEY | API key used to authenticate the request. |
export SERP_API_KEY='YOUR_API_KEY'
curl https://api.serqo.io/v1/search \
-H "x-api-key: $SERP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"q": "open source observability tools",
"engine": "google",
"type": "web",
"gl": "us",
"hl": "en"
}' Code examples
Use the same API key with a standard HTTP client. These examples require Node.js 22 or later, or Python 3.
const response = await fetch('https://api.serqo.io/v1/search', {
method: 'POST',
headers: {
'x-api-key': process.env.SERP_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ q: 'open source observability tools', engine: 'google', type: 'web' }),
});
const result = await response.json();
if (!response.ok) {
console.error(response.status, result.requestId, result.error);
} else {
console.log(result.data.results);
} import json
import os
from urllib.error import HTTPError
from urllib.request import Request, urlopen
request = Request(
'https://api.serqo.io/v1/search',
data=json.dumps({'q': 'open source observability tools', 'engine': 'google', 'type': 'web'}).encode(),
headers={
'x-api-key': os.environ['SERP_API_KEY'],
'Content-Type': 'application/json',
},
)
try:
with urlopen(request) as response:
result = json.load(response)
print(result['data']['results'])
except HTTPError as error:
result = json.load(error)
print(error.code, result['requestId'], result['error']) Parameters
The number of results returned per request depends on the search engine and may vary.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| q | string | Yes | — | Non-empty search query. |
| engine | string | No | Use google for this API. | |
| type | string | No | web | Use web for this API. |
| gl | string | No | — | Two-letter lowercase country code, for example us. |
| hl | string | No | — | Interface language code, for example en. |
| start | integer | No | — | Offset from 0 to 1000000. Use nextStart from the response. |
| safe | off | active | No | — | Explicit-content filter: off disables it, active enables it. |
| tbs | string | No | — | Google time filter, such as qdr:d, qdr:w or qdr:m. |
Only q is required by the API, but keep engine and type as shown for this search. A dash means the API does not assign a default. Unknown parameters return 422 INVALID_PARAM.
Response
HTTP 200. A real API response, trimmed to the first three results for readability. Field availability and result groups vary by the returned page; values can be null.
{
"success": true,
"requestId": "req_3b994246-e7b2-4fbe-b932-0a49c9d5e3d6",
"data": {
"engine": "google",
"type": "web",
"query": {
"q": "open source observability tools",
"gl": "us",
"hl": "en"
},
"searchInformation": {
"totalResults": 123,
"timeTakenMs": 160,
"displayed": "About 123 results"
},
"results": [
{
"position": 1,
"type": "organic",
"title": "Open Source Data Observability Tools: When Free Isn't ...",
"url": "https://montecarlo.ai/blog-data-observability-open-source-tools",
"displayedUrl": "https://montecarlo.ai › blog-data-observability-open-sour...",
"domain": "montecarlo.ai",
"source": "montecarlo.ai",
"date": "Mar 9, 2026",
"snippet": "Mar 9, 2026 — With Monte Carlo , your data team can analyze data at-rest, deploy ML-powered anomaly detection to automatically detect incidents, integrate ... Read more",
"snippetHighlightedWords": [
"Monte Carlo"
],
"thumbnail": null,
"favicon": null,
"duration": null,
"price": null,
"rating": null,
"sitelinks": [
{
"title": "Read more",
"url": "https://www.google.com/goto?url=CAESzQEB6zswFeMmT2D1ovQBWKHRQvogdGw8E8byJiqcx12dE5C6-IAgkF4Byiebi6nfopFZhuJuADXNGSIDxaO5Y_vrnEONjvyxO98TnCdw-Jkpg9NLwQFglBO11Hob5i1hDpAyUpfqG-CYrNTSLl9_CK8juhEUY8eYmgJycAPg7WIWW6-vkUKDFpRg5C7wqqErASYox6Eq7ly4owx7n15uDHevwENJTanA2-22oxzUh1XH1DnuoKMkEIWbInfB31Qcb0Km2Qxj_caQGjPX2jDX"
}
],
"extensions": {
"googleRpos": "0"
}
},
{
"position": 2,
"type": "organic",
"title": "The 11 Best Observability Tools in 2026",
"url": "https://www.dash0.com/comparisons/best-observability-tools",
"displayedUrl": "https://www.dash0.com › Comparisons",
"domain": "dash0.com",
"source": "Dash0",
"date": "Jan 6, 2026",
"snippet": "Jan 6, 2026 — OpenObserve is an open-source observability platform designed for performance and efficiency. Written in Rust, it ships as a single binary ... Read more",
"snippetHighlightedWords": [
"OpenObserve"
],
"thumbnail": null,
"favicon": null,
"duration": null,
"price": null,
"rating": null,
"sitelinks": [
{
"title": "Read more",
"url": "https://www.google.com/goto?url=CAES4gEB6zswFUKVgd3cbv5XUQzW5x89ABN30qEesbRfxFIGdxKP_rlpbeK57JpD4Npi2TzhLx7ayJs8S5Xwrm3whmAsfTK8tG-8972gGVV68a-p6lG26kClQG4IcMBmHx9wOz4XLYlmb7Z6wGCB6VJi0XBNVC857SpxyN_JWVx7Ht6PE-pxH6HPGS9XP-2XRdgjo5Mc9BYfKA7ZJtqnlgI4vmRg7HM0R4i2cPzjZFvvDlQXbp39gf4SMoEuPF3IGHfSo93QsxjnQuj5aBP79wEb_OtRAjvQ1eJ8QYgDuaj_E9JsEGa8"
}
],
"extensions": {
"googleRpos": "1"
}
},
{
"position": 3,
"type": "organic",
"title": "7 Best AI Observability Tools for Engineering Teams",
"url": "https://blog.n8n.io/ai-observability-tools/",
"displayedUrl": "https://blog.n8n.io › ai-observability-tools",
"domain": "blog.n8n.io",
"source": "n8n Blog",
"date": "Aug 6, 2026",
"snippet": "Aug 6, 2026 — Arize Phoenix is an open-source observability platform focused on debugging and improving AI applications. SigNoz and LangFuse are popular open ...",
"snippetHighlightedWords": [
"Arize Phoenix is an open-source observability platform"
],
"thumbnail": null,
"favicon": null,
"duration": null,
"price": null,
"rating": null,
"sitelinks": [],
"extensions": {
"googleRpos": "6"
}
}
],
"features": {
"relatedSearches": [
{
"query": "Open source observability tools free",
"url": "https://www.google.com/search?safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&q=Open+source+observability+tools+free&sa=X&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ1QJ6BAg3EAE"
},
{
"query": "Open source observability tools github",
"url": "https://www.google.com/search?safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&q=Open+source+observability+tools+github&sa=X&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ1QJ6BAg9EAE"
},
{
"query": "Best open source observability tools",
"url": "https://www.google.com/search?safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&q=Best+open+source+observability+tools&sa=X&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ1QJ6BAg8EAE"
},
{
"query": "Observability tools list",
"url": "https://www.google.com/search?safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&q=Observability+tools+list&sa=X&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ1QJ6BAg7EAE"
},
{
"query": "SigNoz",
"url": "https://www.google.com/search?safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&q=SigNoz&sa=X&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ1QJ6BAg6EAE"
},
{
"query": "Top 10 observability tools",
"url": "https://www.google.com/search?safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&q=Top+10+observability+tools&sa=X&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ1QJ6BAg5EAE"
},
{
"query": "OpenObserve",
"url": "https://www.google.com/search?safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&q=OpenObserve&sa=X&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ1QJ6BAg4EAE"
},
{
"query": "Elastic Observability",
"url": "https://www.google.com/search?safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&q=Elastic+Observability&sa=X&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ1QJ6BAg2EAE"
},
{
"query": "2",
"url": "https://www.google.com/search?q=open+source+observability+tools&safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&ei=9u7aaoeLGJ6lptQP4vm2oQ8&start=10&sa=N&sstk=AS6-VmIfDu1Dr98WUp_qT0VP_EC7x8XKg8A8SOXvYt7fsobqGQn_eqhHNWV8YgjrilITKrMvvSZC8nYZPNAYZ9FGyee2UkKPzSPImw&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ8tMDegQIMRAE"
},
{
"query": "3",
"url": "https://www.google.com/search?q=open+source+observability+tools&safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&ei=9u7aaoeLGJ6lptQP4vm2oQ8&start=20&sa=N&sstk=AS6-VmIfDu1Dr98WUp_qT0VP_EC7x8XKg8A8SOXvYt7fsobqGQn_eqhHNWV8YgjrilITKrMvvSZC8nYZPNAYZ9FGyee2UkKPzSPImw&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ8tMDegQIMRAG"
},
{
"query": "4",
"url": "https://www.google.com/search?q=open+source+observability+tools&safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&ei=9u7aaoeLGJ6lptQP4vm2oQ8&start=30&sa=N&sstk=AS6-VmIfDu1Dr98WUp_qT0VP_EC7x8XKg8A8SOXvYt7fsobqGQn_eqhHNWV8YgjrilITKrMvvSZC8nYZPNAYZ9FGyee2UkKPzSPImw&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ8tMDegQIMRAI"
},
{
"query": "5",
"url": "https://www.google.com/search?q=open+source+observability+tools&safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&ei=9u7aaoeLGJ6lptQP4vm2oQ8&start=40&sa=N&sstk=AS6-VmIfDu1Dr98WUp_qT0VP_EC7x8XKg8A8SOXvYt7fsobqGQn_eqhHNWV8YgjrilITKrMvvSZC8nYZPNAYZ9FGyee2UkKPzSPImw&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ8tMDegQIMRAK"
},
{
"query": "6",
"url": "https://www.google.com/search?q=open+source+observability+tools&safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&ei=9u7aaoeLGJ6lptQP4vm2oQ8&start=50&sa=N&sstk=AS6-VmIfDu1Dr98WUp_qT0VP_EC7x8XKg8A8SOXvYt7fsobqGQn_eqhHNWV8YgjrilITKrMvvSZC8nYZPNAYZ9FGyee2UkKPzSPImw&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ8tMDegQIMRAM"
},
{
"query": "7",
"url": "https://www.google.com/search?q=open+source+observability+tools&safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&ei=9u7aaoeLGJ6lptQP4vm2oQ8&start=60&sa=N&sstk=AS6-VmIfDu1Dr98WUp_qT0VP_EC7x8XKg8A8SOXvYt7fsobqGQn_eqhHNWV8YgjrilITKrMvvSZC8nYZPNAYZ9FGyee2UkKPzSPImw&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ8tMDegQIMRAO"
},
{
"query": "8",
"url": "https://www.google.com/search?q=open+source+observability+tools&safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&ei=9u7aaoeLGJ6lptQP4vm2oQ8&start=70&sa=N&sstk=AS6-VmIfDu1Dr98WUp_qT0VP_EC7x8XKg8A8SOXvYt7fsobqGQn_eqhHNWV8YgjrilITKrMvvSZC8nYZPNAYZ9FGyee2UkKPzSPImw&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ8tMDegQIMRAQ"
},
{
"query": "9",
"url": "https://www.google.com/search?q=open+source+observability+tools&safe=off&sca_esv=64345335af5ad8d5&hl=en&gl=us&sxsrf=APpeQnvM7CVcRGCpsL6a9rPwZHtxd5bapg:1792732918403&ei=9u7aaoeLGJ6lptQP4vm2oQ8&start=80&sa=N&sstk=AS6-VmIfDu1Dr98WUp_qT0VP_EC7x8XKg8A8SOXvYt7fsobqGQn_eqhHNWV8YgjrilITKrMvvSZC8nYZPNAYZ9FGyee2UkKPzSPImw&ved=2ahUKEwiH3pzGss-XAxWekokEHeK8LfQQ8tMDegQIMRAS"
}
],
"aiOverview": {
"available": true,
"text": "Open source observability tools are organized around the three core pillars of telemetry: metrics , logs , and traces . Medium · Dotan Horovits (@horovits) +1 Frameworks & Instrumentation OpenTelemetry : The vendor-neutral CNCF framework for collecting metrics, logs, and traces using a unified set of APIs, SDKs, and the OpenTelemetry Collector. OpenTelemetry +1 Metrics Tools Prometheus : A CNCF-graduated time-series database and alerting system built for pull-based metric scraping. Chronosphere +1 VictoriaMetrics : A high-performance, cost-effective, Prometheus-compatible time-series database. Netdata Thanos / Mimir : Scalable, long-term metric storage layers designed to extend Prometheus clusters",
"sources": []
}
},
"pagination": {
"page": 1,
"start": 0,
"hasNext": true,
"nextStart": 10
},
"meta": {
"elapsedMs": 6316
}
},
"meta": {
"cache": "miss"
}
}
Response fields
| Field | Type | Description |
|---|---|---|
| data.query | object | Search query passed to the engine. |
| data.searchInformation | object | Reported result count and search timing, when provided. |
| success | boolean | Whether the request succeeded. True in this example. |
| requestId | string | Request identifier to include when troubleshooting. |
| data.type | string | Search type used for this response. |
| data.engine | string | Engine that returned the results. |
| data.results | array | Main result list. Check feature groups as well when present. |
| data.features | object | Additional result groups; groups not returned by the engine may be absent. |
| data.pagination | object | Current offset and next-page availability. |
| data.meta.elapsedMs | number | Search duration in milliseconds, not a performance guarantee. |
| meta.cache | string | null | hit, miss, or null if cache status is unknown. |
Result fields
Read entries from data.results. Additional groups, when present, are in data.features.
| Field | Type | Description |
|---|---|---|
| data.results[].domain | string | null | Destination domain, when available. |
| data.results[].favicon | string | null | Site icon when provided. |
| data.results[].sitelinks | array | Additional links nested under the result. |
| data.results[].sitelinks[].title | string | Sitelink label. |
| data.results[].sitelinks[].url | string | null | Sitelink destination. |
| data.results[].extensions | object | Other result-specific properties. |
| data.results[].snippetHighlightedWords | string[], optional | Highlighted terms in the snippet, when provided. |
| data.results[].position | integer | Rank on this results page, starting at 1. |
| data.results[].type | string | Result category: organic, news, image, video, shopping, local, forum, book, patent or ad. This can differ from the request type. |
| data.results[].title | string | null | Title shown in the result. |
| data.results[].url | string | null | Destination URL when resolved; it may be null. |
| data.results[].displayedUrl | string | null | URL or domain displayed by the engine; not always a clickable link. |
| data.results[].source | string | null | Source name or displayed domain. |
| data.results[].date | string | null | Date text when extracted; not necessarily an ISO timestamp. |
| data.results[].snippet | string | null | Result summary. |
| data.results[].thumbnail | string | null | Thumbnail URL or inline data URL, when provided. |
| data.results[].duration | string | null | Video duration text when provided. |
| data.results[].price | string | null | Price text when provided. |
| data.results[].rating | number | null | Rating when provided. |
Additional Google web results
Google may return related questions, related searches and knowledge panels. These groups are optional and are not included in the abbreviated example above.
| Field | Type | Description |
|---|---|---|
| data.features.peopleAlsoAsk | array | Follow-up questions, answers and source links when provided. |
| data.features.peopleAlsoAsk[].question | string | Suggested question. |
| data.features.peopleAlsoAsk[].answer | string | null | Answer excerpt. |
| data.features.peopleAlsoAsk[].sources | array | Source entries with title and url. |
| data.features.relatedSearches | array | Related search queries. |
| data.features.relatedSearches[].query | string | Suggested query. |
| data.features.relatedSearches[].url | string | null | Link to the related search when provided. |
| data.features.knowledgePanel | object, optional | Knowledge panel with title, subtitle, description, attributes, sources and thumbnail. |
| data.features.answerBox | object, optional | Answer box with title, snippet, url, source and date. |
| data.features.aiOverview | object, optional | Google AI Overview with extracted text and available source links, when present. |
Pagination
- Check
data.pagination.hasNext; stop when it is false. - Use
data.pagination.nextStartasstart. Keep the other search parameters unchanged. - Send the next request. Each page is a separate search request.
| Field | Type | Description |
|---|---|---|
| data.pagination.nextUrl | string | null | Search-engine URL for the next page, when available; use nextStart with this API. |
| data.pagination.requestedPage | integer | Page requested; may differ from the returned page if the engine does not provide it. |
| data.pagination.page | integer | Current page number. |
| data.pagination.start | integer | Current result offset. |
| data.pagination.hasNext | boolean | Whether another page is available. |
| data.pagination.nextStart | integer | null | Offset for the next request, or null when unavailable. |
Errors
{
"success": false,
"requestId": "req_example",
"error": {
"code": "INVALID_PARAM",
"message": "Unknown parameter \"page\"",
"retryable": false
}
} | Field | Type | Description |
|---|---|---|
| error.code | string | Machine-readable error code. |
| error.message | string | Reason the request failed. |
| error.retryable | boolean | Whether retrying is recommended. |
| error.retryAfterMs | number, optional | Minimum wait before retrying, in milliseconds. |
| HTTP status | Meaning | What to do |
|---|---|---|
| 400 | Invalid request or unsupported search type. | Check the query and engine/type combination. |
| 401 | Missing, invalid or revoked API key. | Check the authentication header and API key. |
| 402 | Insufficient credits. | Check your credit balance. |
| 403 | Permission or plan restriction. | Check account access and plan limits. |
| 422 | Invalid parameter. | Correct the parameter identified by error.message. |
| 429 | Request rate or queue limit. | Follow the retry rules below. |
| 5xx | Server or search service failure. | Keep the requestId; retry only if allowed. |
Retry rules
- Retry only when
error.retryableistrue. - If
error.retryAfterMsis present, wait at least that many milliseconds.
Pricing and limits
- Successful searches use credits at the applicable rate.
- Failed searches and timeouts are not charged.
- Cache hits are free at the default rate. Before searching, your available balance must cover the full request cost.
See plan pricing and rate-limit and credit details.
Frequently asked questions
How do I request another page of Google results?
Check data.pagination.hasNext, then send data.pagination.nextStart as start with the same query and market settings. Each page is a separate search request.
How are Google Search API requests charged?
Successful searches use the applicable credit rate for the engine, type and country. Failed searches and timeouts release the reservation; cache hits are free at the default rate. See Pricing and limits below for the current rules.