> ## Content Index
> Fetch the complete content index at: https://serpapi.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Bing Search API Replacement: Web Search
- URL: https://serpapi.com/blog/bing-search-api-replacement-web-search/
- Published: 2025-06-06T13:10:03.000Z
- Updated: 2025-12-02T04:47:33.000Z
- Description: The official Bing Search API is soon to be retired. Learn how to transition to SerpApi's Bing Search API to reduce disruption to your service.
- Author: David Sojevic
- Tags: Bing, organic results, organic search

## Introduction

The official Bing Search API is [soon to be retired](https://azure.microsoft.com/en-us/updates?id=492574) on 11th August 2025 *(or has already been retired depending on when you're reading this)* and you may be searching for a suitable replacement.

Here at SerpApi, we provide our own [Bing Search API](https://serpapi.com/bing-search-api) that can be easily integrated to minimize disruption to your service once the official APIs have been retired.

In this blog post, I'm going to describe the basic changes you will need to make to make the move to SerpApi's Bing Search API.

![](https://storage.ghost.io/c/a5/00/a5004977-0dd2-4bcd-9292-dd0e05d4c59e/content/images/2025/06/cats-moving-boxes-1.jpg)

## Step 1: SerpApi Account

If you don't already have an account with us, your first step is going to be [signing up for an account](https://serpapi.com/pricing) *(we offer a free account with 100 free searches per month)*.

Once you have signed up and verified your account, you will need to take note of your SerpApi API key found on [your dashboard](https://serpapi.com/dashboard) so that you can use it in the following steps.

![](https://storage.ghost.io/c/a5/00/a5004977-0dd2-4bcd-9292-dd0e05d4c59e/content/images/2025/06/CleanShot-2025-06-06-at-22.43.45.png)

## Step 2: Endpoint and Authentication

First we're going to start off by changing the endpoint and the authentication to move from using the official Bing endpoint and Azure subscription key and over to using the SerpApi endpoint and a SerpApi API key.

An overly simplified version of your current setup may look something like so:

```python
# environment
subscription_key = 'AZURE-SUBSCRIPTION-KEY'
endpoint = 'https://api.bing.microsoft.com/v7.0/search'

# search params
query = 'Bing Search API'
mkt = 'en-US'
headers = { 'Ocp-Apim-Subscription-Key': subscription_key }
params = { 'q': query, 'mkt': mkt }

# request
response = requests.get(endpoint, headers=headers, params=params)
response.raise_for_status()

print("\nJSON Response:\n")
pprint(response.json())

```

First you'll need to change the environment variables we have to use your SerpApi API key and our endpoint:

```diff
  # environment
- subscription_key = 'AZURE-SUBSCRIPTION-KEY'
+ subscription_key = 'SERPAPI-API-KEY'
- endpoint = 'https://api.bing.microsoft.com/v7.0/search'
+ endpoint = 'https://serpapi.com/search.json'

```

Next we're going to authenticate via the `api_key` query parameter and remove the headers entirely as they're not necessary for any calls to our endpoint.

We're also going to add `'engine': 'bing'` as a parameter so that we're still using Bing for search results.

```diff
  # search params
  query = 'Bing Search API'
  mkt = 'en-US'
- headers = { 'Ocp-Apim-Subscription-Key': subscription_key }
- params = { 'q': query, 'mkt': mkt }
+ params = { 'engine': 'bing', 'q': query, 'mkt': mkt, 'api_key': subscription_key }

  # request
- response = requests.get(endpoint, headers=headers, params=params)
+ response = requests.get(endpoint, params=params)
  response.raise_for_status()

```

If your implementation is relatively simple and only uses the `q` and `mkt` parameters, then when you make these changes, you should see a full response come back from our endpoint at this stage. The official API's response format differs from our own so there are still changes to make, but we're part way there.

## Step 3: Header Functionality

SerpApi does not utilize headers for searches, but the functionality provided by the following official API request headers may be largely reproduced by other means:

- `Accept-Language` \- Language to use for the interface returned. You can not directly set this in our API, instead we infer it from the `mkt` code provided
- `Ocp-Apim-Subscription-Key` \- API key authentication. As described earlier, we use query parameter `api_key` for authentication
- `Pragma` \- Toggles cache state, e.g. `no-cache`. We use query parameter `no_cache=true` to disable caching, otherwise searches are cached by default
- `User-Agent` \- User agent to use for the search, can be used to get results on a per device basis. We use query parameter `device` with options `desktop`, `tablet`, and `mobile` to achieve this
- `X-Search-Location` \- Location to use for the search, e.g. (`lat:55;long:-111;re:22` or `disp:Seattle, Washington`)  
  - For `lat` and `long` we use the query parameters `lat` and `lon`
  - For `disp` we use the query parameter `location`
  - All other value types such as radius or timestamp are not supported by our API

The official API supports a number of headers, the following are entirely unsupported by our API:

- `Accept` \- Used to specify either `application/json` or `application/ld+json`. Using the query parameter `output`, our API can only be toggled between `json` or `html`
- `X-MSEdge-ClientID` \- Used by Bing to assign traffic on a consistent route
- `X-MSEdge-ClientIP` \- Used by Bing to infer the user's location

We do not utilize any response headers to convey information about a search result, so the following official API response headers will not be seen when using our API:

- `BingAPIs-Market` \- Market used by the request
- `BingAPIs-TraceId` \- ID used by Bing to correlate to their logs
- `Retry-After` \- Rate limiting information
- `X-MSEdge-ClientID` \- Assigned/used client ID

### Example Header Changes

To illustrate with an example, if you used headers in your script and they looked like this:

```python
headers = {
  'Ocp-Apim-Subscription-Key': 'AZURE-SUBSCRIPTION-KEY',
  'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML; like Gecko) Mobile/10B142 iPhone4;1 BingWeb/3.03.1428.20120423',
  'X-Search-Location': 'lat:55;long:-111;re:22',
  'X-MSEdge-ClientIP': '202.89.233.101',
  'Pragma': 'no-cache',
}
params = {
  'q': 'Bing Search API',
  'mkt': 'en-US',
}

```

Then you would be able to retain most of that functionality other than the IP address assignment with the following changes:

```diff
  headers = {
-   'Ocp-Apim-Subscription-Key': 'AZURE-SUBSCRIPTION-KEY',
-   'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML; like Gecko) Mobile/10B142 iPhone4;1 BingWeb/3.03.1428.20120423',
-   'X-Search-Location': 'lat:55;long:-111;re:22',
-   'X-MSEdge-ClientIP': '202.89.233.101',
-   'Pragma': 'no-cache',
  }
  params = {
+   'engine': 'bing',
    'q': 'Bing Search API',
    'mkt': 'en-US',
+   'lat': '55',
+   'lon': '-111',
+   'device': 'mobile',
+   'no_cache': 'true',
+   'api_key': 'SERPAPI-API-KEY',
  }

```

## Step 4: Query Parameters

The following query parameters behave the same in both the official API and our API, so you don't need to adjust these:

- `q` \- The search query term
- `mkt` \- The market for the search results
- `cc` \- The country for the search results
- `safeSearch` \- The mode to use for safe search

The following query parameter behaves the same, but has a different name in our API:

- `offset` \- The number of results to skip before returning search results. This is called `first` in our API

The following query parameters can be supported through alternate means in our API:

- `freshness` \- Controls the age or date-range of search results. These can be achieved using the `filter` parameter in our API with the following values:  
  - Value `Day` becomes `ex1:"ez1"` *(past 24 hours)*
  - Value `Week` becomes `ex1:"ez2"` *(past 7 days)*
  - Value `Month` becomes `ex1:"ez3"` *(past month)*
  - Year (unsupported by official API) becomes `ex1:"ez4"` *(past year)*
  - Single date (e.g. `2019-02-04`) becomes `ex1:"ez5_17931_17931"` *(number of days since 1970-01-01)*
  - Date range (e.g. `2019-02-04..2019-02-06`) becomes similar to `ex1:"ez5_17931_17933"` *(number of days since 1970-01-01)*

![](https://storage.ghost.io/c/a5/00/a5004977-0dd2-4bcd-9292-dd0e05d4c59e/content/images/2025/06/CleanShot-2025-06-06-at-22.59.12.png)

The remaining query parameters are unsupported in our API but you can achieve a similar result programmatically:

- `answerCount` \- Number of answer types to include in the search results. You will need to selectively ignore/include result types after receiving a response to achieve this
- `promote` \- Answer types to promote in the search results. You will need to selectively promote or demote result types after receiving a response to achieve this
- `responseFilter` \- Answer types to receive to be returned or excluded in the search results. You will need to selectively include/reject result types after receiving a response to achieve this
- `setLang` \- Language to use for the interface returned. You can not directly set this in our API, instead we infer it from the `mkt` code provided
- `textDecorations` \- Whether or not snippets should contain highlighting decorations. Our API will always provide a plain text `snippet` attribute and a secondary `snippet_highlighted_words` array attribute where able
- `textFormat` \- Format of the text decorations (raw or HTML). You will need to manually build the desired format using `snippet` and the `snippet_highlighted_words` array if present

### Example Query Parameter Changes

Here is an example to help illustrate where a variety of query parameters have been used with the official API:

```python
params = {
  'q': 'Bing Search API',
  'mkt': 'en-US',
  'offset': 10,
  'freshness': '2019-02-04',
  'textDecorations': 'false',
  'textFormat': 'raw',
}

```

All of the above query parameters, with the exception of `textDecorations` and `textFormat` can be used as-is or ported to use with our API.

Here are the changes that would need to be made to the example to achieve this:

```diff
  params = {
+   'engine': 'bing',
    'q': 'Bing Search API',
    'mkt': 'en-US',
-   'offset': 10,
+   'first': 10,
-   'freshness': '2019-02-04',
+   'filters': 'ex1:"ez5_17931_17931"',
-   'textDecorations': 'false',
-   'textFormat': 'raw',
  }

```

## Step 5: Response Format

While the previous steps have all been quite straightforward, the changes to the response format handling will likely be the most involved for you depending on how much of the data you have been using.

Due to the sheer number of different possible response objects available, I'm only going to cover a few of them directly in this blog post.

### Web Pages

Returned in the `webPages.value` key (an array of results) in the official API, our API returns the equivalent in the top level `organic_results` key (an array of results).

![](https://storage.ghost.io/c/a5/00/a5004977-0dd2-4bcd-9292-dd0e05d4c59e/content/images/2025/06/CleanShot-2025-06-06-at-22.49.50.png)

The Bing search URL that would be found under `webPages.webSearchUrl` in the official API can be found under `search_metadata.bing_url` in our API.

When available, the estimated number of results that was previously found under `webPages.totalEstimatedMatches` will be available under `search_information.total_results` in our API.

#### Web Page Result Mapping

The following attributes on the web page result objects can be mapped and used without change:

- `name` \- Name of the web page. Becomes `title` on our API
- `url` \- URL of the web page. Becomes `link` on our API
- `displayUrl` \- Displayed URL of the web page. Becomes `displayed_link` on our API
- `snippet` \- Snippet describing the web page. No change to name.  
  - In order to retain highlighting functionality, you must also utilize the `snippet_highlighted_words` array (when available) from our API to highlight this in your application

The `dateLastCrawled` and `datePublished` attributes are not available and have no equivalent, however, the `datePublishedDisplayText` has a similar property in our result named `date`.

The `date` attribute in our API will return the date displayed in the result, though it can be in the form of a formatted date (e.g. `Oct 29, 2020`) or a relative date (e.g. `3 days ago`).

The `deepLinks` attribute in the official API can be somewhat mapped by reading the `sitelinks.inline` and `sitelinks.expanded` attributes which each contain objects with at least the attributes `title`, `link`, and `tracking_link` in them.

Significantly more is available on these organic results when using our API, so don't forget to check out the [Bing Organic Results API documentation](https://serpapi.com/bing-organic-results) page.

### Related Searches

Returned in the `relatedSearches.value` key (array of related searches) in the official API, our API returns the equivalent in the top level `related_searches` key (array of related searches).

#### Related Search Result Mapping

The following attributes on the related search result objects can be mapped and used without change:

- `displayText` \- Display text of the related search. Becomes `query` on our API, always unformatted
- `text` \- Unformatted text of the related search. Becomes `query` on our API
- `webSearchUrl` \- URL for the Bing search. Becomes `link` on our API

### Images

Returned in the `images.value` key (array of images) in the official API, our API returns the equivalent in the `inline_images.items` key (array of images).

![](https://storage.ghost.io/c/a5/00/a5004977-0dd2-4bcd-9292-dd0e05d4c59e/content/images/2025/06/CleanShot-2025-06-06-at-22.57.37.png)

The Bing search URL found at `images.webSearchUrl` in the official API can be found at `inline_images.see_more_link` in ours.

The `images.readLink` attribute in the official API which provides the URL for the equivalent API image search can be found at `inline_images.serpapi_link` in our API.

The `isFamilyFriendly` attribute in the official API has no equivalent in our API.

#### Image Result Mapping

The following attributes on the image result objects can be mapped and used without change:

- `name` \- Name of the image result. Becomes `title` on our API
- `thumbnailUrl` \- URL to the image thumbnail. Becomes `thumbnail` on our API
- `webSearchUrl` \- URL to view the image in Bing search. Becomes `link` on our API
- `hostPageUrl` \- URL the image is found on. Becomes `source.link` on our API

## What's Next

If you were able to make the move using everything we've covered in this blog post, great work, there's nothing left for you to do!

Otherwise if you were utilizing much more of the official Bing Search API than we were able to cover here, then you're going to want to take a look over our [Bing Search API](https://serpapi.com/bing-search-api) documentation and everything we provide to fill the rest of the gaps.

It's also worth taking a look at our [Bing Playground](https://serpapi.com/playground?engine=bing) and performing a few searches to see it all in action.

That's all for now, I hope this was helpful to get you started on your transition to our Bing Search API!