Bing Webmaster CLI

  • Agents and operations
  • Operations CLI
  • 2026
  • Open source

Go, Bing Webmaster JSON API, IndexNow, OS keychain

Bing Webmaster CLI is a Go binary called bwt for Bing Webmaster Tools. It covers search performance, crawl health, URL and sitemap submission, IndexNow, keyword research and site settings. Each of the 59 non-obsolete methods in the Bing Webmaster JSON API has a command. I built it mainly for coding agents, so the JSON is stable and every write can be printed as a dry run first.

Bing’s API shows its age. Performance methods return Bing’s top rows with no date range or paging. Dates arrive as old WCF strings, and some legacy methods return empty lists for sites that do have links or crawl issues. A thin wrapper would pass all of that through, and an agent would read empty as healthy and submitted as indexed.

siteprojects.piyushgambhir.com/bing-webmaster-cli
Bing Webmaster CLI cover
A Go CLI for Bing Webmaster Tools. Search performance, crawl health, URL and sitemap submission, IndexNow and keyword research, built for agents.

bwtsession

# a dry run builds the request and sends nothingbwt submit urls https://www.example.com/new --dry-run -o yamldry_run: truerequests:  - method: SubmitUrl    http: POST    url: https://ssl.bing.com/webmaster/api.svc/json/SubmitUrl    body:      siteUrl: https://www.example.com/      url: https://www.example.com/new

1 command8 lines of output

Chapter
Agents and operations
Category
Operations CLI
Year
Availability
Open source
Last commit
stack4 parts
  • Go
  • Bing Webmaster JSON API
  • IndexNow
  • OS keychain

Go, CLI, Bing Webmaster Tools, IndexNow, SEO

A key, not OAuth

I planned the browser login I had built for Google Search Console CLI, and v0.1.1 shipped one. Registering the OAuth client then failed. Bing rejects http://127.0.0.1:47619/callback and its localhost twin as invalid URLs, and a CLI can only receive a code locally. A public relay page would add a server and a place for codes to leak. So bwt auth login opens Bing Webmaster Tools, reads the API key at a hidden prompt, and checks it with one GetUserSites call before saving. One key covers every site on the account. Profiles and keychain storage follow the gsc design. The key travels in the apikey query parameter, as Bing requires, so the client scrubs it from logs and errors.

One registry, 62 methods

Every Bing method is one entry in internal/registry, with its HTTP verb, parameters and an effect of read or write. Commands, --read-only, the raw bwt api call and the tests all read from it. Effect is behaviour, not verb. GetChildrenUrlInfo is the one POST that only reads, so it still runs under --read-only. The registry is checked against a vendored snapshot of Microsoft’s 62 reference pages, parsed from the published pages because the docs repository is private. TestRegistryMatchesSnapshot fails when a verb, parameter or obsolete marker drifts. TestMutatesMatchesRegistry fails unless a command blocks under --read-only exactly when one of its methods writes. bwt api methods -o json prints the registry, so an agent learns the surface without reading docs.

Only what Bing said

Successful responses arrive wrapped in a d field. Faults are documented under HTTP 400 and also arrive under HTTP 200. The client checks both and maps the code to a name such as InvalidApiKey or ThrottleUser. Dates become RFC 3339 with Bing’s offset kept, __type metadata is dropped, and --raw prints the wire JSON. The performance API has no server-side window, so --since, --until, --limit and --sort work locally, and JSON marks the result filtered_locally. Submissions report accepted, never indexed. crawl issues decodes Bing’s bitmask into an issue_labels field, and an empty list prints a warning rather than passing as health. Only stats summary adds rows together, and it states the window it covered.

Choices and their cost

  • The snapshot is parsed from Microsoft’s published pages, one request every few seconds, because learn.microsoft.com answers bursts with HTTP 429. Refreshing it is a manual chore, and the tests only notice drift after a refresh.
  • Nothing retries. ThrottleUser, ThrottleHost and HTTP 429 are reported, because Bing documents no rate numbers. submit urls lists the accepted batches and stops at the first failure, since resubmitting spends quota. A throttled run is mine to rerun by hand.
  • GetSiteMoves returned HTTP 404 in the live check, so site-move lives under bwt experimental and prints a notice on every run. The cost is a command that may never work.
  • Positions are printed raw. The test account had too little traffic to settle the position scale, or whether a date marks a day or a week. This is the one I would revisit, since raw positions cannot yet be compared with Google’s.

Publishing a change

bash6 lines
bwt auth login
bwt indexnow key generate
bwt indexnow key check
bwt indexnow submit --sitemap https://www.example.com/sitemap.xml --changed-since 2026-10-01
bwt submit urls https://www.example.com/new-page --dry-run -o json
bwt stats summary --compare previous

IndexNow needs no Bing login. key generate creates a 32-character key, follows the site’s www redirect, and says where KEY.txt must live. Keys sit in the config file, not the keychain, because the protocol publishes them. submit groups URLs by host, sends up to 10,000 per request, and explains each status, where 202 means key validation is pending. The dry run shows the exact SubmitUrl request before anything spends quota.

Where it stops

It is an independent client, not affiliated with Microsoft. Dashboard features without a public API are out of scope, including AI Performance and citations, Recommendations, Site Scan and IndexNow Insights. In the live check of 4 October 2026, the URL information methods returned UnknownError on a site without crawl data. Microsoft documents no cause. The name collides with Bitcoin Wallet Tracker, so the installer and bwt doctor warn. It is MIT licensed and at v0.1.7. Reckon pins it as its Bing tool and always runs it with BWT_READ_ONLY set.

All 43 projects