Direct Web Search API
curl --request POST \
--url https://api.nano-gpt.com/api/web \
--header 'Content-Type: application/json' \
--data '
{
"query": "<string>",
"provider": "<string>",
"operation": "<string>",
"depth": "<string>",
"outputType": "<string>",
"structuredOutputSchema": "<string>",
"includeImages": true,
"fromDate": "<string>",
"toDate": "<string>",
"includeDomains": [
"<string>"
],
"excludeDomains": [
"<string>"
]
}
'import requests
url = "https://api.nano-gpt.com/api/web"
payload = {
"query": "<string>",
"provider": "<string>",
"operation": "<string>",
"depth": "<string>",
"outputType": "<string>",
"structuredOutputSchema": "<string>",
"includeImages": True,
"fromDate": "<string>",
"toDate": "<string>",
"includeDomains": ["<string>"],
"excludeDomains": ["<string>"]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
query: '<string>',
provider: '<string>',
operation: '<string>',
depth: '<string>',
outputType: '<string>',
structuredOutputSchema: '<string>',
includeImages: true,
fromDate: '<string>',
toDate: '<string>',
includeDomains: ['<string>'],
excludeDomains: ['<string>']
})
};
fetch('https://api.nano-gpt.com/api/web', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.nano-gpt.com/api/web",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'query' => '<string>',
'provider' => '<string>',
'operation' => '<string>',
'depth' => '<string>',
'outputType' => '<string>',
'structuredOutputSchema' => '<string>',
'includeImages' => true,
'fromDate' => '<string>',
'toDate' => '<string>',
'includeDomains' => [
'<string>'
],
'excludeDomains' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.nano-gpt.com/api/web"
payload := strings.NewReader("{\n \"query\": \"<string>\",\n \"provider\": \"<string>\",\n \"operation\": \"<string>\",\n \"depth\": \"<string>\",\n \"outputType\": \"<string>\",\n \"structuredOutputSchema\": \"<string>\",\n \"includeImages\": true,\n \"fromDate\": \"<string>\",\n \"toDate\": \"<string>\",\n \"includeDomains\": [\n \"<string>\"\n ],\n \"excludeDomains\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.nano-gpt.com/api/web")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"<string>\",\n \"provider\": \"<string>\",\n \"operation\": \"<string>\",\n \"depth\": \"<string>\",\n \"outputType\": \"<string>\",\n \"structuredOutputSchema\": \"<string>\",\n \"includeImages\": true,\n \"fromDate\": \"<string>\",\n \"toDate\": \"<string>\",\n \"includeDomains\": [\n \"<string>\"\n ],\n \"excludeDomains\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nano-gpt.com/api/web")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": \"<string>\",\n \"provider\": \"<string>\",\n \"operation\": \"<string>\",\n \"depth\": \"<string>\",\n \"outputType\": \"<string>\",\n \"structuredOutputSchema\": \"<string>\",\n \"includeImages\": true,\n \"fromDate\": \"<string>\",\n \"toDate\": \"<string>\",\n \"includeDomains\": [\n \"<string>\"\n ],\n \"excludeDomains\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": [
{}
],
"metadata": {
"query": "<string>",
"provider": "<string>",
"operation": "<string>",
"depth": "<string>",
"outputType": "<string>",
"timestamp": "<string>",
"cost": 123
}
}Endpoint Examples
Direct Web Search API
Run direct web search requests with explicit query control, provider-specific options, and Sofya search, fetch, extract, and research operations
POST
/
api
/
web
Direct Web Search API
curl --request POST \
--url https://api.nano-gpt.com/api/web \
--header 'Content-Type: application/json' \
--data '
{
"query": "<string>",
"provider": "<string>",
"operation": "<string>",
"depth": "<string>",
"outputType": "<string>",
"structuredOutputSchema": "<string>",
"includeImages": true,
"fromDate": "<string>",
"toDate": "<string>",
"includeDomains": [
"<string>"
],
"excludeDomains": [
"<string>"
]
}
'import requests
url = "https://api.nano-gpt.com/api/web"
payload = {
"query": "<string>",
"provider": "<string>",
"operation": "<string>",
"depth": "<string>",
"outputType": "<string>",
"structuredOutputSchema": "<string>",
"includeImages": True,
"fromDate": "<string>",
"toDate": "<string>",
"includeDomains": ["<string>"],
"excludeDomains": ["<string>"]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
query: '<string>',
provider: '<string>',
operation: '<string>',
depth: '<string>',
outputType: '<string>',
structuredOutputSchema: '<string>',
includeImages: true,
fromDate: '<string>',
toDate: '<string>',
includeDomains: ['<string>'],
excludeDomains: ['<string>']
})
};
fetch('https://api.nano-gpt.com/api/web', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.nano-gpt.com/api/web",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'query' => '<string>',
'provider' => '<string>',
'operation' => '<string>',
'depth' => '<string>',
'outputType' => '<string>',
'structuredOutputSchema' => '<string>',
'includeImages' => true,
'fromDate' => '<string>',
'toDate' => '<string>',
'includeDomains' => [
'<string>'
],
'excludeDomains' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.nano-gpt.com/api/web"
payload := strings.NewReader("{\n \"query\": \"<string>\",\n \"provider\": \"<string>\",\n \"operation\": \"<string>\",\n \"depth\": \"<string>\",\n \"outputType\": \"<string>\",\n \"structuredOutputSchema\": \"<string>\",\n \"includeImages\": true,\n \"fromDate\": \"<string>\",\n \"toDate\": \"<string>\",\n \"includeDomains\": [\n \"<string>\"\n ],\n \"excludeDomains\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.nano-gpt.com/api/web")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"<string>\",\n \"provider\": \"<string>\",\n \"operation\": \"<string>\",\n \"depth\": \"<string>\",\n \"outputType\": \"<string>\",\n \"structuredOutputSchema\": \"<string>\",\n \"includeImages\": true,\n \"fromDate\": \"<string>\",\n \"toDate\": \"<string>\",\n \"includeDomains\": [\n \"<string>\"\n ],\n \"excludeDomains\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nano-gpt.com/api/web")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": \"<string>\",\n \"provider\": \"<string>\",\n \"operation\": \"<string>\",\n \"depth\": \"<string>\",\n \"outputType\": \"<string>\",\n \"structuredOutputSchema\": \"<string>\",\n \"includeImages\": true,\n \"fromDate\": \"<string>\",\n \"toDate\": \"<string>\",\n \"includeDomains\": [\n \"<string>\"\n ],\n \"excludeDomains\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": [
{}
],
"metadata": {
"query": "<string>",
"provider": "<string>",
"operation": "<string>",
"depth": "<string>",
"outputType": "<string>",
"timestamp": "<string>",
"cost": 123
}
}Overview
UsePOST /api/web when you want direct control over search requests and output formatting.
You can also call this tool through the unified Data API at POST /api/v1/data/web/search. The Data API preserves this endpoint’s request body, response body, billing, and provider behavior while adding discovery and dispatch metadata.
For chat-first workflows, use POST /api/v1/chat/completions with model suffixes like :online, :online/linkup, or :online/sofya, including provider-specific suffixes such as :online/exa-instant, :online/exa-deep-reasoning, :online/brave, and :online/valyu-web-deep. See Model Suffixes.
Sofya can do more than search on this endpoint. Set provider: "sofya" and choose the search, fetch, extract, or research operation.
See hosted-key pricing before choosing a provider. Chat search also incurs the selected model’s token charges. BYOK uses your own provider account and that provider’s billing; it does not make provider usage free.
When to use which endpoint
| Use case | Endpoint |
|---|---|
| You want the model to answer with web context in one call | POST /api/v1/chat/completions + :online... |
| You want one discoverable endpoint family for data tools | POST /api/v1/data/web/search |
You need explicit control over query, outputType, domain/date filters, or structured schema output | POST /api/web |
| You need OpenAI-native web search | POST /api/v1/chat/completions only |
Authentication
Either auth header is supported:string
Bearer
YOUR_API_KEYstring
YOUR_API_KEYAccountless x402 Payment
For accountless payment, prefer the public Data API path:curl -i https://api.nano-gpt.com/api/v1/data/web/search \
-H "Content-Type: application/json" \
-H "x-x402: true" \
-d '{
"query": "What happened in AI this week?",
"provider": "linkup",
"depth": "standard",
"outputType": "sourcedAnswer"
}'
Authorization or x-api-key, and include x-x402: true. NanoGPT will return 402 Payment Required with available payment options. This endpoint supports accountless x402 payments where listed by GET /api/v1/x402/endpoints, including Lightning L402 when advertised. See Accountless x402 API Payments for the full flow.
If you receive 401 missing_api_key immediately, check that the initial quote request includes x-x402: true. Without that header, NanoGPT does not enter the x402 quote flow.
Request body
string
Search or research query. Required for every provider’s search operation and for Sofya research. Not used by Sofya fetch or extract.
string
default:"linkup"
Search provider:
linkup, tavily, exa, kagi, perplexity, valyu, brave, sofya, or firecrawl. openai-native is not allowed on /api/web.string
default:"search"
Sofya operation:
search, fetch, extract, or research. Other providers support search only.string
default:"standard"
Search depth. For Linkup:
standard or deep.For Linkup,
depth: "standard" is executed as Linkup fast under the hood.string
default:"searchResults"
Output mode. Allowed values:
searchResults, sourcedAnswer, structured.string
Required when
outputType is structured. Pass a JSON schema string.boolean
default:false
Include image results.
string
Earliest result date (
YYYY-MM-DD).string
Latest result date (
YYYY-MM-DD).string[]
Restrict results to these domains.
string[]
Exclude these domains.
Linkup supports
outputType: "searchResults", "sourcedAnswer", and "structured".
Non-Linkup providers currently support only outputType: "searchResults".Sofya operations
Sofya Search returns extracted page content instead of snippets alone. The other operations let you fetch known URLs, extract requested information from one page, or produce a cited multi-source research report.Search
Useoperation: "search" or omit operation.
query(string, required)maxResults(integer, 1-20; default 10)topic(generalornews)freshness(day,week,month,year, orYYYY-MM-DD:YYYY-MM-DD)includeDomains/excludeDomains(up to 10 strings each)
Fetch
Useoperation: "fetch" with:
urls(array of 1-10 URL strings, required)includeRawHtmlorinclude_raw_html(boolean)
Extract
Useoperation: "extract" with:
url(string, required)prompt(string, required), describing what to extract
Research
Useoperation: "research" with:
query(string, required)topic(generalornews)freshness(day,week,month,year, orYYYY-MM-DD:YYYY-MM-DD)maxSourcesormax_sources(integer, 5-30)
Response shape
array|object
Provider-formatted payload.
object
searchResults, data is normally an array of normalized results. Sofya extract and research return an object, while Sofya fetch returns an array.
For sourcedAnswer and structured, data is the provider response object.
Example response
{
"data": "... provider-formatted payload ...",
"metadata": {
"query": "string",
"provider": "linkup",
"depth": "standard",
"outputType": "sourcedAnswer",
"timestamp": "ISO-8601",
"cost": 0.006
}
}
Pricing (hosted key)
| Mode | Price |
|---|---|
| Linkup standard | $0.006 |
| Linkup deep | $0.06 |
| Sofya search | $0.01575 |
| Sofya fetch | $0.00525 per URL |
| Sofya extract | $0.02625 |
| Sofya research | $0.13125 |
Error codes
| HTTP status | Meaning |
|---|---|
400 | Invalid parameters |
401 | Invalid session or auth |
402 | Insufficient balance or usage cap |
429 | Rate limited |
503 | Provider key missing |
504 | Search failed or timed out |
Examples
curl -X POST https://api.nano-gpt.com/api/web \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "What happened in AI this week?",
"provider": "linkup",
"depth": "standard",
"outputType": "sourcedAnswer"
}'
curl -X POST https://api.nano-gpt.com/api/web \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "Latest OpenAI announcements",
"provider": "linkup",
"depth": "deep",
"outputType": "searchResults"
}'
curl -X POST https://api.nano-gpt.com/api/web \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "Top 5 AI coding tools in 2026 with pricing",
"provider": "linkup",
"depth": "standard",
"outputType": "structured",
"structuredOutputSchema": "{\"type\":\"object\",\"properties\":{\"tools\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"price\":{\"type\":\"string\"}},\"required\":[\"name\"]}}},\"required\":[\"tools\"]}"
}'
curl -X POST https://api.nano-gpt.com/api/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o:online/linkup",
"messages": [
{ "role": "user", "content": "Summarize today'\''s top AI headlines." }
]
}'
curl -X POST https://api.nano-gpt.com/api/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o:online/sofya",
"messages": [
{ "role": "user", "content": "Summarize today'\''s top AI headlines." }
]
}'
Sofya examples
curl -X POST https://api.nano-gpt.com/api/web \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "sofya",
"operation": "search",
"query": "NanoGPT API documentation",
"maxResults": 10,
"topic": "general"
}'
curl -X POST https://api.nano-gpt.com/api/web \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "sofya",
"operation": "fetch",
"urls": ["https://sofya.co/docs"],
"includeRawHtml": false
}'
curl -X POST https://api.nano-gpt.com/api/web \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "sofya",
"operation": "extract",
"url": "https://sofya.co/pricing",
"prompt": "Extract the available plans and their prices."
}'
curl -X POST https://api.nano-gpt.com/api/web \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "sofya",
"operation": "research",
"query": "Compare current AI web search APIs",
"maxSources": 15
}'