Web search
Endpoint
Search is a single authenticated POST to https://gateway.codegraff.com/v1/search. The only required field is query:
curl https://gateway.codegraff.com/v1/search \
-H "Authorization: Bearer cg_sk_your_key" \
-H "Content-Type: application/json" \
-d '{"query": "how does HTTP/3 differ from HTTP/2", "numResults": 5}'The gateway runs the search server-side and bills the result to your account, so the call never needs a search-provider key. Just use your cg_sk_ key. GET /v1/models advertises this capability as "available_tools": ["web_search"].
TypeScript
It is a plain REST endpoint, so any HTTP client works. No SDK is required. Using fetch:
const res = await fetch("https://gateway.codegraff.com/v1/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CODEGRAFF_API_KEY}`, // cg_sk_...
"Content-Type": "application/json",
},
body: JSON.stringify({
query: "how does HTTP/3 differ from HTTP/2",
numResults: 5,
}),
});
const data = await res.json();
for (const r of data.results) {
console.log(r.title, "|", r.url);
}
console.log("cost:", data.codegraff_usage.cost_micro_usd, "µUSD");Python
The same call with requests (or any HTTP client, including httpx, aiohttp, the stdlib):
import os
import requests
res = requests.post(
"https://gateway.codegraff.com/v1/search",
headers={"Authorization": f"Bearer {os.environ['CODEGRAFF_API_KEY']}"}, # cg_sk_...
json={
"query": "how does HTTP/3 differ from HTTP/2",
"numResults": 5,
},
)
data = res.json()
for r in data["results"]:
print(r["title"], "|", r["url"])
print("cost:", data["codegraff_usage"]["cost_micro_usd"], "µUSD")Parameters
Send these as JSON fields in the request body. Only query is required; the rest mirror the underlying search API.
| Field | Type | Default | Notes |
|---|---|---|---|
query | string | required | The search query. An empty or missing value returns a 400. |
type | string | "auto" | Search mode: auto, neural, or keyword. |
numResults | number | 5 | Number of results to return. Clamped to a maximum of 20. |
contents | object | { text: { maxCharacters: 3000 } } | What to pull back per result. Defaults to up to 3,000 characters of page text. |
category | string | None | Narrow to a content category, e.g. company, research paper, or github. |
includeDomains | string[] | None | Only return results from these domains. |
excludeDomains | string[] | None | Drop results from these domains. |
Response
The response is the search result set plus a codegraff_usage block that reports what the call cost and your remaining balance. Upstream cost details are stripped:
{
"results": [
{
"title": "HTTP/3 explained",
"url": "https://example.com/http3",
"publishedDate": "2026-01-15",
"author": "Jane Doe",
"text": "…up to maxCharacters of page text…"
}
],
"codegraff_usage": {
"cost_micro_usd": 7700,
"balance_micro_usd": 4992300
}
}Pricing
Credits & cost
$0.03 up front, then settles to the actual upstream cost plus a 10% margin, with a $0.005 floor. The final cost is typically well under a cent. You need at least $0.03 in credits to start a search, or the call returns 402 insufficient_credits. Costs are reported in micro-USD (1,000,000 µUSD = $1).Hosted web_search tool
OpenAI models (gpt-6-astra, gpt-6-sol, gpt-6-luna and the gpt-5.6 family) can also search the web themselves. Add {"type": "web_search"} to the tools array of a Responses API request, over HTTP or WebSocket. The model decides when to search and cites its sources in the answer:
curl https://gateway.codegraff.com/v1/responses \
-H "Authorization: Bearer cg_sk_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-luna",
"tools": [{"type": "web_search"}],
"input": "What changed in the latest Node.js release?"
}'How it's billed
$0.011, shown as its own web_searchline in your usage. Opening a page or searching within one is free. The page text the model reads is billed as ordinary input tokens at the model's rate. A request runs at most 10 tool calls (set max_tool_calls for fewer), and credits for the worst case are reserved up front, then settled to what was actually used.Other hosted tools (web_search_preview, file_search, code_interpreter, …), web_search on non-OpenAI models, and hosted tools on Chat Completions are rejected with hosted_tools_not_supported. Use /v1/search with those models, and your own JSON-schema function tools for everything else.