Skip to content

Search and read the web

Urai gives you two built-in tools for the web.

  • web_search finds pages. Each result has a title, a URL, and a short description.
  • web_fetch reads pages. It reads more than one URL in one call. It returns the text of each page.

Name these tools in tools[]. Urai does the search and the reads on the server. You get the answer in one response. Your code does not run a tool call.

Terminal window
curl https://chat.app.urai.dev/api/openai/v1/chat/completions \
-H "Authorization: Bearer $URAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-haiku-4-5",
"messages": [
{ "role": "user", "content": "What is in the latest Rust release? Give your sources." }
],
"tools": [
{ "type": "function", "function": { "name": "web_search" } },
{ "type": "function", "function": { "name": "web_fetch" } }
]
}'

The same request from an OpenAI SDK:

response = client.chat.completions.create(
model="anthropic/claude-haiku-4-5",
messages=[{"role": "user",
"content": "What is in the latest Rust release? Give your sources."}],
tools=[
{"type": "function", "function": {"name": "web_search"}},
{"type": "function", "function": {"name": "web_fetch"}},
],
)
print(response.choices[0].message.content)

Do not send parameters for these two tools. Urai supplies the two schemas.

The response is an assistant message with finish_reason: "stop". Urai completes the search and the page reads before it sends the response.

web_search returns a title and two lines of text for each result. This is sufficient to name a source. It is not sufficient to answer a question about the content of the source.

web_fetch gives the model the full text. The model selects the results to read. Urai reads them. The model then writes the answer.

web_fetch uses many tokens. The pages fill the largest part of the prompt. A question about a new subject can use more than 10,000 prompt tokens. The usage object shows this count. For a short question, do not name web_fetch.

Each provider has a different name for these tools. Some providers do the search themselves. You always use the same two names. Urai sends the correct tool to the provider.

Provider web_search runs as web_fetch runs as Credentials
gemini, vertex, google Gemini’s googleSearch Gemini’s urlContext None
openai OpenAI’s own web search Jina, run by Urai Jina
anthropic Anthropic’s own web search Jina, run by Urai Jina
Every other provider, such as openrouter Brave Search, run by Urai Jina, run by Urai Brave Search and Jina

Two conditions apply to this table.

  • Gemini uses googleSearch and urlContext together. Thus Urai adds urlContext when you name web_search, also when you do not name web_fetch. On Gemini, web_fetch gives you urlContext and not Jina. A different fetch tool with these two tools causes errors in the model.
  • OpenAI does its own search on Responses API models only. These are the gpt-5, the codex, and the pro models. On an older Chat Completions model, web_search is a usual function, and Urai does the search with Brave Search. This needs the Brave Search credential.

When the provider does the search itself, you configure nothing. The provider puts the results in its own answer.

Urai adds a note to your last user message. This occurs on all providers except OpenAI and Gemini.

Current timestamp: 2026-08-13T19:35:01.369771+00:00
[Note: You have access to the `web_search` tool for searching the web and the
`web_fetch` tool for reading the full content of web pages. Follow this workflow:
1. Use `web_search` to find relevant URLs.
2. ALWAYS use `web_fetch` to read the content of the most relevant URLs from the
search results...]

The timestamp gives the model the current date and time. The model uses it to find out if its own data is old. The note tells the model to read the pages. Without the note, the model answers from the short descriptions in the search results.

The note agrees with the tools that you name. If you name only web_search, the note does not mention web_fetch.

Urai puts the note in the user message and not in the system prompt. Providers keep a cache of the system prompt, and the timestamp is different for each call. In the system prompt, the timestamp makes that cache invalid for each call.

Urai adds the note to the request only. Urai does not write the note in the stored thread. Thus a thread that you continue with x-thread-id does not repeat an old timestamp.

Tool Provider Credential
web_search Not openai, anthropic, or Gemini brave_search
web_fetch Not Gemini jina

A credential applies to the full organization. An administrator connects it at Settings → Credentials.

Urai examines the credentials when the request arrives. A request without the necessary credential fails immediately, and not at the tool call:

{
"error": {
"message": "web_fetch requires a Jina credential for this organization",
"type": "invalid_request_error",
"param": "tools",
"code": "tool_not_configured"
}
}
  • The response has the answer only. Urai does the tool calls on the server, and the tool calls are not in the response.
  • usage counts the full request. This includes the tokens for the search results and for the pages.
  • Streaming operates in the usual manner. The tool rounds occur in the stream. The model can write text between two rounds, before the final answer.
  • A request does 10 tool rounds at a maximum. Then Urai stops and sends the text of the model.

Urai keeps a cache of each page that it reads. If a recent turn read the same URL, Urai uses the cache and does not read the page again.

Name the web tools and your UraiJS tools in the same request. The model selects between them.

{
"model": "anthropic/claude-haiku-4-5",
"messages": [
{ "role": "user", "content": "Does the vendor on order 4471 have an outage now?" }
],
"tools": [
{ "type": "function", "function": { "name": "orders" } },
{ "type": "function", "function": { "name": "web_search" } },
{ "type": "function", "function": { "name": "web_fetch" } }
],
"metadata": { "account_id": "acct_8812" }
}

See Call your UraiJS tools for the way metadata goes to your own tools. See Search knowledge collections for the two tools that read your uploaded documents.