JSON API
query the web, images, and news over a single public endpoint and get back clean, structured JSON: the exact same data that powers the results pages, with none of the HTML.
the API is public: no key, no signup, no auth header. there are no rate limits or pagination caps either, so be a good citizen, the upstream is shared.
making a request
send a POST to /api with a JSON body.
POST /api
Content-Type: application/json
{
"query": "metasearch",
"type": "web",
"page": 0
}
request fields
| field | type | description |
|---|---|---|
query |
string | required. the search query. |
type |
string |
optional, defaults to web. one of web,
images, news.
|
page |
integer |
optional, defaults to 0. the result offset. 0 is the
first page; increment to paginate. no upper bound.
|
examples
curl
curl -X POST https://search.tiago.zip/api \
-H "Content-Type: application/json" \
-d '{"query":"metasearch","type":"web","page":0}'
javascript
const res = await fetch("https://search.tiago.zip/api", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ query: "metasearch", type: "web", page: 0 }),
});
const data = await res.json();
console.log(data.results);
responses
every successful response echoes query, type, and
page, exposes more_results_available so you know whether to
fetch the next page, and carries the results for the requested type.
web (type: "web")
results is an object grouping the different result kinds. fields are
null when absent for a given query.
{
"query": "metasearch",
"type": "web",
"page": 0,
"badResults": false,
"more_results_available": true,
"results": {
"web": {
"results": [
{
"title": "…",
"url": "https://…",
"description": "…",
"age": "…",
"meta_url": { "hostname": "…", "favicon": "…" },
"profile": { "name": "…", "img": "…" },
"thumbnail": { "src": "…" },
"deep_results": { "buttons": [{ "title": "…", "url": "…" }] },
"cluster": [{ "title": "…", "label": "…", "url": "…", "description": "…" }]
}
]
},
"news": { "results": [ … ] },
"videos": { "results": [ … ] },
"discussions": { "results": [ … ] },
"faq": { "results": [ … ] },
"infobox": { "results": [ … ] },
"rich": [ … ],
"qanda": …,
"locations": …,
"images": …,
"mixed": [ … ]
}
}
rich carries instant answers (calculator, weather, currency, crypto,
timezones, unit conversions, and more), each tagged with a subtype.
mixed mirrors the upstream ordering of the main column.
images (type: "images")
{
"query": "teto",
"type": "images",
"page": 0,
"more_results_available": true,
"results": [
{
"title": "…",
"url": "https://…",
"source": "…",
"thumbnail": "https://…",
"properties": { "url": "https://…", "width": 1200, "height": 800 },
"meta_url": { "hostname": "…", "favicon": "…" }
}
]
}
news (type: "news")
{
"query": "elections",
"type": "news",
"page": 0,
"more_results_available": true,
"results": [
{
"title": "…",
"url": "https://…",
"description": "…",
"age": "…",
"meta_url": { "hostname": "…", "favicon": "…" },
"profile": { "name": "…", "img": "…" },
"thumbnail": { "src": "…" },
"is_live": false
}
]
}
pagination
start at page: 0. if the response has
more_results_available: true, request page: 1, then
2, and so on. when it is false there is nothing more to fetch.
errors
errors come back as JSON with an error string and a matching status code.
| status | meaning |
|---|---|
400 |
bad body, missing query, unknown type, or invalid page. |
502 |
the upstream search failed. |
{ "error": "missing required field: query" }
autocomplete (/suggest)
send a GET to /suggest with a partial query.
GET /suggest?q=weath
query parameters
| param | type | description |
|---|---|---|
q |
string | required. the partial query to complete, up to 100 characters. |
response
suggestions is an ordered array. plain completions carry just a
query; rich entities (people, places, and more) set
entity and add the best-effort fields below.
{
"suggestions": [
{ "query": "weather" },
{ "query": "weather radar" },
{
"query": "elon musk",
"entity": true,
"name": "Elon Musk",
"desc": "businessman and entrepreneur (born 1971)",
"category": "person",
"img": "https://imgs.search.brave.com/…"
}
]
}
| field | type | description |
|---|---|---|
query |
string | the suggested query. always present. |
entity |
boolean | true on entity suggestions; absent otherwise. |
name |
string | the entity's display name. |
desc |
string | a short description. |
category |
string | e.g. person, place. |
img |
string | thumbnail URL, when one is available. |
curl
curl "https://search.tiago.zip/suggest?q=weath"
notes
- CORS is open, so the endpoint is reachable directly from the browser.
- no rate limits are enforced by the API itself. be a good citizen: the upstream is shared.
- no logging. queries sent through the API are not stored, same as the website.
made and hosted in the EU 🇪🇺