Web search
Models only know what was in their training data. FreeTheAI has two ways to bring in current information from the web.
| Way | Works with | Use it when |
|---|---|---|
POST /v1/search and POST /v1/answer | Any model, any app, any code | You want results or a short answer to use yourself or put in a prompt |
web_search_options and web_search tools | fta/dog/ and fta/lion/ models | You want the model to search on its own and cite its sources |
Search and Answer endpoints
/v1/search returns current results (title, link, and a text excerpt when available). /v1/answer returns a short written answer in Markdown with the sources it used; it takes a few seconds longer than a search.
curl https://api.freetheai.org/v1/search \
-H "Authorization: Bearer $FTAI_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "latest stable Python release", "num_results": 5}'Both use your API key and share one small daily web-search allowance, separate from your free requests. Every response tells you where you stand with daily_used and daily_limit, and the allowance resets at 00:00 UTC. Identical queries within an hour return the same results.
Give the results to any model
import os
import requests
from openai import OpenAI
KEY = os.environ["FTAI_KEY"]
client = OpenAI(base_url="https://api.freetheai.org/v1", api_key=KEY)
question = "What changed in the latest stable Python release?"
found = requests.post(
"https://api.freetheai.org/v1/search",
headers={"Authorization": f"Bearer {KEY}"},
json={"query": "latest stable Python release notes", "num_results": 5},
timeout=60,
).json()
sources = "\n\n".join(
f"[{i + 1}] {r['title']} ({r['url']})\n{r.get('text', '')[:1500]}"
for i, r in enumerate(found["results"])
)
reply = client.chat.completions.create(
model="fta/zai/glm-5.3",
messages=[
{"role": "system", "content": "Answer from the sources below and cite them as [1], [2].\n\n" + sources},
{"role": "user", "content": question},
],
)
print(reply.choices[0].message.content)Let the model search
The fta/dog/ and fta/lion/ models can search the web before they answer. Ask for it in the format you use:
{
"model": "fta/dog/gpt-6-luna",
"web_search_options": {},
"messages": [{ "role": "user", "content": "What is the weather in Lisbon this week?" }]
}{
"model": "fta/dog/gpt-6-luna",
"tools": [{ "type": "web_search" }],
"input": "What is the weather in Lisbon this week?"
}{
"model": "fta/dog/gpt-6-luna",
"max_tokens": 1024,
"tools": [{ "type": "web_search_20250305", "name": "web_search" }],
"messages": [{ "role": "user", "content": "What is the weather in Lisbon this week?" }]
}On Chat Completions the sources come back as url_citation annotations on the reply message (or on the stream delta):
{
"role": "assistant",
"content": "Expect mild days around 19°C with rain on Thursday...",
"annotations": [
{ "type": "url_citation", "url_citation": { "url": "https://...", "title": "Lisbon weather forecast" } }
]
}Other models do not search this way; leave these options out and use /v1/search as shown above. Model IDs change, so check the Models page for the current fta/dog/ and fta/lion/ models.

