Tools
X Search
The X Search tool enables Grok to perform keyword search, semantic search, user search, and thread fetch on X (formerly Twitter). This powerful tool allows the model to access real-time social media content, analyze posts, and gather insights from X's vast data.
X Search is billed at $5 per 1k posts fetched and $10 per 1k user profiles fetched, in addition to token costs; see tool invocation costs for what counts as a fetched post or profile.
SDK Support
| SDK/API | Tool Name |
|---|---|
| xAI SDK | x_search |
| OpenAI Responses API | x_search |
| Vercel AI SDK | xai.tools.xSearch() |
This tool is also supported in all Responses API compatible SDKs.
Basic Usage
import os
from xai_sdk import Client
from xai_sdk.chat import user
from xai_sdk.tools import x_search
client = Client(api_key=os.getenv("XAI_API_KEY"))
chat = client.chat.create(
model="grok-4.7", # reasoning model
tools=[x_search()],
include=["verbose_streaming"],
)
chat.append(user("What are people saying about xAI on X?"))
is_thinking = True
for response, chunk in chat.stream():
for tool_call in chunk.tool_calls:
print(f"\nCalling tool: {tool_call.function.name} with arguments: {tool_call.function.arguments}")
if response.usage.reasoning_tokens and is_thinking:
print(f"\rThinking... ({response.usage.reasoning_tokens} tokens)", end="", flush=True)
if chunk.content and is_thinking:
print("\n\nFinal Response:")
is_thinking = False
if chunk.content and not is_thinking:
print(chunk.content, end="", flush=True)
print("\n\nCitations:")
print(response.citations)X Search Parameters
| Parameter | Description |
|---|---|
allowed_x_handles | Only consider posts from specific X handles (max 20) |
excluded_x_handles | Exclude posts from specific X handles (max 20) |
from_date | Start date for search range (ISO8601 format) |
to_date | End date for search range (ISO8601 format) |
enable_image_understanding | Enable analysis of images in posts |
enable_video_understanding | Enable analysis of videos in posts |
Only Consider Posts from Specific Handles
Use allowed_x_handles to consider X posts only from a given list of X handles. The maximum number of handles you can include is 20.
allowed_x_handles cannot be set together with excluded_x_handles in the same request.
import os
from xai_sdk import Client
from xai_sdk.chat import user
from xai_sdk.tools import x_search
client = Client(api_key=os.getenv("XAI_API_KEY"))
chat = client.chat.create(
model="grok-4.7",
tools=[
x_search(allowed_x_handles=["elonmusk"]),
],
)
chat.append(user("What is the current status of xAI?"))
# stream or sample the response...Exclude Posts from Specific Handles
Use excluded_x_handles to prevent the model from including X posts from the specified handles in any X search tool invocations. The maximum number of handles you can exclude is 20.
chat = client.chat.create(
model="grok-4.7",
tools=[
x_search(excluded_x_handles=["elonmusk"]),
],
)Date Range
You can restrict the date range of search data used by specifying from_date and to_date. This limits the data to the period from from_date to to_date, including both dates.
Both fields need to be in ISO8601 format, e.g., "YYYY-MM-DD". If you're using the xAI Python SDK, the from_date and to_date fields can be passed as datetime.datetime objects.
import os
from datetime import datetime
from xai_sdk import Client
from xai_sdk.chat import user
from xai_sdk.tools import x_search
client = Client(api_key=os.getenv("XAI_API_KEY"))
chat = client.chat.create(
model="grok-4.7",
tools=[
x_search(
from_date=datetime(2025, 10, 1),
to_date=datetime(2025, 10, 10),
),
],
)
chat.append(user("What is the current status of xAI?"))
# stream or sample the response...Enable Image Understanding
Setting enable_image_understanding to true allows the agent to analyze images in X posts encountered during the search process.
chat = client.chat.create(
model="grok-4.7",
tools=[
x_search(enable_image_understanding=True),
],
)Enable Video Understanding
Setting enable_video_understanding to true allows the agent to analyze videos in X posts. This is only available for X Search (not Web Search).
chat = client.chat.create(
model="grok-4.7",
tools=[
x_search(enable_video_understanding=True),
],
)Usage counts
Each Responses API response that ran X Search reports how many items it fetched, so you can reconcile a request against the per-item pricing in effect as of September 21, 2026. The counts live under usage.server_side_tool_usage_details, next to the per-call x_search_calls:
| Field | Counts |
|---|---|
x_posts_fetched | Posts returned by x_keyword_search, x_semantic_search, and x_thread_fetch, including parent and quoted posts and every post of a fetched thread |
x_users_fetched | User profiles returned by x_user_search |
Both counts accumulate over every X Search call in the request and are not de-duplicated; a post returned by two searches counts twice. When streaming, the usage on the terminal event (response.completed, or response.incomplete when the response was truncated) is the total for the request.
The server_side_tool_usage_details block of a /v1/responses usage object after two X searches looks like this:
JSON
"server_side_tool_usage_details": {
"web_search_calls": 0,
"x_search_calls": 2,
"x_posts_fetched": 44,
"x_users_fetched": 3,
"code_interpreter_calls": 0,
"file_search_calls": 0,
"mcp_calls": 0,
"document_search_calls": 0,
"image_generation_calls": 0
}
Citations
For details on how to retrieve and use citations from search results, see the Citations page.
Last updated: September 22, 2026