Introducing an xAI X Search Skill for Cost-Aware Agents
Keep agent searches cheap, bounded, and inspectable with xAI’s server-side X Search tool.
I spend a fair amount of time writing in English, and a fair amount of that writing starts as a question I can’t answer from training data alone: did anyone on X actually say this, or is this just vibes?
That’s the whole reason I built xai-x-search-skill. Not because calling an API is hard — it’s one JSON field — but because the moment you wire X search into an agent loop, the model will happily search three times when one would have done, and your bill grows in steps of half a cent that somehow add up faster than you expect.
This post is a field note from shipping that skill: how we got from “search Twitter” to server-side x_search, what parameters actually matter, which models behave, how billing works in practice, and a small demo if you want to click around instead of reading curl.
A short history of searching X (and why agents care)
If you’ve been on the platform long enough, “search” has meant several different products.
The early years were pure inverted-index keyword search. Operators like from:, since:, filter:replies, and min_faves: became a craft. Power users lived in advanced search. Developers got the REST search endpoints, rate limits, and the usual timeline of “this GraphQL field moved again.”
Semantic search showed up later in the product UI — useful when you care about aboutness rather than exact tokens. “People complaining that AI essays all start with ‘In today’s fast-paced world’” is a terrible keyword query and a decent semantic one.
API access has always been the bottleneck for builders. Scrapers, unofficial clients, cookie-based CLIs, academic archives — the ecosystem filled the gaps when official access was expensive, restricted, or flaky. Fine for a side project. Miserable as a dependency inside an agent that needs to run unattended.
Then Grok got native X access, and xAI exposed it as a server-side tool on the Responses API: you don’t implement search yourself. You attach { "type": "x_search" } and the model decides when to fire keyword search, semantic search, user lookup, or thread fetch. That is a different contract than “here is a search endpoint, go paginate.”
That contract is also where costs get sneaky. More on that below.
What x_search is (public surface vs what the model actually runs)
From the outside, the API is almost boring:
POST https://api.x.ai/v1/responses
{
"model": "grok-4.3",
"input": [{ "role": "user", "content": "What are people saying about …" }],
"tools": [{ "type": "x_search" }]
}
You never call x_keyword_search yourself. Internally, though, successful X tool usage is categorized under server-side X search, and the implementation names you’ll see in traces are roughly:
| Internal tool | What it’s for |
|---|---|
x_keyword_search |
Classic operator-style / keyword / latest ranking |
x_semantic_search |
Meaning-based retrieval |
x_user_search |
Resolve or find accounts |
x_thread_fetch |
Pull a post + surrounding thread |
The skill’s rule is simple: agents talk to x_search; humans read the internal names only when debugging usage.
Docs also allow combining x_search with web_search in one request. The model will mix sources if the question needs both a tweet and a primary source. That’s powerful. It’s also how a “quick check” turns into a multi-tool agent turn if you don’t constrain it.
Parameters that actually matter
Official x_search tool parameters (as of the current docs):
| Parameter | Notes |
|---|---|
from_date / to_date |
YYYY-MM-DD. Inclusive range. Use them. Always. |
allowed_x_handles |
Allowlist, max 20 |
excluded_x_handles |
Blocklist, max 20 |
enable_image_understanding |
Lets the agent inspect images on posts (extra tokens) |
enable_video_understanding |
X-only; video analysis (extra tokens) |
Two things I wish I’d known on day one:
- You cannot set both
allowed_x_handlesandexcluded_x_handleson the same tool. The API returns 400. Pick a lane. - Date bounds are the cheapest precision you have. A vague query over “all time” invites extra internal searches. A week-long window with a tight keyword often finishes in one call.
Beyond the tool object, request-level knobs matter more for agents:
max_tool_calls— advisory. I have seen runs withmax_tool_calls: 1still report more than one server-side X search. Treat it as a hint, not a circuit breaker.- Prompt text — still the real throttle. “Use exactly one keyword/latest search; no semantic follow-ups” works better than optimism.
max_output_tokens— keep summaries short if you’re doing lookup, not essay generation.reasoning.effort— useful on models that support it; not universal (see below).
In the skill I only expose two modes, because that’s the tradeoff people actually make:
Cost-first (default)
One keyword/latest search. No semantic, no user search, no thread crawl unless the user pasted a status URL. Small result count. Low output budget. This is “is this claim even on the timeline?”
Quality-first
Semantic + keyword, optional user/thread context, higher call budget. This is “map the discussion and rank confidence.”
There is room for a middle tier (two calls: semantic + keyword). I didn’t add it in v1 on purpose. Two modes force a choice; three modes invite bikeshedding.
Which models you can use
Anything on the Responses path that is allowed to use server-side tools can, in principle, run x_search. In practice, behavior differs.
From my own live checks while building the skill (prices and IDs move — double-check console / docs):
| Model | Notes for X search |
|---|---|
grok-4.3 |
Best default for controlled search. Respects tight prompts; supports reasoning.effort. |
grok-4.20-0309-reasoning / non-reasoning |
Supports x_search, but reject reasoning: { effort: ... } with HTTP 400. Strip that block if you use these IDs. |
grok-4.5 |
Current docs examples often show 4.5. Smarter, pricier per token. Overkill if you only need three links. |
grok-build-0.1 |
Can call x_search, but it’s a coding model. In my tests it was eager to multi-search. I wouldn’t use it as a search workhorse. |
Personal take: for “verify a claim on X,” prefer a mid-tier chat model with a strict prompt over the flagship with a vague one. The expensive part is usually the extra tool invocations, not the difference between two token price cards.
Billing, without the happy path diagram
xAI bills tool-using requests on two axes:
- Tokens — input, output, reasoning, images, etc., at the model’s rate.
- Server-side tool invocations — successful calls only.
For X Search specifically, the public price is $5 per 1,000 invocations → $0.005 per successful x_search. Web Search is priced the same way. Image/video understanding on found media is token-based, not a separate per-call fee for the view tools.
The misconception that burns money:
“I only made one HTTP request to
/v1/responses, so I only paid for one search.”
No. One Responses call can contain multiple internal X searches. Keyword, then semantic, then a thread fetch — that’s three billable X tool uses, plus whatever tokens the agent burned planning them. Billable counts live in usage fields like server_side_tool_usage / server_side_tool_usage_details.x_search_calls (names vary slightly by SDK surface). Failed tool attempts don’t count; successful ones do.
Rough numbers from my June 2026 measurements (same query, your mileage will vary):
| Setup | x_search calls | Ballpark total |
|---|---|---|
grok-4.3 cost-first + strict prompt |
1 | ~$0.012–0.015 |
| Same model, loose prompt | 2 | ~$0.020–0.025 |
| Quality-first (~3 calls) | 3 | ~$0.025–0.035 |
So at cost-first rates, five dollars is a few hundred lookups, not “infinite social listening.” If you’re building a product that fans out agents, put a budget story in the skill before you put a nicer renderer in the UI.
That was the entire design thesis of xai-x-search-skill:
- Default to cost-first.
- Encode the limit in both
max_tool_callsand the instruction text. - Prefer date filters.
- Keep
SKILL.mdself-contained (a lot of agents only load that file). - Ship a small PowerShell helper that prints
x_search_callsand warns when reality exceeds the limit.
It’s not glamorous infrastructure. It’s seatbelts.
How the skill is structured (if you want to steal the pattern)
SKILL.md # what the agent reads: modes, payloads, failure modes
scripts/*.ps1 # optional CLI for humans / agents that can exec
agents/openai.yaml
README.md # humans, pricing tables, caveatsThe interesting part isn’t the PowerShell. It’s treating search policy as code you version with the agent. When the platform changes a default model or softens max_tool_calls, you update one skill instead of twelve prompts scattered across repos.
If you’re building skills for other tools (web search, code exec), the same split works: cheap default mode, explicit expensive mode, usage introspection after the call.
An online demo
Docs and skills are easy to skim without ever paying a cent of tool fees — which also means people never feel the “two internal searches” problem.
So I put up a small Next.js demo that mirrors the skill’s two modes:
https://xai-x-search-demo.vercel.app
You paste your own xAI key (browser localStorage only; the route proxies to xAI for that request and does not keep the key). Pick cost-first or quality-first, optional date range, run a search, get bookmark-style results. Successful runs snapshot into a local history modal so you can re-open bookmarks without spending again.
Source for the demo lives in a private repo on my GitHub and deploys from main to Vercel. The skill itself is public: Tan35/xai-x-search-skill.
I’m not going to claim the UI is the point. The point is you can feel the mode switch: one careful call versus “go dig.”
Closing notes
If you only take three things from this post:
x_searchis an agent tool, not a paginated Twitter API. The model chooses keyword vs semantic vs thread; you pay per successful internal call.- Parameters worth caring about: date range, handle allow/deny (not both), media understanding only when you need it, and prompt-level call discipline.
- Default cheap. Make expensive search an explicit user intent.
X is still one of the noisiest, fastest feedback loops on the public internet. Giving agents access without a cost story is how you learn what “$0.005” means the hard way. The skill is my cost story, written down so I don’t re-learn it every quarter.
References
- Skill: github.com/Tan35/xai-x-search-skill
- Demo: xai-x-search-demo.vercel.app
- Official X Search docs: docs.x.ai/developers/tools/x-search
- Pricing: docs.x.ai/docs/pricing
- Tool usage / billing details: docs.x.ai/developers/tools/tool-usage-details
Prices and model IDs change. Treat tables here as orientation, not a contract — verify against xAI’s docs before you put this in production.