Quickstart¶
This guide shows how to make your first Search API request and get structured organic results back.
Prerequisites¶
You need a Zyte API key.
Basic request¶
Send a POST request to https://api.zyte.com/v1/search with domain
and query. Use include to control what you get back.
{
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"]
}
curl \
--user YOUR_ZYTE_API_KEY: \
--header 'Content-Type: application/json' \
--data @input.json \
--compressed \
https://api.zyte.com/v1/search \
| jq .organicResults
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
HttpClientHandler handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.All
};
HttpClient client = new HttpClient(handler);
var apiKey = "YOUR_ZYTE_API_KEY";
var bytes = Encoding.GetEncoding("ISO-8859-1").GetBytes(apiKey + ":");
var auth = System.Convert.ToBase64String(bytes);
client.DefaultRequestHeaders.Add("Authorization", "Basic " + auth);
client.DefaultRequestHeaders.Add("Accept-Encoding", "br, gzip, deflate");
var input = new Dictionary<string, object>(){
{"domain", "search.engine.com"},
{"query", "web scraping tools"},
{"include", new[] {"organic"}}
};
var inputJson = JsonSerializer.Serialize(input);
var content = new StringContent(inputJson, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync("https://api.zyte.com/v1/search", content);
var body = await response.Content.ReadAsByteArrayAsync();
var data = JsonDocument.Parse(body);
var organicResults = data.RootElement.GetProperty("organicResults").ToString();
Console.WriteLine(organicResults);
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
class Example {
private static final String API_KEY = "YOUR_ZYTE_API_KEY";
public static void main(final String[] args)
throws InterruptedException, IOException, ParseException {
Map<String, Object> parameters =
ImmutableMap.of(
"domain", "search.engine.com",
"query", "web scraping tools",
"include", List.of("organic"));
String requestBody = new Gson().toJson(parameters);
HttpPost request = new HttpPost("https://api.zyte.com/v1/search");
request.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON);
request.setHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate");
request.setHeader(HttpHeaders.AUTHORIZATION, buildAuthHeader());
request.setEntity(new StringEntity(requestBody));
CloseableHttpClient client = HttpClients.createDefault();
client.execute(
request,
response -> {
HttpEntity entity = response.getEntity();
String apiResponse = EntityUtils.toString(entity, StandardCharsets.UTF_8);
JsonObject jsonObject = JsonParser.parseString(apiResponse).getAsJsonObject();
JsonArray organicResults = jsonObject.get("organicResults").getAsJsonArray();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(organicResults));
return null;
});
}
private static String buildAuthHeader() {
String auth = API_KEY + ":";
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
return "Basic " + encodedAuth;
}
}
const axios = require('axios')
axios.post(
'https://api.zyte.com/v1/search',
{
domain: 'search.engine.com',
query: 'web scraping tools',
include: ['organic']
},
{
auth: { username: 'YOUR_ZYTE_API_KEY' }
}
).then((response) => {
const organicResults = response.data.organicResults
console.log(organicResults)
})
<?php
$client = new GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.zyte.com/v1/search', [
'auth' => ['YOUR_ZYTE_API_KEY', ''],
'headers' => ['Accept-Encoding' => 'gzip'],
'json' => [
'domain' => 'search.engine.com',
'query' => 'web scraping tools',
'include' => ['organic'],
],
]);
$data = json_decode($response->getBody());
$organicResults = json_encode($data->organicResults);
echo $organicResults.PHP_EOL;
import requests
api_response = requests.post(
"https://api.zyte.com/v1/search",
auth=("YOUR_ZYTE_API_KEY", ""),
json={
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"],
},
)
organic_results = api_response.json()["organicResults"]
print(organic_results)
import requests
api_response = requests.post(
"https://api.zyte.com/v1/search",
auth=("YOUR_ZYTE_API_KEY", ""),
json={
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"],
},
)
organic_results = api_response.json()["organicResults"]
print(organic_results)
The response contains a structured organicResults array:
{
"status": "success",
"url": "https://www.example-engine.com/search?q=web+scraping+tools",
"fetchedAt": "2026-05-11T09:36:57Z",
"meta": {
"requestedAt": "2026-05-11T09:36:39Z"
},
"organicResults": [
{
"rank": 1,
"title": "Zyte - Web Scraping API",
"url": "https://www.zyte.com/",
"snippet": "The leading web scraping platform...",
"displayedUrl": "zyte.com"
}
]
}
Getting raw HTML¶
Use include: ["html"] to get the raw rendered HTML instead of parsed
results. You can also request both at once:
curl \
--user YOUR_ZYTE_API_KEY: \
--header 'Content-Type: application/json' \
--data '{
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["html", "organic"]
}' \
https://api.zyte.com/v1/search
More results¶
Set maxResults to get up to 100 results in a single call. The platform
fetches multiple pages automatically and returns them in one
organicResults array:
{
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"],
"maxResults": 100
}
curl \
--user YOUR_ZYTE_API_KEY: \
--header 'Content-Type: application/json' \
--data @input.json \
--compressed \
https://api.zyte.com/v1/search \
| jq .organicResults
var input = new Dictionary<string, object>(){
{"domain", "search.engine.com"},
{"query", "web scraping tools"},
{"include", new[] {"organic"}},
{"maxResults", 100}
};
Map<String, Object> parameters =
ImmutableMap.of(
"domain", "search.engine.com",
"query", "web scraping tools",
"include", List.of("organic"),
"maxResults", 100);
axios.post(
'https://api.zyte.com/v1/search',
{
domain: 'search.engine.com',
query: 'web scraping tools',
include: ['organic'],
maxResults: 100
},
{ auth: { username: 'YOUR_ZYTE_API_KEY' } }
).then((response) => {
console.log(response.data.organicResults)
})
$response = $client->request('POST', 'https://api.zyte.com/v1/search', [
'auth' => ['YOUR_ZYTE_API_KEY', ''],
'json' => [
'domain' => 'search.engine.com',
'query' => 'web scraping tools',
'include' => ['organic'],
'maxResults' => 100,
],
]);
api_response = requests.post(
"https://api.zyte.com/v1/search",
auth=("YOUR_ZYTE_API_KEY", ""),
json={
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"],
"maxResults": 100,
},
)
organic_results = api_response.json()["organicResults"]
api_response = requests.post(
"https://api.zyte.com/v1/search",
auth=("YOUR_ZYTE_API_KEY", ""),
json={
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"],
"maxResults": 100,
},
)
organic_results = api_response.json()["organicResults"]
Geo-targeting¶
Pass queryParameters to target a specific country and language:
{
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"],
"queryParameters": {
"style": "engineSpecific",
"gl": "us",
"hl": "en"
}
}
curl \
--user YOUR_ZYTE_API_KEY: \
--header 'Content-Type: application/json' \
--data @input.json \
--compressed \
https://api.zyte.com/v1/search \
| jq .organicResults
var input = new Dictionary<string, object>(){
{"domain", "search.engine.com"},
{"query", "web scraping tools"},
{"include", new[] {"organic"}},
{"queryParameters", new Dictionary<string, object>(){
{"style", "engineSpecific"},
{"gl", "us"},
{"hl", "en"}
}}
};
Map<String, Object> parameters =
ImmutableMap.of(
"domain", "search.engine.com",
"query", "web scraping tools",
"include", List.of("organic"),
"queryParameters", ImmutableMap.of(
"style", "engineSpecific",
"gl", "us",
"hl", "en"));
axios.post(
'https://api.zyte.com/v1/search',
{
domain: 'search.engine.com',
query: 'web scraping tools',
include: ['organic'],
queryParameters: {
style: 'engineSpecific',
gl: 'us',
hl: 'en'
}
},
{ auth: { username: 'YOUR_ZYTE_API_KEY' } }
).then((response) => {
console.log(response.data.organicResults)
})
$response = $client->request('POST', 'https://api.zyte.com/v1/search', [
'auth' => ['YOUR_ZYTE_API_KEY', ''],
'json' => [
'domain' => 'search.engine.com',
'query' => 'web scraping tools',
'include' => ['organic'],
'queryParameters' => [
'style' => 'engineSpecific',
'gl' => 'us',
'hl' => 'en',
],
],
]);
api_response = requests.post(
"https://api.zyte.com/v1/search",
auth=("YOUR_ZYTE_API_KEY", ""),
json={
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"],
"queryParameters": {
"style": "engineSpecific",
"gl": "us",
"hl": "en",
},
},
)
organic_results = api_response.json()["organicResults"]
api_response = requests.post(
"https://api.zyte.com/v1/search",
auth=("YOUR_ZYTE_API_KEY", ""),
json={
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["organic"],
"queryParameters": {
"style": "engineSpecific",
"gl": "us",
"hl": "en",
},
},
)
organic_results = api_response.json()["organicResults"]
For city-level targeting, add a uule value. Generate one from a city name
using the uule_grabber Python library:
import uule_grabber
uule_grabber.uule("Chicago, USA") # w+CAIQ...
AI Overview¶
Add "aiOverview" to include to trigger full browser rendering. The
AI Overview block will be present in the raw html field:
{
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["aiOverview", "organic", "html"]
}
curl \
--user YOUR_ZYTE_API_KEY: \
--header 'Content-Type: application/json' \
--data @input.json \
--compressed \
https://api.zyte.com/v1/search
var input = new Dictionary<string, object>(){
{"domain", "search.engine.com"},
{"query", "web scraping tools"},
{"include", new[] {"aiOverview", "organic", "html"}}
};
Map<String, Object> parameters =
ImmutableMap.of(
"domain", "search.engine.com",
"query", "web scraping tools",
"include", List.of("aiOverview", "organic", "html"));
axios.post(
'https://api.zyte.com/v1/search',
{
domain: 'search.engine.com',
query: 'web scraping tools',
include: ['aiOverview', 'organic', 'html']
},
{ auth: { username: 'YOUR_ZYTE_API_KEY' } }
).then((response) => {
const { organicResults, html } = response.data
console.log(organicResults)
})
$response = $client->request('POST', 'https://api.zyte.com/v1/search', [
'auth' => ['YOUR_ZYTE_API_KEY', ''],
'json' => [
'domain' => 'search.engine.com',
'query' => 'web scraping tools',
'include' => ['aiOverview', 'organic', 'html'],
],
]);
api_response = requests.post(
"https://api.zyte.com/v1/search",
auth=("YOUR_ZYTE_API_KEY", ""),
json={
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["aiOverview", "organic", "html"],
},
)
data = api_response.json()
organic_results = data["organicResults"]
html = data["html"] # parse AI Overview from here
api_response = requests.post(
"https://api.zyte.com/v1/search",
auth=("YOUR_ZYTE_API_KEY", ""),
json={
"domain": "search.engine.com",
"query": "web scraping tools",
"include": ["aiOverview", "organic", "html"],
},
)
data = api_response.json()
organic_results = data["organicResults"]
html = data["html"] # parse AI Overview from here
Note
Parsed aiOverview extraction is coming in a future release. For now,
the AI Overview block is available in the raw html field.
Next steps¶
Request parameters — full parameter reference
Response schema — response field details
Geo-targeting — geo-targeting by country, language, and domain