Skip to content

Bing Search API replacement: fix calls to api.bing.microsoft.com

Microsoft shut down the Bing Search APIs on 11 August 2025, so requests to api.bing.microsoft.com/v7.0/search no longer work. ContextFetch serves a Bing v7-compatible web search route at https://api.contextfetch.dev/bing/v7.0/search: same query parameters, same Ocp-Apim-Subscription-Key header, same SearchResponse JSON with webPages.value. Change the URL and the key and your parsing code keeps working. It returns web results only, at $1 per 1,000 searches.

Verified PythonBing Web Search APILangChain/bing/v7.0/search

1. Why your Bing code stopped working

Microsoft retired the Bing Search APIs, including Bing Web Search v7 and Bing Custom Search, on 11 August 2025. Its lifecycle notice says existing instances were decommissioned completely and no new signups are accepted: Bing Search APIs retiring on August 11, 2025.

So any code that still sends requests to https://api.bing.microsoft.com/v7.0/search fails, whether it is a script built from Microsoft's Python quickstart, a LangChain tool, or a cron job nobody has touched in years. The fix does not need a new client library. Point the same request at a server that still speaks the v7 format.

2. Get a ContextFetch key

A single POST gives you a free key loaded with $2.50, which covers 2,500 web searches. No account form is involved, and each network can claim one free key. Put it in CONTEXTFETCH_API_KEY, which is where the program below looks for it.

To just poke at the route first, you can leave the key header off entirely: keyless calls are allowed 25 times per IP address per UTC day.

curl -X POST https://api.contextfetch.dev/v1/keys/free# {"apiKey": "cf_live_...", "balance_usd": 2.5}export CONTEXTFETCH_API_KEY="cf_live_..."

3. Change the endpoint and the key

In code based on Microsoft's quickstart, two values change: search_url and the key. The header name stays Ocp-Apim-Subscription-Key, so the requests.get call and every line that reads webPages.value stay as they are.

The route accepts q, count (up to 50), offset for paging, mkt such as en-US, and freshness as Day, Week, Month or a YYYY-MM-DD..YYYY-MM-DD range. Each page in webPages.value carries id, name, url, displayUrl, snippet, dateLastCrawled, language and isFamilyFriendly, and rankingResponse.mainline.items lists them in order, as Bing's did.

import osimport requests # before: retired on 11 August 2025# search_url = "https://api.bing.microsoft.com/v7.0/search"# subscription_key = os.environ["BING_SEARCH_V7_SUBSCRIPTION_KEY"] # aftersearch_url = "https://api.contextfetch.dev/bing/v7.0/search"subscription_key = os.environ["CONTEXTFETCH_API_KEY"] headers = {"Ocp-Apim-Subscription-Key": subscription_key}params = {"q": "python requests timeout", "textDecorations": True, "textFormat": "HTML"}response = requests.get(search_url, headers=headers, params=params)response.raise_for_status()search_results = response.json()

4. LangChain's BingSearchAPIWrapper

BingSearchAPIWrapper in langchain_community.utilities takes bing_subscription_key and bing_search_url (or the BING_SUBSCRIPTION_KEY and BING_SEARCH_URL environment variables). Its default URL is the retired Bing endpoint, so set bing_search_url to the ContextFetch route and pass your ContextFetch key. run() and results() then work unchanged; we checked both against langchain-community 0.4.2.

One caution: langchain-community's maintainers have announced that the package is being sunset, and importing it now prints a deprecation warning. The wrapper still installs and works, but for new code a plain requests call like the one above is the more durable choice.

import osfrom langchain_community.utilities import BingSearchAPIWrapper search = BingSearchAPIWrapper(    bing_subscription_key=os.environ["CONTEXTFETCH_API_KEY"],    bing_search_url="https://api.contextfetch.dev/bing/v7.0/search",    k=3,)print(search.results("python requests timeout", 3)) # or set BING_SEARCH_URL and BING_SUBSCRIPTION_KEY and call BingSearchAPIWrapper()

5. What is different from Bing

  • Only web results. There are no news, image, video, entity, autosuggest or spell check routes, and the response has no news, images or videos sections.
  • Snippets are plain text. textDecorations and textFormat=HTML are accepted and ignored, so there are no hit-highlight markers to strip.
  • dateLastCrawled is a date for the page, sometimes its publication date rather than a crawl time, so do not treat it as an exact crawl timestamp.
  • webPages.webSearchUrl links to the ContextFetch playground instead of bing.com.

6. Cost

A request with count of 25 or fewer is one search at $1 per 1,000, or $0.001 each. Asking for more raises the price by another $1 per 1,000 for each extra block of 25, so count=50 costs $0.002. Every billable response includes X-Cost-USD and X-Balance-USD headers, which makes the spend easy to log. See pricing for top-ups.

The complete code

Python, runnable as is with CONTEXTFETCH_API_KEY set. Install first: requests. We ran it against the live API; the output below is what it printed.

import os import requests # The only two lines that changed from Microsoft's quickstart:search_url = "https://api.contextfetch.dev/bing/v7.0/search"subscription_key = os.environ["CONTEXTFETCH_API_KEY"] headers = {"Ocp-Apim-Subscription-Key": subscription_key}params = {"q": "python requests timeout", "count": 3, "mkt": "en-US"} response = requests.get(search_url, headers=headers, params=params, timeout=30)response.raise_for_status()search_results = response.json() print(search_results["_type"], "for", repr(search_results["queryContext"]["originalQuery"]))for page in search_results["webPages"]["value"]:    print(f"- {page['name']}\n  {page['url']}\n  {page['snippet'][:160]}") 
OutputRecorded
SearchResponse for 'python requests timeout'
- Python Requests Timeout: A Complete Guide for Developers
  https://python-requests.org/python-requests-timeout/
  When working with APIs, web scraping, or any online data retrieval in Python, handling timeouts correctly is critical. Without proper timeout settings, your pro
- A Complete Guide to Timeouts in Python | Better Stack Community
  https://betterstack.com/community/guides/scaling-python/python-timeouts/
  Back to Scaling Python applications guides Python Stanley Ulili Updated on March 4, 2025 Why you need timeouts in Python HTTP request timeouts Database operatio
- Timeout for Python requests.get() entire response - Stack Overflow
  https://stackoverflow.com/questions/21965484/timeout-for-python-requests-get-entire-response
  timeout is not a time limit on the entire response download; rather, an exception is raised if the server has not issued a response for timeout ...

The same call with curl

The raw HTTP request, and the response it returned (long text fields and lists shortened).

curl -s "https://api.contextfetch.dev/bing/v7.0/search?q=python+requests+timeout&count=3&mkt=en-US" \  -H "Ocp-Apim-Subscription-Key: $CONTEXTFETCH_API_KEY"
ResponseRecorded
{
  "_type": "SearchResponse",
  "queryContext": {
    "originalQuery": "python requests timeout"
  },
  "webPages": {
    "webSearchUrl": "https://contextfetch.dev/playground?q=python+requests+timeout",
    "totalEstimatedMatches": 3,
    "value": [
      {
        "id": "https://api.contextfetch.dev/bing/v7.0/search#WebPages.0",
        "name": "Python Requests Timeout: A Complete Guide for Developers",
        "url": "https://python-requests.org/python-requests-timeout/",
        "displayUrl": "python-requests.org/python-requests-timeout/",
        "snippet": "When working with APIs, web scraping, or any online data retrieval in Python, handling timeouts correctly is critical. Without proper timeout settings, your program may hang indefinitely, consume system resources, or become unresponsive. In this comprehensive guide, we’ll explore…",
        "dateLastCrawled": "2025-11-13T00:00:00.0000000Z",
        "language": "en",
        "isFamilyFriendly": true
      },
      {
        "id": "https://api.contextfetch.dev/bing/v7.0/search#WebPages.1",
        "name": "A Complete Guide to Timeouts in Python | Better Stack Community",
        "url": "https://betterstack.com/community/guides/scaling-python/python-timeouts/",
        "displayUrl": "betterstack.com/community/guides/scaling-python/python-timeouts/",
        "snippet": "Back to Scaling Python applications guides Python Stanley Ulili Updated on March 4, 2025 Why you need timeouts in Python HTTP request timeouts Database operation timeouts Timeouts in asynchronous programming How to choose a timeout value Final thoughts Every Python application in…",
        "dateLastCrawled": "2025-03-04T00:00:00.0000000Z",
        "language": "en",
        "isFamilyFriendly": true
      },
      {
        "id": "https://api.contextfetch.dev/bing/v7.0/search#WebPages.2",
        "name": "Timeout for Python requests.get() entire response - Stack Overflow",
        "url": "https://stackoverflow.com/questions/21965484/timeout-for-python-requests-get-entire-response",
        "displayUrl": "stackoverflow.com/questions/21965484/timeout-for-python-requests-get-entire-response",
        "snippet": "timeout is not a time limit on the entire response download; rather, an exception is raised if the server has not issued a response for timeout ...",
        "dateLastCrawled": "2014-02-23T00:00:00.0000000Z",
        "language": "en",
        "isFamilyFriendly": true
      }
    ]
  },
  "rankingResponse": {
    "mainline": {
      "items": [
        {
          "answerType": "WebPages",
          "resultIndex": 0,
          "value": {
            "id": "https://api.contextfetch.dev/bing/v7.0/search#WebPages.0"
          }
        },
        {
          "answerType": "WebPages",
          "resultIndex": 1,
          "value": {
            "id": "https://api.contextfetch.dev/bing/v7.0/search#WebPages.1"
          }
        },
        {
          "answerType": "WebPages",
          "resultIndex": 2,
          "value": {
            "id": "https://api.contextfetch.dev/bing/v7.0/search#WebPages.2"
          }
        }
      ]
    }
  }
}

Questions

Does ContextFetch support Bing News, Image or Video Search?

No. Only the web search route, /bing/v7.0/search, is served. Calls to paths such as /bing/v7.0/news/search return 404. For recent news, use the web route with freshness=Day or Week.

Can I call the Bing-compatible route without a key?

Yes, for testing. Leave out the Ocp-Apim-Subscription-Key header and you get 25 free requests per IP address per UTC day. For anything regular, claim the free key, which carries $2.50 of balance.

Isn't Grounding with Bing Search the official replacement?

Microsoft points Bing API customers to Grounding with Bing Search, a tool inside Azure AI Agents that lets an agent use web data when an LLM writes its response. It is not a REST endpoint with the v7 request and response format, so code written for /v7.0/search does not run against it unchanged.

Do I need to change how I parse the response?

Usually not. The response keeps _type, queryContext.originalQuery, webPages.value and rankingResponse.mainline.items, and each page keeps name, url, displayUrl and snippet. Code that reads other answer types, such as news or images, gets nothing back for them.

Run it with your own key

A free key has 2,500 searches and needs no signup. Agents can claim one themselves with the POST below.

curl -X POST https://api.contextfetch.dev/v1/keys/free
Get a free key