Skip to main content
Tako Search is a built-in tool on the Vercel AI Gateway. Add one option to a generateText call and any model on the gateway can search Tako’s curated knowledge graph and the live web, then answer with sourced figures and an embeddable chart. Vercel runs the search and bills for it, so you need no Tako account and no Tako key. This page covers authenticating, reading the cards a search returns, and the two behaviors that most often make a working integration look broken.
Which Vercel integration do you want? This page covers the AI Gateway’s built-in tool: search only, no Tako account, Vercel bills you. If you want answer and contents as well, and you’re happy to hold a Tako API key and let us bill you, use @takoviz/ai-sdk instead. You use both through the Vercel AI SDK, and both expose a function called takoSearch, but their options aren’t interchangeable.

Install

The gateway tool ships in the AI SDK itself. You don’t install a Tako package.

Authenticate

Create a key in the Vercel dashboard under AI Gateway → API Keys:
On Vercel deployments, use the automatically available VERCEL_OIDC_TOKEN instead and set nothing.
Without a payment card on file, every request returns 403 customer_verification_required. Add one in the Vercel dashboard. The free credits it unlocks are rate-limited, so top up with paid credits before you build against it.

Quick start

Pass gateway.tools.takoSearch() in tools. The gateway executes the search, feeds the results back to the model, and returns one finished answer:
Drop the tools option and the same model answers “$130.5 billion for fiscal year 2025” — a real figure, one year stale, presented with no indication that a newer one exists.

Parameters

Options you set here are developer defaults — the gateway applies them over anything the model generates. For the complete wire schema see Vercel’s Web Search reference; for retrieval behavior see the Tako Search guide.
sources.data.includeContents is the parameter that adds row charges, and models set it on their own if you don’t pin it. Search first, read each card’s content.export_pricing, then export.

Read the cards

This is what makes Tako different from the gateway’s other search tools: alongside web results, a Tako search returns knowledge cards — structured series with their sources, and a rendered chart you can embed. Web results arrive alongside the cards in web_results, each carrying title, url, snippet, source_name, content, and publish_date where the source reports one. Each card carries these fields, among others — the full card schema covers the rest: Collect them across steps, and dedupe. The gateway runs the tool loop, so one prompt can produce several searches, and overlapping searches return the same series more than once. Keep the freshest copy of each:
Output — three cards in, two out:
Cards are windowed to the time range a query implies, so the same metric returns at different vintages depending on how the model phrased each search. Three things that recipe gets right:
  • steps, not toolResults — on a multi-step call the top-level toolResults holds the last step only.
  • title, not card_id — every request mints a fresh id, so an id-based dedupe removes nothing.
  • Pad before comparingcoverage_end is ISO 8601 reduced precision, so a raw string compare puts 2026 below 2026-06.
A card that carries projections reports a coverage_end in the future, and nothing in the response marks it as a projection, so it wins this comparison. If that matters to you, drop cards whose period ends after today — but note that also drops the current month and the current year, whose periods haven’t closed either. An embed posts a tako::resize message carrying its rendered height. Handle it and set that iframe’s height, or the chart clips. See Embedding Knowledge Cards for the handler and dark-mode options.

Inline the underlying rows

A search returns each card’s headline figure and chart. To give an agent the series itself — to filter it, join it, or compute on it — set sources.data.includeContents:
Output
Columns are typed and unit-labeled, and ref links back to the card the rows came from. Read the field that matches your contentFormat. Each format returns a different type, so each lands in its own field. One is populated when rows are delivered — but a response shares a row budget across cards, so a later card can come back with no rows at all. Test content.content_format for null to tell a quote from a delivery, and fetch that card’s rows from /api/v1/contents using its export_pricing quote: card_json is the one to guard. Card types that have no card_json shape fall back to json_compact on search rather than erroring, so a request that asked for card_json can return its rows in content.dataset. Branch on the content.content_format the response reports, not on the format you asked for. content.cost is what this response billed for the rows it inlined; on a card with no inlined rows it’s a quote and Vercel billed nothing. Price a later export from content.export_pricing alone — the two cover different row counts. Omit maxRows and each card returns 20 rows, with truncated: true when more remain. Vercel bills every inlined row.
A model can attribute a figure to these rows that isn’t in them. Check any figure it cites against the rows themselves. Asked to compute a growth rate from a payload like this one, a model reported “from the returned rows” and used a figure that appears nowhere in them — it had read the card’s description instead. The arithmetic was right; the provenance claim was not.

Examples

Compare two companies over time

The interesting questions need more than one lookup. Ask when one company passed another and the model searches both, reads the rows, and reconciles the dates — no orchestration on your side:
Output — after four searches:
Note the last line: the model caught the fiscal-calendar mismatch on its own, because each card carries its own period boundaries.

Screen the market

Ranking cards are same-day. This one is a leaderboard of 30 trading items refreshed during the session:
Output

Test a hypothesis

Some questions have a defensible answer rather than a lookup. This one needs three separate series and one piece of domain knowledge — that “core” is defined as excluding energy, which is what makes the gap between headline and core diagnostic:
Output — after eight searches:
Without a date, “latest” resolves to the model’s training cutoff, not today. Say when “now” is. A model’s clock stops at that cutoff, and nothing in the gateway tells it otherwise, so “latest” resolves to whenever it believes the present to be. Asked this same question with no date, it answered “No — not primarily” from February 2026 figures while July 2026 cards sat unread in the same result set. The date changed the conclusion, not only the numbers.

Chat Completions on the gateway

The same tool works over the OpenAI-compatible endpoint. Use snake case for config keys:
Output
config keys are snake case here, not the camel case the AI SDK takes. query is required on this path and fixes the search for every request — edit messages alone and you still search Nvidia annual revenue. This path returns the finished answer only — no raw cards, so no embed_url. Read choices[0].message.provider_metadata.gateway.gatewayToolCalls for the search count. Use the AI SDK when you want the cards.
Keep max_tokens generous. Reasoning models spend the budget before writing prose — at 300 this request returns finish_reason: "length" and empty content.

Pricing

Vercel bills gateway searches on top of model tokens, so Vercel’s AI Gateway rates are what you pay. sources.data.includeContents adds a row surcharge derived from Tako’s Contents pricing.

Resources