Bing Search API alternatives after the August 2025 retirement
Microsoft retired the Bing Search APIs on August 11, 2025. Existing instances were decommissioned, and there is no sign-up path. Microsoft’s recommended successor, Grounding with Bing Search, is a tool for Azure AI agents, not a search results API: it does not hand you the result list. If your product needs ranked web results as JSON, you have to move to a different provider, and in most cases to a different index.
What Microsoft announced
The lifecycle notice (checked 2026-09-17) states:
- Bing Search APIs retired on August 11, 2025.
- Existing instances were decommissioned completely; the product is no longer available for use or new customer sign-up.
- Customers are encouraged to migrate to Grounding with Bing Search as part of Azure AI Agents, which lets agents incorporate real-time public web data when generating responses with an LLM.
The Bing Web Search v7 reference is still readable in Microsoft’s archive (query parameters, response objects), marked as retired. The mapping tables below use it.
Is Grounding with Bing Search a replacement?
Only if your use of Bing was to give an LLM fresh web context. Microsoft’s how-to page (checked 2026-09-17) describes it this way:
- The agent decides whether to call the tool; Bing searches public web data and returns chunks to the model, which generates the response.
- Developers and end users do not have access to the raw content returned by the tool. You get the model’s response, with citations to the websites used and a link to the Bing query.
- Those references must be retained and displayed in the exact form Microsoft provides, per its use and display requirements.
- Only paid and pay-as-you-go Azure subscriptions are eligible; sponsored and free-credit subscriptions are not.
- Search queries sent to the tool leave the Azure compliance boundary.
- Optional parameters include
count(default 5, maximum 50),freshness,marketandset_lang.
The same page notes that classic agents are deprecated and will retire on March 31, 2027, and recommends starting with the new Web Search tool in the agents API.
Microsoft’s grounding pricing page (checked 2026-09-17) lists $14 per 1,000 transactions for Grounding with Bing Search and for Grounding with Bing Custom Search, each with limits of 150 transactions per second and 1 million transactions per day. Transactions are counted as tool calls per run, and one run can call the tool more than once.
If your code consumed webPages.value[], stored rankings, rendered your own result list or computed anything from positions, grounding does not give you that data.
The options
| Need | Option | What you get |
|---|---|---|
| LLM answers with web citations inside Azure | Grounding with Bing Search | A model response with citations; no raw results |
| A web results list from an independent index | Brave Search API | Brave’s own index and ranking |
| The Google results page as JSON | A Google SERP API | Google’s organic results and SERP modules |
| What Microsoft’s assistant answers | Copilot monitoring | The Copilot response, via this API’s Copilot endpoint |
Brave Search API
Brave’s API page (checked 2026-09-17) lists $5 per 1,000 requests, $5 in free credits every month, and a capacity of 50 queries per second. It states that the API is its own independent index of the web with its own ranking models, not a repackaging of Google or Bing results. If you want a general web index and do not care whose ranking it is, this is the closest in spirit to the old Bing API.
Google SERP APIs
A SERP API returns the Google results page. Prices from each vendor’s own page, checked 2026-09-17:
| Provider | Published price | Source |
|---|---|---|
| SerpApi | Free: 250 searches/month; Starter $25/month for 1,000; Developer $75/month for 5,000; Production $150/month for 15,000 | serpapi.com/pricing |
| DataForSEO (Google Organic) | Standard queue $0.6 per 1K SERPs; Priority $1.2 per 1K; Live $2 per 1K | dataforseo.com pricing |
| Serper | 2,500 free queries, no credit card (paid packs not verified) | serper.dev |
| This API | 500 free credits per month, no card; Google Search task 3 credits, synchronous call 5 | /pricing, /docs/credits |
See best SERP APIs, cheapest SERP API and search APIs for AI agents for deeper comparisons.
The index changes
This API returns Google results, not Bing results. Moving from Bing to any Google SERP API changes:
- Rankings. Different index, different ranking. Historic Bing positions are not comparable with new Google positions; start a new baseline.
- Coverage. Google shows modules Bing’s API did not return in the same form (People Also Ask, AI Overviews, local packs), and Bing’s API returned answers Google’s page does not expose as data (computation, time zone, translations).
- Market handling. Bing used one
mktcode; Google separates result geography (gl) from interface language (hl).
If downstream users see numbers, tell them the source changed on a specific date.
Request migration map
This API’s Google Search endpoint (POST /v1/monitor/google) accepts two shapes. The standard shape takes query plus country (or gl), with optional hl, location or uule, device and pages (1 to 10). The URL shape takes url, a Google web search URL, and applies only q, gl, hl, uule, num, start, tbs and safe; url cannot be combined with query, location, uule or pages.
| Bing Web Search v7 | This API | Notes |
|---|---|---|
q |
query |
Bing advanced operators do not all exist on Google; site:, quotes and - do (see Google search operators) |
mkt (en-US) |
country: "US" + hl: "en" |
Split language and country |
cc |
country or gl |
Must be listed by GET /v1/countries?model=google |
setLang |
hl |
Google codes such as en, de, pt-BR |
count (default 10, max 50) |
pages |
pages = ceil(count / 10); Bing’s max of 50 is 5 pages |
offset |
start in url |
Google’s start=10 is the second page |
freshness=Day/Week/Month |
tbs=qdr:d / qdr:w / qdr:m in url |
tbs values are not documented by Google |
freshness=YYYY-MM-DD..YYYY-MM-DD |
after: and before: operators in query |
Google documents both operators |
safeSearch=Strict / Off |
safe=active / safe=off in url |
Bing’s default Moderate has no direct equivalent |
responseFilter |
read only the arrays you need | Every module Google shows is returned |
answerCount, promote |
none | |
textDecorations, textFormat |
none | Text fields are plain text |
X-Search-Location header |
location or uule |
location uses Google canonical names such as "New York,New York,United States" |
The tbs values and the zero-based start are taken from Bright Data’s Google URL parameter reference (dated February 26, 2026); Google does not document them. The before:/after: operators are on Google’s Refine Google searches help page. Full details are in Google search parameters.
Response migration map
Bing (SearchResponse) |
This API (result) |
Notes |
|---|---|---|
webPages.value[].name |
organicResults[].title |
|
webPages.value[].url |
organicResults[].link |
Redirected links also carry redirectLink |
webPages.value[].displayUrl |
organicResults[].displayedLink |
|
webPages.value[].snippet |
organicResults[].snippet |
|
webPages.value[].datePublished |
organicResults[].date |
Here a display string such as “2 days ago”, not ISO |
webPages.value[].deepLinks[] |
organicResults[].sitelinks.inline[] |
title, link |
| array index | organicResults[].position, page |
Explicit fields |
relatedSearches.value[].text |
relatedSearches[].query |
|
entities |
knowledgeGraph |
Different structure |
places |
localResults[] |
title, rating, address, phone, hours |
news |
POST /v1/monitor/google/news |
Separate endpoint |
images, videos, computation, timeZone, translations, spellSuggestions |
none | |
| (none) | peopleAlsoAsk[], ads[], aioverview |
New data |
Code
Python
Using requests:
import math
import os
from urllib.parse import urlencode
import requests
API = "https://api.answerline.dev"
HEADERS = {"Authorization": f"Bearer {os.environ['ANSWERLINE_API_KEY']}"}
FRESHNESS = {"day": "qdr:d", "week": "qdr:w", "month": "qdr:m"}
SAFE = {"strict": "active", "off": "off"}
def to_request(bing: dict) -> dict:
"""Translate Bing Web Search v7 query parameters into a Google Search request body."""
lang, _, country = bing.get("mkt", "en-US").partition("-")
country = bing.get("cc", country or "US").upper()
hl = bing.get("setLang", lang)
count, offset = int(bing.get("count", 10)), int(bing.get("offset", 0))
tbs = FRESHNESS.get(bing.get("freshness", "").lower())
safe = SAFE.get(bing.get("safeSearch", "").lower())
if offset == 0 and not tbs and not safe:
return {"query": bing["q"], "country": country, "hl": hl, "pages": min(10, math.ceil(count / 10))}
params = {"q": bing["q"], "gl": country.lower(), "hl": hl, "num": count, "start": offset}
if tbs:
params["tbs"] = tbs
if safe:
params["safe"] = safe
return {"url": "https://www.google.com/search?" + urlencode(params)}
def search(bing: dict) -> dict:
"""Return a Bing-shaped subset so existing consumers keep working."""
r = requests.post(f"{API}/v1/monitor/google", json=to_request(bing), headers=HEADERS, timeout=360)
r.raise_for_status()
result = r.json()["result"]
return {
"webPages": {
"value": [
{"name": o["title"], "url": o["link"], "displayUrl": o.get("displayedLink"), "snippet": o.get("snippet")}
for o in result.get("organicResults", [])
]
},
"relatedSearches": {"value": [{"text": s["query"]} for s in result.get("relatedSearches", [])]},
}
print(search({"q": "project management software", "mkt": "en-GB", "count": 20}))
A Bing date range (freshness=2025-01-01..2025-03-31) is not handled above; append after:2025-01-01 before:2025-03-31 to q instead.
TypeScript
const API = "https://api.answerline.dev";
const FRESHNESS: Record<string, string> = { day: "qdr:d", week: "qdr:w", month: "qdr:m" };
const SAFE: Record<string, string> = { strict: "active", off: "off" };
type BingParams = {
q: string; mkt?: string; cc?: string; setLang?: string;
count?: number; offset?: number; freshness?: string; safeSearch?: string;
};
function toRequest(bing: BingParams): Record<string, unknown> {
const [lang, marketCountry] = (bing.mkt ?? "en-US").split("-");
const country = (bing.cc ?? marketCountry ?? "US").toUpperCase();
const hl = bing.setLang ?? lang;
const count = bing.count ?? 10;
const offset = bing.offset ?? 0;
const tbs = FRESHNESS[(bing.freshness ?? "").toLowerCase()];
const safe = SAFE[(bing.safeSearch ?? "").toLowerCase()];
if (offset === 0 && !tbs && !safe) {
return { query: bing.q, country, hl, pages: Math.min(10, Math.ceil(count / 10)) };
}
const params = new URLSearchParams({ q: bing.q, gl: country.toLowerCase(), hl, num: String(count), start: String(offset) });
if (tbs) params.set("tbs", tbs);
if (safe) params.set("safe", safe);
return { url: `https://www.google.com/search?${params}` };
}
export async function search(bing: BingParams) {
const res = await fetch(`${API}/v1/monitor/google`, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.ANSWERLINE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify(toRequest(bing)),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { result } = await res.json();
return {
webPages: {
value: (result.organicResults ?? []).map((o: any) => ({
name: o.title, url: o.link, displayUrl: o.displayedLink, snippet: o.snippet,
})),
},
relatedSearches: { value: (result.relatedSearches ?? []).map((s: any) => ({ text: s.query })) },
};
}
Migration steps
- Classify each Bing call by purpose: LLM context, ranked results for display or analysis, or monitoring what users see.
- Pick the source per purpose. Grounding for agent answers in Azure, an independent index for generic web results, a Google SERP API for Google visibility.
- Translate requests with a function like
to_request, and log parameters you cannot map. - Adapt consumers through a thin response adapter first, then move them to the richer fields (
position,page,peopleAlsoAsk) when convenient. - Reset baselines. Mark the date the source changed in any ranking history.
- Move volume to async tasks. Async tasks cost 2 credits less than synchronous calls and accept batches of up to 500 with webhooks; see async tasks and rank tracking with batches.
- Handle validation errors. Sending
urlwithpages, orlocationwithuule, returns 400 with the offending field indetails[]; see API errors and retries.
Pitfalls
- Comparing Bing and Google positions as if they were one time series.
- Mapping
count=50to 50 results. Google returns pages of about ten; ask for 5 pages and count what arrives. - Assuming grounding returns results. Microsoft’s documentation says the raw content is not available to developers.
- Forgetting the language half of
mkt. Withouthl, the interface language follows the country, which may not match your old market. - Keeping Bing-only operators in stored queries; test each operator on Google before relying on it.
If you are also moving off Google’s Custom Search, see Google Custom Search JSON API alternatives; for the broader picture, is there an official Google Search API.
Request fields and response examples are on the Google Search engine page.
Questions
When did the Bing Search APIs retire?
Microsoft's lifecycle notice states that the Bing Search APIs retired on August 11, 2025, that existing instances were decommissioned completely, and that the product is no longer available for use or new sign-ups.
What does Microsoft recommend instead of the Bing Search APIs?
The retirement notice encourages customers to migrate to Grounding with Bing Search as part of Azure AI Agents. Microsoft's documentation says developers and end users do not get the raw content it returns; the model response includes citations that must be displayed as Microsoft requires.
How much does Grounding with Bing Search cost?
Microsoft's pricing page lists $14 per 1,000 transactions for both Grounding with Bing Search and Grounding with Bing Custom Search, with limits of 150 transactions per second and 1 million transactions per day (checked 2026-09-17).
Can a Google SERP API replace the Bing Web Search API?
It can replace the job of getting ranked web results as JSON, but not the data source: a Google SERP API returns Google's results, which rank differently from Bing's index. If you need Bing's results specifically, no API covered here returns them.
How do Bing's mkt, count and offset parameters map to this API?
Split mkt such as en-US into country US and hl en; convert count into pages of about ten results; and put offset into the start parameter of a Google search URL sent in the url field. setLang maps to hl.