Web Search
The Responses API Beta supports web search integration, allowing models to access real-time information from the internet and provide responses with proper citations and annotations.
Web Search Plugin
Enable web search using the plugins parameter:
const response = await fetch("https://novapai.ai/api/v1/responses", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_NOVASTACK_AI_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/o4-mini",
input: "What is this platform?",
plugins: [{ id: "web", max_results: 3 }],
max_output_tokens: 9000,
}),
});
const result = await response.json();
console.log(result);Plugin Configuration
Configure web search behavior:
| Parameter | Type | Description |
|---|---|---|
id | string | Required. Must be “web” |
engine | string | Search engine: "native", "exa", "firecrawl", "parallel", or omit for auto |
max_results | integer | Maximum search results to retrieve (1-25, default 5) |
include_domains | string[] | Restrict results to these domains (supports wildcards like *.substack.com) |
exclude_domains | string[] | Exclude results from these domains |
See the Web Search plugin docs for full details on engine selection, domain filter compatibility, and pricing.
X Search Filters (xAI only)
When using xAI models (e.g. x-ai/grok-4.1-fast), you can pass x_search_filter as a top-level request parameter to filter X/Twitter search results:
{
"model": "x-ai/grok-4.1-fast",
"input": "What are people saying about AI?",
"plugins": [{ "id": "web" }],
"x_search_filter": {
"allowed_x_handles": ["example"],
"from_date": "2025-01-01",
"enable_image_understanding": true
}
}| Parameter | Type | Description |
|---|---|---|
allowed_x_handles | string[] | Only include posts from these handles (max 10) |
excluded_x_handles | string[] | Exclude posts from these handles (max 10) |
from_date | string | Start date (ISO 8601, e.g. "2025-01-01") |
to_date | string | End date (ISO 8601, e.g. "2025-12-31") |
enable_image_understanding | boolean | Analyze images in posts |
enable_video_understanding | boolean | Analyze videos in posts |
allowed_x_handles and excluded_x_handles are mutually exclusive. See the Web Search plugin docs for full details.
Structured Message with Web Search
Use structured messages for more complex queries:
const response = await fetch("https://novapai.ai/api/v1/responses", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_NOVASTACK_AI_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/o4-mini",
input: [
{
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "What was a positive news story from today?",
},
],
},
],
plugins: [{ id: "web", max_results: 2 }],
max_output_tokens: 9000,
}),
});
const result = await response.json();
console.log(result);Online Model Variants
Some models have built-in web search capabilities using the :online variant:
const response = await fetch("https://novapai.ai/api/v1/responses", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_NOVASTACK_AI_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/o4-mini:online",
input: "What was a positive news story from today?",
max_output_tokens: 9000,
}),
});
const result = await response.json();
console.log(result);Response with Annotations
Web search responses include citation annotations:
{
"id": "resp_1234567890",
"object": "response",
"created_at": 1234567890,
"model": "openai/o4-mini",
"output": [
{
"type": "message",
"id": "msg_abc123",
"status": "completed",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "This platform is a unified API for accessing multiple Large Language Model providers through a single interface. It allows developers to access 100+ AI models from providers like OpenAI, Anthropic, Google, and others with intelligent routing and automatic failover.",
"annotations": [
{
"type": "url_citation",
"url": "https://novapai.ai/docs",
"start_index": 0,
"end_index": 85
},
{
"type": "url_citation",
"url": "https://novapai.ai/models",
"start_index": 120,
"end_index": 180
}
]
}
]
}
],
"usage": {
"input_tokens": 15,
"output_tokens": 95,
"total_tokens": 110
},
"status": "completed"
}Annotation Types
Web search responses can include different annotation types:
URL Citation
{
"type": "url_citation",
"url": "https://example.com/article",
"start_index": 0,
"end_index": 50
}Complex Search Queries
Handle multi-part search queries:
const response = await fetch("https://novapai.ai/api/v1/responses", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_NOVASTACK_AI_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/o4-mini",
input: [
{
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "Compare OpenAI and Anthropic latest models",
},
],
},
],
plugins: [{ id: "web", max_results: 5 }],
max_output_tokens: 9000,
}),
});
const result = await response.json();
console.log(result);Web Search in Conversation
Include web search in multi-turn conversations:
const response = await fetch("https://novapai.ai/api/v1/responses", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_NOVASTACK_AI_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/o4-mini",
input: [
{
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "What is the latest version of React?",
},
],
},
{
type: "message",
id: "msg_1",
status: "in_progress",
role: "assistant",
content: [
{
type: "output_text",
text: "Let me search for the latest React version.",
annotations: [],
},
],
},
{
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "Yes, please find the most recent information",
},
],
},
],
plugins: [{ id: "web", max_results: 2 }],
max_output_tokens: 9000,
}),
});
const result = await response.json();
console.log(result);Streaming Web Search
Monitor web search progress with streaming:
const response = await fetch("https://novapai.ai/api/v1/responses", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_NOVASTACK_AI_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/o4-mini",
input: [
{
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "What is the latest news about AI?",
},
],
},
],
plugins: [{ id: "web", max_results: 2 }],
stream: true,
max_output_tokens: 9000,
}),
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split("\n");
for (const line of lines) {
if (line.startsWith("data: ")) {
const data = line.slice(6);
if (data === "[DONE]") return;
try {
const parsed = JSON.parse(data);
if (
parsed.type === "response.output_item.added" &&
parsed.item?.type === "message"
) {
console.log("Message added");
}
if (parsed.type === "response.completed") {
const annotations =
parsed.response?.output
?.find((o) => o.type === "message")
?.content?.find((c) => c.type === "output_text")?.annotations ||
[];
console.log("Citations:", annotations.length);
}
} catch (e) {
// Skip invalid JSON
}
}
}
}Annotation Processing
Extract and process citation information:
function extractCitations(response: any) {
const messageOutput = response.output?.find((o: any) => o.type === 'message');
const textContent = messageOutput?.content?.find((c: any) => c.type === 'output_text');
const annotations = textContent?.annotations || [];
return annotations
.filter((annotation: any) => annotation.type === 'url_citation')
.map((annotation: any) => ({
url: annotation.url,
text: textContent.text.slice(annotation.start_index, annotation.end_index),
startIndex: annotation.start_index,
endIndex: annotation.end_index,
}));
}
const result = await response.json();
const citations = extractCitations(result);
console.log('Found citations:', citations);Best Practices
. **Limit results**: Use appropriate `max_results` to balance quality and speed
. **Handle annotations**: Process citation annotations for proper attribution
. **Query specificity**: Make search queries specific for better results
. **Error handling**: Handle cases where web search might fail
. **Rate limits**: Be mindful of search rate limitsNext Steps
- Learn about Tool Calling integration
- Explore Reasoning capabilities
- Review Basic Usage fundamentals