Node.js Bing Search API Client
The `node-bing-api` library is a Node.js client for integrating with the Microsoft Cognitive Services Bing Web Search API. It provides synchronous and asynchronous access to various Bing search verticals, including Web, Composite, News, Video, Images, Related Search, and Spelling Suggestions. The current stable version is 4.1.1, with its last publication being over five years ago, indicating a maintenance release cadence rather than active feature development. The library is callback-centric by default, requiring the use of `util.promisify` for applications that prefer Promise-based asynchronous operations. A key differentiator is its direct mapping to the Bing API responses, providing raw body data, and its explicit support for features like market specification and adult content filtering. Users must provide a valid Azure Cognitive Services Bing Search API key for functionality.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'value')
cause This usually indicates that the API response `body` is malformed, empty, or does not contain the expected `webPages.value` property. Common causes include an invalid or expired API key, network issues, or an API error status code.fixVerify that your `accKey` is correct and active. Add robust error handling to check the `error` parameter in the callback and inspect `res.statusCode` before attempting to access properties on `body`. -
TypeError: Bing.web is not a function
cause The `Bing` object was not correctly initialized. The `require('node-bing-api')` call returns a factory function that *must* be invoked with an options object (containing `accKey`) to return the client instance.fixEnsure the initialization is `const Bing = require('node-bing-api')({ accKey: 'your-account-key' });`. Do not omit the `({ accKey: '...' })` part. -
Promise { <pending> } (or .then() never resolves)cause This occurs when attempting to use `.then()` directly on a callback-based method (e.g., `Bing.web()`) without first transforming it into a Promise using `util.promisify`.fixYou must use `util.promisify(Bing.web.bind(Bing))` to create a Promise-returning version of the method. Ensure you include `.bind(Bing)` to maintain the correct context. -
Request failed with status code 401
cause A 401 Unauthorized status code almost always indicates an issue with the API key, such as it being incorrect, expired, or lacking the necessary permissions for the requested operation.fixDouble-check your `accKey` for typos. Ensure your Azure subscription is active and the Bing Search API resource is properly configured and enabled.
Warnings
- breaking Version 4 of `node-bing-api` migrated to the Microsoft Cognitive Services Bing Search API v7. New API registrations might only support this version, requiring existing users to potentially update their code and API keys.
- breaking Version 3 introduced support for the new Cognitive Services API. This was a significant backend change that could affect existing applications not configured for Cognitive Services.
- breaking Version 2 changed the callback function signature, making it consistently the last parameter in all API method calls. Older code might have placed options or other parameters after the callback.
- gotcha The library is primarily callback-based. To use Promise-based `async/await` patterns, `util.promisify()` must be applied to each `Bing` method, specifically binding the method to the `Bing` instance (e.g., `util.promisify(Bing.web.bind(Bing))`) to preserve `this` context.
- gotcha A valid Azure Cognitive Services Bing Search API key is mandatory for all operations. Attempts to use the library without a correct and active key will result in API call failures or empty responses.
- gotcha Search methods have specific limits for `count` (number of results) and `offset` (pagination) that vary by search vertical. Exceeding these limits (e.g., `count: 50` for web search, `count: 15` for news search) may result in fewer results than requested or API errors.
Install
-
npm install node-bing-api -
yarn add node-bing-api -
pnpm add node-bing-api
Imports
- Bing
import Bing from 'node-bing-api';
const BingFactory = require('node-bing-api'); const Bing = BingFactory({ accKey: process.env.BING_API_KEY ?? '' }); - Bing.web
Bing.web("query", callback, options);Bing.web("query", options, callback); - promisify
const searchBingWeb = util.promisify(Bing.web);
const util = require('util'); const searchBingWeb = util.promisify(Bing.web.bind(Bing));
Quickstart
const util = require('util');
const BingFactory = require('node-bing-api');
// Ensure you set your BING_API_KEY as an environment variable
// You can get one from Azure Cognitive Services
const BING_API_KEY = process.env.BING_API_KEY ?? '';
if (!BING_API_KEY) {
console.error('Error: BING_API_KEY environment variable is not set.');
process.exit(1);
}
const Bing = BingFactory({ accKey: BING_API_KEY });
// Option 1: Using callbacks (default)
Bing.web("JavaScript library", {
count: 5,
offset: 0
}, function(error, res, body){
if (error) {
console.error('Callback Error:', error);
return;
}
if (body && body.webPages && body.webPages.value && body.webPages.value.length > 0) {
console.log('--- Callback Results (first 2 web pages) ---');
console.log(body.webPages.value[0]?.name + ' - ' + body.webPages.value[0]?.url);
console.log(body.webPages.value[1]?.name + ' - ' + body.webPages.value[1]?.url);
} else {
console.log('No web page results found via callback.');
}
});
// Option 2: Using Promises with util.promisify
const searchBingWebPromise = util.promisify(Bing.web.bind(Bing));
async function performPromiseSearch() {
try {
const [res, body] = await searchBingWebPromise("TypeScript documentation", {
count: 3,
offset: 0
});
if (body && body.webPages && body.webPages.value && body.webPages.value.length > 0) {
console.log('\n--- Promise Results (first web page) ---');
console.log(body.webPages.value[0]?.name + ' - ' + body.webPages.value[0]?.url);
} else {
console.log('No web page results found via Promise.');
}
} catch (error) {
console.error('\nPromise Error:', error);
}
}
performPromiseSearch();