Parallel tools
Web search, page reading, image search, place search and decisions with the parallel:* tools, alone or with Tako: a first request, Claude Code and Codex, cost from $0.001 a call.
The Parallel tools give a chat model the web through Parallel:
parallel:search: web search, with excerpts of each page;parallel:extract: reading the pages the model names;parallel:image_search: finding images (their URLs, source pages and sizes);parallel:place_search: finding places such as restaurants, shops and museums near a location;parallel:decisions: typed answers (a probability, a choice or a score) to questions, grounded in current web evidence, with the sources.
You add them to tools (or send one header), the model decides when to call them, the gateway runs each call, and you get one finished answer. They work with tako:search in the same request. This page takes you from a key to a first answer; Server tools is the full reference.
Quickstart
1. Get a key
Sign in and create a key at API keys. Use an organization key: the Parallel tools are billed per call to an organization.
2. Add paid credit
Add credit in Billing. Each search needs its $0.001, and each extract $0.001 for each URL it sends, in credit before it runs, on top of the model's own turns.
3. Export the key
export TM_API_KEY=tm_vk_...4. Send a first request
curl https://api.routerplus.com/v1/chat/completions \
-H "Authorization: Bearer $TM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-haiku-4-5",
"messages": [{"role": "user", "content": "Which RFC defines HTTP semantics, and what does it say a 404 means?"}],
"tools": [
{"type": "parallel:search", "parameters": {"max_uses": 3}},
{"type": "parallel:extract", "parameters": {"max_urls": 2}}
],
"tool_choice": {"type": "parallel:search"}
}'The same with the header instead of tools entries (default parameters):
curl https://api.routerplus.com/v1/chat/completions \
-H "Authorization: Bearer $TM_API_KEY" \
-H "Content-Type: application/json" \
-H "x-tm-tools: parallel:search, parallel:extract" \
-d '{"model": "claude-haiku-4-5", "messages": [{"role": "user", "content": "Which RFC defines HTTP semantics?"}]}'x-tm-tools: tako:search, parallel:search, parallel:extract turns on those three server tools; the header takes any of the seven values tako:search, parallel:search, parallel:extract, parallel:image_search, parallel:place_search, parallel:decisions and parallel:research (see Parallel research). It works on /v1/chat/completions, /v1/messages and /v1/responses.
A place search and a decision, with tools entries:
curl https://api.routerplus.com/v1/chat/completions \
-H "Authorization: Bearer $TM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-haiku-4-5",
"messages": [{"role": "user", "content": "Find two coffee shops open now in Shibuya, Tokyo, and tell me whether PostgreSQL 17 supports incremental backups."}],
"tools": [
{"type": "parallel:place_search", "parameters": {"max_results": 5}},
{"type": "parallel:decisions", "parameters": {"max_questions": 3}}
]
}'Claude Code and Codex
Set the harness up for RouterPlus first (Install). Then add the header.
Claude Code, in the env block of settings.json:
"env": { "ANTHROPIC_CUSTOM_HEADERS": "x-tm-tools: parallel:search,parallel:extract" }Codex, in the [model_providers.routerplus] block of ~/.codex/config.toml:
http_headers = { "x-tm-tools" = "parallel:search,parallel:extract" }Add tako:search to the same value for Tako's data cards as well, for example x-tm-tools: tako:search,parallel:search,parallel:extract. ANTHROPIC_CUSTOM_HEADERS takes one header per line: if you already send one, put x-tm-tools: ... on a line of its own. With the header set every request your harness sends can use the tools, and each answer arrives whole (no token streaming).
Codex repeats its searches. Codex does not keep the parallel_search_call and parallel_extract_call items in the history it sends back, so the model does not see that it already searched and may search again in each new request. You pay for each call ($0.001 to $0.005 a call, $0.001 a URL for an extract). A lower max_uses (in a tools entry) bounds the calls per request. Claude Code keeps the blocks and does not repeat them.
What ran live on dev (2026-11-04), with Claude Code 2.1.309 and Codex 0.163.0: parallel:search with Claude Code on claude-sonnet-5-5 and z-ai/glm-5.3 and with Codex on gpt-6-luna and moonshotai/kimi-k3; all three tools (tako:search, parallel:search, parallel:extract) with Claude Code on claude-sonnet-5-5. Not run: parallel:extract with Codex, Codex with all three tools, Codex on a Claude model, other harnesses and versions, and any production gateway. parallel:image_search, parallel:place_search and parallel:decisions were probed against Parallel's API (2026-11-06), not run through Claude Code or Codex.
What the model sees
Each tool is one function the model calls:
parallel_search(objective, search_queries): a sentence saying what it needs, and 1 to 5 short keyword queries (3 to 6 words each). Each search returns up tomax_resultsresults:url,title,publish_dateandexcerpts.parallel_extract(urls, objective): 1 tomax_urlsabsolute http(s) URLs and, optionally, what to look for. It returns each page'surl,title,publish_dateand theexcerptsthat matter,errors(urlanderror_type, such ashttp_errorfor a 404 orconnect_errorfor a host that does not exist) andnot_read(the URLs overmax_urls).parallel_image_search(objective, search_queries): 1 to 5 short keyword queries and, optionally, a sentence saying what images it needs. It returns up tomax_resultsimages:title,image_url,source_page_url,widthandheight(null when Parallel does not know them).parallel_place_search(query, location, latitude, longitude, max_distance_km, open_now): what to find (1 to 200 characters) and where: onelocation(2 to 200 characters: a city, neighbourhood, address or postal code), orlatitudeandlongitude, or both; optionally a radius (more than 0 and at most 200 km) and open places only. It returns up tomax_resultsplaces:name,url,address,phone,latitude,longitude,distance_km,rating(fair,good,greatorexcellent),price_level(1 to 4),opening_hours(per weekday,opensandclosesasHH:MM),timezoneandopen_now; any of them can be null.parallel_decisions(state, questions): a JSON object of shared context, and 1 tomax_questionsquestions, each with aname(letters, digits,_or-, at most 64), atypeandinstructions:noul(Parallel's name for a yes/no question: is it true? a probability from 0 to 1;criteriaoptional,{"true": ..., "false": ...}),choice(criteria: 2 to 20 named options) orscore(criteria: 2 to 10 levels, lowest first). It returnsanswersby name (noul;choicewith each option's probability;scorewith its legend and probabilities; orrefusalwhen Parallel gave no answer) and up to 10citations(urlandtitle). Achoiceorscoreanswer can carryconfidence, Parallel's own confidence from 0 to 1, which is not the probability of the chosen option.
For image and place search, mode trades cost for quality: fast (the default, $0.001 a call, about 1 second) or advanced ($0.005 a call, a few seconds, better results for images, more complete results for places).
Nothing else from Parallel's reply reaches the model or you (no ids, usage, warnings or Parallel error messages), and each result is at most 16 KB. The gateway asks for excerpts only, never a page's full content. A parallel:search call reads Parallel's index: the gateway never asks it to fetch pages live, Parallel documents that search does not fetch unless asked, and in our probes (2026-11-06) no search result held a fresh page's per-run marker, in fast, basic or advanced mode, even when the query was a fresh URL. That shows no live-fetched content came back in the results, not that Parallel made no request to the page. Image search, place search and decisions were not probed for live fetching, and Parallel does not document whether they fetch. An extract can make Parallel fetch the page from its website at call time: that is Parallel's default for extract, and no setting turns it off. That site then sees a request from Parallel (never from you or from us) for the full URL the model gave, query string included. The gateway itself never opens a URL from a result: not a page, not an image, not a place's website. If your app shows an image, your user's browser loads it from that third-party site, and the image may be unsuitable or under someone else's licence.
Correction, 2026-11-06: until then this page said the gateway never caused a live fetch. That was wrong for parallel:extract, as described above.
Web results are text from the open web: excerpts, image titles, place names and addresses, and citation titles. Any of them can try to give the model instructions. The limits narrow this, but they cannot remove it.
Read the answer
On /v1/chat/completions the answer is an ordinary chat.completion; usage.server_tool_use has a count of billed calls per tool on the request (parallel_search_requests, parallel_extract_requests, parallel_image_search_requests, parallel_place_search_requests, parallel_decisions_requests), and x-tm-server-tools says the same (parallel_search=1, parallel_extract=1). On /v1/messages each call is a server_tool_use block and a <function>_tool_result block before the answer (parallel_search_tool_result, parallel_image_search_tool_result, and so on); on /v1/responses it is a <function>_call item (parallel_search_call, parallel_place_search_call, and so on). usage.cost is the model's turns plus every call, in USD.
Parameters
| Tool | Field | Values | Default |
|---|---|---|---|
parallel:search | max_uses | 1 to 10 | 5 |
parallel:search | mode | "turbo", "fast", "basic" or "advanced" | "fast" |
parallel:search | max_results | 1 to 10 | 5 |
parallel:extract | max_uses | 1 to 10 | 3 |
parallel:extract | max_urls | 1 to 5 | 3 |
parallel:image_search | max_uses | 1 to 10 | 3 |
parallel:image_search | mode | "fast" or "advanced" | "fast" |
parallel:image_search | max_results | 1 to 20 | 10 |
parallel:place_search | max_uses | 1 to 10 | 3 |
parallel:place_search | mode | "fast" or "advanced" | "fast" |
parallel:place_search | max_results | 1 to 20 | 10 |
parallel:decisions | max_uses | 1 to 10 | 3 |
parallel:decisions | max_questions | 1 to 20 | 10 |
A gateway that does not serve the search modes "basic" and "advanced" answers them with a 400 that says to use "turbo" or "fast". Any other field (full_content, fetch_policy, source_policy, session_id, client_model, location, a mode for decisions), a value out of range, a second entry of the same tool, or a function of your own named like one of the tools (parallel_search, parallel_place_search, and so on) is a 400 invalid_request naming the field.
Cost
- Search: $1 per 1,000 searches ($0.001 a search), Parallel's list price in
turboandfastmode with up to 10 results; $5 per 1,000 searches ($0.005 a search) inbasicandadvancedmode. - Extract: $1 per 1,000 URLs ($0.001 a URL), for each URL Parallel read. A URL it could not read is not billed: in our probes Parallel counted only the URLs that returned a result.
- Image search and place search: $1 per 1,000 calls ($0.001 a call) in
fastmode and $5 per 1,000 calls ($0.005 a call) inadvancedmode, up to 20 results either way. - Decisions: $1 per 1,000 calls ($0.001 a call), for any number of questions up to
max_questions. A call Parallel answers is billed even when every answer is a refusal. - A call that fails is not billed. The model's turns are billed as ordinary chat requests.
- A tool may be free for a while: Tools then shows its list price struck through with "Free",
/api/tools.jsonsays"free": true, and its calls are not charged (server_tool_fee_usd0; with a balance of $0 a call is refused). The prices above are the list prices. See Pricing.
Each call is its own attempt in GET /v1/usage & /v1/generation: provider parallel, model the tool (parallel:search, parallel:image_search, and so on). See Pricing & billing.
Limits
- At most
max_usescalls of each tool per request. A call over it gives the model{"error":"parallel_search limit for this request reached; continue without it"}(or the tool's own name), is not sent, and is not billed. Once every server tool on the request is at its limit, the next turns offer only your own tools. - At most 60 Parallel calls a minute per organization, every Parallel tool together; a call over the rate is not sent or billed, and the model is told.
- 15 seconds per search, 30 seconds per extract, 15 seconds per image search, 20 seconds per place search, 15 seconds per decisions call. The whole request has 150 seconds when streamed and 110 seconds when not: send
"stream": truefor long research. - A call Parallel refuses or times out on gives the model
{"error":"parallel_search failed"}(orparallel_extract,parallel_image_search, and so on), is not billed, and the model goes on. - A place search or decisions call the model wrote wrongly (no location, a duplicate question name) is not sent or billed: the model gets an error that says what to fix.
Troubleshooting
- 400
server_tool_unsupported, "not enabled on this gateway": the gateway you called does not serve the tool the message names, so nothing was searched or billed. Ask support to turn it on, or remove it from thex-tm-toolsheader (ortools) to send the request without it. - 503, "turned on but not configured": the tool is turned on for the gateway you called, but our Parallel key is not in place yet. Ask support; retrying will not help until the key is configured.
- 400 that names
parallel:searchwhile Tako works: the gateway you called servestako:searchbut not the Parallel tools. Drop theparallel:*values from the header (or the entries fromtools) to send the request with Tako alone, or ask support. - 400 "needs an organization key": use an organization key, not a static one.
- 400 naming
x-tm-tools: the header holds something other than the six values above. - 400 naming
parallel:image_search,parallel:place_searchorparallel:decisionswhileparallel:searchworks: the gateway you called does not serve that tool; drop it from the header ortools, or ask support. "basic" is not supported; use "turbo" or "fast": the gateway you called does not serve thebasicandadvancedsearch modes. Use"turbo"or"fast", or ask support.- A place search error, "give a location (or latitude and longitude)": a place search needs one place to search in. Put what in
queryand where inlocation(one place, not a list). - A decisions error: each question needs a unique name of letters, digits,
_or-; achoiceneeds 2 to 20 options and ascore2 to 10 levels; instructions and criteria together at most 4,000 characters, and the state at most 8,000 characters as JSON. - 429
insufficient_quota: your credit or a spend cap does not cover the next call.
Data
The queries, objectives and URLs the model writes are sent to Parallel, a third party in the United States, with our key; never your messages as such, your key or your organization. So are a place search's query and location (a place name, an address or coordinates can say where someone is) and a decisions call's state and questions, which the model can fill with anything from your conversation. Place results carry businesses' public addresses and phone numbers; image results are links to third-party images, which the gateway never opens. Under Parallel's standard terms it may use inputs and outputs, not linked to any individual, to improve its models; zero data retention is an Enterprise plan. Until our account terms with Parallel are settled, assume it does. See Data policy.
Where next
Markdown source for agents: /docs/parallel-search.md · index at /llms.txt