# Agents (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/agents)
`bwt` is built mainly for coding agents. Any agent or harness that can run shell commands can use it;
nothing else is needed.
## Ground rules [#ground-rules]
* Run commands with `-o json --no-input`. Data is on stdout; notes and structured errors are on stderr.
* Use `--read-only` unless the user asked for a change. It blocks every command that changes Bing state,
local credentials, or the binary itself.
* Run writes with `--dry-run` first and show the plan. Destructive commands (remove, block) also need
`--yes` under `--no-input`; pass it only when the user asked for that exact change.
* Never invent, print, or log an API key. If `bwt auth status -o json` fails, ask the user to run
`bwt auth login` or to set `BWT_API_KEY`.
```bash
# A safe, non-interactive read for an agent
bwt --read-only stats queries --sort clicks --limit 20 -o json --no-input
```
## Discover capabilities [#discover-capabilities]
```bash
bwt api methods -o json
```
Lists every Bing Webmaster method with its HTTP verb, `read` or `write` effect, status
(`implemented`, `experimental`, or `obsolete`), and the commands that call it. Read/write effects come
from a registry, not from the HTTP verb: `url children` is a read even though Bing implements it with
POST, so it works under `--read-only`.
For anything without a dedicated command, `bwt api METHOD` calls the method directly with the same
redaction, error handling, and date conversion. Unknown methods count as writes.
## Automation flags [#automation-flags]
| Flag | Environment | Effect |
| ------------- | ----------------- | ------------------------------------------------------------------- |
| `--read-only` | `BWT_READ_ONLY=1` | Blocks remote writes, credential changes, and self-update |
| `--no-input` | `BWT_NO_INPUT=1` | Never prompts or opens a browser; commands fail instead |
| `--dry-run` | | Prints every write request, including each batch, and sends nothing |
| `--yes`, `-y` | | Confirms destructive commands and `update` without a prompt |
| `--quiet` | `BWT_QUIET=1` | Drops informational notes from stderr |
| `--verbose` | `BWT_VERBOSE=1` | Logs method, redacted URL, and status to stderr |
| `--site` | `BWT_SITE` | Site for this command |
| `--profile` | `BWT_PROFILE` | Saved profile for this command |
Agents never see the update notice: its once-a-day GitHub check runs only when stderr is a terminal, and
`BWT_NO_UPDATE_NOTIFIER=1` turns it off everywhere. `bwt update --check -o json` reports
`current_version`, `latest_version`, `update_available`, `release_url`, and `install_method`.
## Reporting results honestly [#reporting-results-honestly]
* Performance rows are Bing's top rows; never sum them into site totals. Use `bwt stats summary`.
* Never call a submission "indexed". `submit` and `indexnow submit` report what Bing accepted.
* An empty `links` or `crawl issues` result is not proof of health; say so.
* `UnknownError` on URL methods means Bing gave no reason, not that the URL is missing from the index.
* `ThrottleUser` and `ThrottleHost` mean stop; do not retry in a loop.
[Reading the data](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/data) covers each of these in detail.
## Agent skill and LLM files [#agent-skill-and-llm-files]
* The agent skill lives at
[`bwt/SKILL.md`](https://github.com/piyush-gambhir/bing-webmaster-cli/blob/main/bwt/SKILL.md).
Copy it into your agent's skills directory.
* [`llms.txt`](https://projects.piyushgambhir.com/bing-webmaster-cli/llms.txt) indexes these docs,
and [`llms-full.txt`](https://projects.piyushgambhir.com/bing-webmaster-cli/llms-full.txt) contains
all of them, including the full command reference.
# Authentication (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/authentication)
Bing Webmaster Tools signs API calls with an API key. One key belongs to your Microsoft account and
covers every site you can access in Bing Webmaster Tools.
## Log in [#log-in]
```console
$ bwt auth login
Log in with your Bing Webmaster Tools API key (one key covers all your sites):
1. Opening https://www.bing.com/webmasters
2. Go to Settings (gear icon) > API Access > API Key, then Generate or copy your key.
3. Paste it below. Input is hidden.
Bing Webmaster API key:
Logged in (profile "default"). Found 1 site; default site is https://www.example.com/ (change with: bwt sites use SITE).
```
What happens:
1. In a terminal, `bwt` opens Bing Webmaster Tools and reads the key from a hidden prompt. Piped input
is read from stdin instead, so scripts work too.
2. The key is checked with one `GetUserSites` call **before** anything is saved. If Bing rejects it,
nothing is saved. A newly generated key can take about 30 minutes to start working; `--no-verify`
saves it without the check.
3. The key goes into the OS keychain: macOS Keychain, Windows Credential Manager, or the Secret
Service on Linux. Without a keychain, login stops unless you pass `--insecure-storage`, which keeps
the key in a plaintext file with `0600` permissions.
4. A default site is chosen: your only site, a numbered pick when you have several, or none under
`--no-input` (set one later with `bwt sites use SITE`).
## Without saving anything (CI and agents) [#without-saving-anything-ci-and-agents]
```bash
BWT_API_KEY=... bwt sites list -o json # one command, nothing stored
printf '%s' "$KEY" | bwt auth login --no-input --profile ci # or save it to a named profile
```
Prefer the environment variable or stdin over `--api-key`, which can end up in your shell history.
## Several accounts or clients [#several-accounts-or-clients]
Each profile is a separate login:
```bash
bwt auth login --profile client-b # add a profile
bwt auth list # list profiles (never shows secrets)
bwt --profile client-b sites list # use one for a single command
bwt auth use client-b # change the default profile
```
`BWT_PROFILE` also selects a profile. Parallel commands are safe: each profile has its own keychain
entry, and login and logout take a per-profile lock. Keychain entries are namespaced by config file,
so separate configs (`BWT_CONFIG`) never overwrite each other's keys.
## Credential precedence [#credential-precedence]
`--access-token` > `BWT_ACCESS_TOKEN` > `--api-key` > `BWT_API_KEY` > the selected profile. Profiles
are chosen by `--profile`, then `BWT_PROFILE`, then the saved default.
```bash
bwt auth status # which credential and site are active; no network call
bwt auth status --verify # plus one GetUserSites check
```
## Bearer tokens [#bearer-tokens]
`--access-token` or `BWT_ACCESS_TOKEN` sends a bearer token obtained elsewhere, for example from your
own OAuth web application. Bearer calls go to `www.bing.com`, as Bing's OAuth guide shows;
`BWT_OAUTH_API_HOST=ssl.bing.com` switches hosts.
## Why there is no browser login [#why-there-is-no-browser-login]
Bing's OAuth client registration rejects loopback redirect URIs: `http://127.0.0.1:47619/callback`
and `http://localhost:47619/callback` are both refused as "not a valid http or https url" (checked
2026-10-04). A command-line tool can only receive an OAuth code on the local machine, so browser
OAuth would need a public web page that relays codes to the CLI. An API key gives the same access with
one copy and paste.
Profiles saved by v0.1.1, which had a browser login, stop working until you run
`bwt auth login --profile NAME` with an API key. Login and logout both delete the old OAuth tokens.
## Logging out and rotating the key [#logging-out-and-rotating-the-key]
`bwt auth logout` deletes the saved key from this machine and keeps the profile's site and IndexNow
keys. It does not invalidate the key. Bing allows one API key per account, and regenerating it under
**Settings > API Access** invalidates it everywhere; run `bwt auth login` again on each machine
afterwards.
The key travels in the `apikey` query parameter, as Bing requires. `bwt` removes it from verbose logs,
error messages, and transport errors, and never follows a redirect with it.
## Troubleshooting [#troubleshooting]
| Message | Fix |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `Bing did not accept this key, so nothing was saved` | Check the key. A new key can take about 30 minutes to activate; retry later, or pass `--no-verify` |
| `InvalidApiKey` | The key was regenerated or mistyped; run `bwt auth login` |
| `used browser login, which bwt no longer supports` | The profile is from v0.1.1; run `bwt auth login` with your API key |
| `No OS keychain is available` | Start a keychain service, pass `--insecure-storage`, or use `BWT_API_KEY` |
| `OS keychain did not respond within 10s` | Unlock the keychain and retry |
| `NotAuthorized` | Use the site URL exactly as `bwt sites list` prints it, and check that your account can access the site |
# Crawl & URLs (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/commands/crawl-urls)
## Crawl [#crawl]
```bash
bwt crawl stats # daily crawled pages, index counts, errors, and HTTP status classes
bwt crawl issues # URLs Bing had trouble crawling, with the issue bitmask decoded
bwt crawl settings # hourly crawl rate and crawl boost
```
`crawl issues` adds `issue_labels`, decoded locally from Bing's `Issues` bitmask. To change the crawl
rate or boost, see [Site settings](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/commands/site-settings#crawl-rate-and-boost).
## URLs [#urls]
```bash
bwt url info https://www.example.com/page # last crawl, discovery, status, size
bwt url traffic https://www.example.com/page # clicks and impressions
bwt url children https://www.example.com/blog/ --http 4xx,5xx --all
bwt url children-traffic https://www.example.com/blog/
```
`url children` filters by `--http`, `--crawl-date`, `--discovered`, and `--doc-flags`. Pages start at
0, and `--all` continues until Bing returns an empty page, bounded by `--max-pages` (default 100).
## Inbound links [#inbound-links]
```bash
bwt links counts --all # pages with inbound link counts
bwt links list https://www.example.com/ --all # links to one page, with anchor text
```
## Fetch as Bingbot [#fetch-as-bingbot]
```bash
bwt fetch request https://www.example.com/new-page # ask Bingbot to fetch it
bwt fetch list # requests and whether they finished
bwt fetch get https://www.example.com/new-page --save fetched.txt
```
`fetch get` shows the status in a table; `--save` writes what Bingbot fetched (its crawl record and the
response) to a file, and `-o json` includes it too.
`url info` has no "indexed" field, and empty `links` or `crawl issues` results are not proof of
health. On a site without crawl data, the URL methods return `UnknownError`. See
[Reading the data](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/data).
# Overview (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/commands)
Every command has `-h`/`--help`, and every command that returns data accepts `-o json|yaml|csv`. The
[command reference](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/reference/commands) lists every flag; these pages show how the groups fit
together.
## Groups [#groups]
## Global flags [#global-flags]
| Flag | Effect |
| ----------------------------------- | ------------------------------------------------------------------- |
| `-s`, `--site` | Site URL exactly as in `sites list`, or a bare host (or `BWT_SITE`) |
| `--profile` | Saved profile (or `BWT_PROFILE`) |
| `-o`, `--output` | `table` (default), `json`, `yaml`, or `csv` |
| `--read-only` | Block remote writes, local credential changes, and self-update |
| `--dry-run` | For writes: print the requests and send nothing |
| `-y`, `--yes` | Confirm destructive commands and updates without a prompt |
| `--no-input` | Never prompt or open a browser |
| `--raw` | Print Bing's wire JSON without date conversion |
| `-q`, `--quiet` / `-v`, `--verbose` | Fewer notes, or a log line per request, on stderr |
| `--timeout` | HTTP request timeout (default `30s`) |
| `--api-key`, `--access-token` | Credential overrides; prefer `BWT_API_KEY` or `bwt auth login` |
## Account and setup [#account-and-setup]
```bash
bwt auth status # also: login, list, use, logout
bwt doctor --verify # local checks plus one GetUserSites call
bwt update --check
bwt completion zsh > "${fpath[1]}/_bwt"
```
## Any Bing method [#any-bing-method]
`bwt api` calls a Bing Webmaster method directly, with the same redaction, error handling, and date
conversion as every other command:
```bash
bwt api methods -o json # every method and its command
bwt api GetUserSites
bwt api GetQueryStats --param siteUrl=https://www.example.com/
bwt api SubmitUrlBatch --data '{"siteUrl":"https://www.example.com/","urlList":["https://www.example.com/a"]}'
```
Known methods use their documented HTTP verb and read/write effect. Writes ask for confirmation, and
`--read-only` refuses them.
# Keyword research (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/commands/keywords)
Keyword research reports Bing search demand for a query in a market. It is market data, not your
site's performance, so it needs no `--site`.
```bash
bwt keywords get "running shoes" # impressions over a date range
bwt keywords stats "running shoes" # weekly impression history
bwt keywords related "running shoes" --country gb --language en-GB
```
`--country` (default `us`) and `--language` (default `en-US`) pick the market. `get` and `related`
take `--start` and `--end` dates (`YYYY-MM-DD`); `--end` defaults to today (UTC) and `--start` to 30
days before it. Microsoft does not document the accepted date syntax, so `bwt` sends `YYYY-MM-DD`,
which works in live checks.
# Search performance (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/commands/performance)
```bash
bwt stats summary --compare previous # totals for the latest 28 days, and the change
bwt stats traffic --since 2026-09-01 # clicks and impressions by day
bwt stats queries --sort clicks --limit 20 # top queries
bwt stats pages --sort impressions --limit 20 # top pages
```
## Drill down [#drill-down]
```bash
bwt stats query-pages "running shoes" # pages that rank for a query
bwt stats page-queries https://www.example.com/shoes/ # queries that lead to a page
bwt stats detail "running shoes" https://www.example.com/shoes/ # position detail for both
bwt stats query-traffic "running shoes" # daily history for a top query
```
## Summaries [#summaries]
`bwt stats summary` sums daily site traffic over the latest `--days` (default 28) calendar days that
Bing returned and recomputes CTR from the sums. `--compare previous` adds the preceding window and the
change; percentage changes are `null` when the earlier value is zero, and the CTR change is in
percentage points.
## Filtering and sorting [#filtering-and-sorting]
`--since`, `--until`, `--limit`, `--sort`, and `--asc` work **locally**, because Bing's API has no date
range or paging. Sort keys: `date`, `clicks`, `impressions`, `ctr`, `query`, `position`,
`avg-click-position`, and `avg-impression-position`.
```bash
bwt stats queries --since 2026-09-01 --sort ctr --limit 10 -o json
```
These are Bing's top rows, not complete data. Never add query or page rows up into site totals; use
`stats summary`. See [Reading the data](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/data).
# Site settings (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/commands/site-settings)
Every command on this page that changes Bing state is blocked by `--read-only`, and `--dry-run`
prints its request without sending it.
## Sites [#sites]
```bash
bwt sites list # use these URLs exactly in other commands
bwt sites add https://www.example.com/
bwt sites verify https://www.example.com/ # after adding the XML file, meta tag, or DNS record
bwt sites use https://www.example.com/ # the profile's default site (local only)
bwt sites remove https://old.example.com/
```
`sites list -o json` includes each site's `AuthenticationCode` and `DnsVerificationCode` for
verification. `sites verify` prints `verified: false` when Bing could not confirm ownership.
## Users and roles [#users-and-roles]
```bash
bwt users list --all-subdomains
bwt users add colleague@example.com --role read-only
bwt users remove colleague@example.com
```
Roles are `admin`, `read-only`, and `read-write`. `--delegated-url` targets a host under the site.
## URL parameters [#url-parameters]
Query parameters Bing should ignore when normalizing URLs:
```bash
bwt params list
bwt params add sessionid
bwt params disable sessionid # or: enable, remove
```
## Blocked URLs and previews [#blocked-urls-and-previews]
```bash
bwt block list
bwt block add https://www.example.com/private/ --type directory --request cache-only
bwt block remove https://www.example.com/private/
bwt preview-blocks list
bwt preview-blocks add https://www.example.com/page --reason 1
bwt preview-blocks remove https://www.example.com/page
```
`block add` has no default `--request`: `cache-only` removes the cached copy, and `full-removal`
removes the URL from Bing results until it expires (and asks for confirmation). Microsoft does not
publish the preview `--reason` values; `1` is `ContentNeedsToBeRemoved`.
## Geo-targeting and deep links [#geo-targeting-and-deep-links]
```bash
bwt geo list
bwt geo add --url https://www.example.com/uk/ --type directory --country gb
bwt geo remove --url https://www.example.com/uk/ --type directory --country gb
bwt deeplink-blocks list
bwt deeplink-blocks add --market en-US --search-url https://www.example.com/ \
--deep-link-url https://www.example.com/old-page
```
Bing accepts only lowercase country and market codes; `bwt` lowercases them for you.
## Connected pages [#connected-pages]
```bash
bwt connected-pages list
bwt connected-pages add https://social.example.com/your-profile
```
## Crawl rate and boost [#crawl-rate-and-boost]
```bash
bwt crawl settings
bwt crawl set-settings --boost on
bwt crawl set-settings --rate 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,4,3,3,4
```
`set-settings` reads the current settings, applies your change, and saves the full object. `--rate`
takes 24 hourly values; Bing does not document their valid range or timezone.
## Site moves (experimental) [#site-moves-experimental]
```bash
bwt experimental site-move list
bwt experimental site-move submit --from https://old.example.com/ --to https://www.example.com/ \
--scope host --type global
```
Bing still documents these methods, but `GetSiteMoves` returned HTTP 404 in a live check. Each run
prints a notice; confirm the result in the Bing Webmaster Tools dashboard.
# Submission & IndexNow (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/commands/submission)
## IndexNow (preferred) [#indexnow-preferred]
IndexNow tells Bing and the other participating search engines about new, changed, or deleted URLs. It
needs no Bing login and spends no Bing quota; you prove ownership by hosting a key file.
```bash
bwt indexnow key generate # creates a key for your site's host and saves it
# upload KEY.txt, containing only the key, to https://www.example.com/KEY.txt
bwt indexnow key check # fetches the key file and confirms it matches
```
`key generate` and `key check` follow your site's redirect between `example.com` and
`www.example.com`, so the key lands on the host that serves your pages. Pass `--host` to choose one.
```bash
bwt indexnow submit https://www.example.com/new-post
bwt indexnow submit --file changed.txt
bwt indexnow submit --sitemap https://www.example.com/sitemap.xml --changed-since 2026-10-01
```
URLs are grouped by host and sent up to 10,000 per request. `--endpoint` picks `indexnow`
(`api.indexnow.org`, the default), `bing`, or any HTTPS endpoint; one submission reaches every
participating engine. `200` and `202` mean received (`202`: key validation pending), not indexed.
## URL submission [#url-submission]
```bash
bwt quota # remaining daily and monthly quota
bwt submit urls https://www.example.com/new-page --dry-run
bwt submit urls https://www.example.com/new-page
bwt submit urls --file urls.txt --check-quota # batches of up to 500
```
On a failure, `submit urls` reports the batches Bing accepted and stops. It never resubmits, because
every submission spends quota, even for the same URL.
## Content submission [#content-submission]
Push a page's full HTTP response so Bing can index it without crawling:
```bash
curl -s --http1.1 -i https://www.example.com/ -o home.http
bwt submit content https://www.example.com/ --file home.http
```
The file holds the status line, headers, a blank line, and the body, up to 10 MB. Add
`--structured-data` for a JSON-LD file and `--dynamic-serving` for device-specific pages. It works with
an API key and spends the separate content quota. Submitted content can be indexed even when
`robots.txt` disallows the URL; `NOINDEX` is honored.
## Sitemaps [#sitemaps]
```bash
bwt sitemaps list
bwt sitemaps submit https://www.example.com/sitemap.xml
bwt sitemaps get https://www.example.com/sitemap_index.xml # sitemaps inside an index
bwt sitemaps remove https://www.example.com/old-sitemap.xml
```
XML sitemaps, sitemap indexes, RSS 2.0, Atom 0.3 and 1.0, and text feeds are supported.
# Compatibility (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/compatibility)
`bwt` targets the Bing Webmaster **JSON** API at `https://ssl.bing.com/webmaster/api.svc/json/`, as
documented on Microsoft Learn, plus the IndexNow protocol.
## Pinned documentation snapshot [#pinned-documentation-snapshot]
The method registry is tested against a snapshot of Microsoft's reference, captured on 2026-10-03:
62 methods (35 GET, 27 POST). Three are marked obsolete by Microsoft and are never called
(`GetDeepLink`, `GetDeepLinkAlgoUrls`, `UpdateDeepLink`). The other 59 each have a command. The two
site-move methods live under `bwt experimental`: `GetSiteMoves` returned HTTP 404 in a live check, and
`SubmitSiteMove` was only checked with `--dry-run`.
Tests fail when the registry drifts from the snapshot, when a method has no command, or when a
command's read/write classification disagrees with the registry. The
[API coverage](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/reference/api-coverage) page lists every method, and the
[compatibility record](https://github.com/piyush-gambhir/bing-webmaster-cli/blob/main/docs/compatibility.md)
has the exact documentation commits and how to refresh them.
Legacy SOAP and POX endpoints were retired on August 31, 2026. `bwt` never used them.
## Live checks (2026-10-04) [#live-checks-2026-10-04]
Commands were run against a real account with an API key. Reads ran under `--read-only`, writes were
limited to reversible ones on a test page or a throwaway test site, and every change was undone.
Commands with outside effects (`users add`, `users remove`, `connected-pages add`, `sitemaps remove`, and
`experimental site-move submit`) were checked with `--dry-run` only.
| Area | Result |
| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| Login, sites, sitemaps, quota, crawl settings, keywords, users, fetch, URL parameters, blocks, preview blocks | Working |
| `submit urls` and `submit content` | Working with an API key, and counted against the URL and content quotas |
| Geo-targeting | Needs a lowercase country code (`us`); `bwt` lowercases it for you |
| Deep-link blocks | Need a lowercase market (`en-us`); `bwt` lowercases it for you |
| IndexNow | `api.indexnow.org` accepted submissions |
| Performance and crawl stats | Empty for a site with little traffic; not an error |
| `url info`, `url traffic`, `url children` | `UnknownError` on a site without crawl data, also when called directly; cause undocumented |
| Site moves (`GetSiteMoves`) | HTTP 404; kept under `bwt experimental` |
Still unsettled, because the test site had little data: the scale of the position fields, whether
performance dates mark days or weekly buckets, and the URL information methods on a crawled site.
## Platforms [#platforms]
Prebuilt binaries for macOS, Linux, and Windows on `amd64` and `arm64`. CI runs the tests on all three
operating systems.
# Reading the data (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/data)
Bing's API has gaps that are easy to misread. `bwt` is explicit about them, and this page explains
why.
## Performance data is Bing's top rows [#performance-data-is-bings-top-rows]
The `stats` methods return Bing's own selection of top rows. The API has no server-side date range,
row limit, or paging.
* `--since`, `--until`, `--limit`, and `--sort` filter and sort **locally**, and JSON output says so
with `filtered_locally: true`.
* **Never add up query or page rows to get site totals.** Use `bwt stats summary`, which sums the daily
site traffic over a stated window and recomputes CTR from the sums.
* Query and page statistics update **weekly**; site traffic and query traffic update **daily**.
* Positions (`AvgClickPosition`, `AvgImpressionPosition`) are printed exactly as Bing returns them,
because Microsoft does not document their scale.
* A new or low-traffic site returns no rows at all. That is missing data, not zero traffic.
## Accepted is not indexed [#accepted-is-not-indexed]
`bwt submit urls`, `bwt submit content`, and `bwt indexnow submit` report what Bing **received**. A
`200` or `202` from IndexNow means the submission was accepted (`202`: the key is still being
validated). None of them means the URL is, or will be, indexed.
## There is no indexing verdict [#there-is-no-indexing-verdict]
`bwt url info` shows crawl details: last crawl, discovery date, HTTP status, size, and child count.
The API has no "indexed" field, and a zero status or `IsPage: false` describes crawling, not indexing.
On a site without crawl data, the URL methods (`url info`, `url traffic`, `url children`) return
Bing's `UnknownError`. Microsoft documents no cause, so treat it as "no answer", not "not indexed".
## Empty is not healthy [#empty-is-not-healthy]
`bwt links` and `bwt crawl issues` can return empty lists for sites that do have links or issues.
Fixed crawl issues can also stay listed for several days. `bwt` notes this on stderr; an empty result
is not proof of anything.
## Quotas belong to each site [#quotas-belong-to-each-site]
`bwt quota` shows Bing's daily and monthly counters exactly as returned. Every `submit urls` call
spends quota, even for a URL you already submitted, so `bwt` never resubmits automatically. IndexNow
has no Bing quota and reaches every participating search engine, so prefer it for new or changed
URLs.
# Introduction (https://projects.piyushgambhir.com/bing-webmaster-cli/docs)
**Bing Webmaster CLI** (`bwt`) is a command-line interface for **Bing Webmaster Tools**. Read search
performance and crawl health, submit URLs, sitemaps, and page content, notify search engines with
IndexNow, and manage site settings from your terminal.
It is built mainly for coding agents and works just as well at the keyboard. Every command can print
JSON, writes can be previewed with `--dry-run`, and `--read-only` blocks every change.
The binary is `bwt`. One Bing Webmaster API key covers every site in your account, and
`bwt auth login` keeps it in your OS keychain.
## What it covers [#what-it-covers]
* **Search performance:** top queries and pages, clicks and impressions by day, query and page
drill-downs, and a summary over a stated window.
* **Crawl health:** daily crawl stats, crawl issues with the bitmask decoded, crawl rate and boost,
URL details, inbound links, and Fetch as Bingbot.
* **Submission:** URLs (one at a time or batched), full page content, sitemaps and feeds, and quota.
* **IndexNow:** key generation and checks, and submissions from arguments, a file, or a sitemap
filtered by date.
* **Site settings:** sites and verification, users and roles, URL parameters, blocked URLs, preview
blocks, geo-targeting, and deep-link blocks.
* **Keyword research:** impressions, weekly history, and related queries for any market.
* **Anything else:** `bwt api` calls any Bing Webmaster method directly, and `bwt api methods` lists
every method with its read or write effect.
Each of the 59 current methods in the Bing Webmaster JSON API has a command. The
[API coverage](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/reference/api-coverage) page maps them one by one.
## Next steps [#next-steps]
**Independent project.** Not affiliated with, endorsed by, or sponsored by Microsoft. Bing and Bing
Webmaster Tools are trademarks of Microsoft, named here only to identify the service this tool works with.
# Installation (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/installation)
## Install script (recommended) [#install-script-recommended]
For macOS and Linux. The script downloads the latest release for your OS and architecture, checks its
SHA-256 checksum, and installs `bwt` to `~/.local/bin`:
```bash
curl -fsSL https://raw.githubusercontent.com/piyush-gambhir/bing-webmaster-cli/main/install.sh | sh
```
Pin a version or change the install directory:
```bash
curl -fsSL https://raw.githubusercontent.com/piyush-gambhir/bing-webmaster-cli/main/install.sh | VERSION=v0.1.2 sh
curl -fsSL https://raw.githubusercontent.com/piyush-gambhir/bing-webmaster-cli/main/install.sh | INSTALL_DIR=/usr/local/bin sh
```
Another program, Bitcoin Wallet Tracker, also installs a binary named `bwt`. The installer warns when a
different `bwt` comes first on your `PATH`, and `bwt doctor` checks for it too.
## Download a release manually [#download-a-release-manually]
Each [GitHub release](https://github.com/piyush-gambhir/bing-webmaster-cli/releases) has
`bing-webmaster-cli__.tar.gz` archives for `darwin` and `linux` (`amd64` or `arm64`) and
`bing-webmaster-cli_windows_.zip` for Windows. Extract `bwt` and put it on your `PATH`.
`checksums.txt` lists the SHA-256 of every archive.
## Verify a download [#verify-a-download]
Releases are immutable once published. Every archive ships with an SBOM and a signed build-provenance
attestation, so you can confirm it was built by the repository's release workflow:
```bash
gh attestation verify bing-webmaster-cli_darwin_arm64.tar.gz --repo piyush-gambhir/bing-webmaster-cli
```
## Build from source [#build-from-source]
Requires Go 1.26 or later:
```bash
git clone https://github.com/piyush-gambhir/bing-webmaster-cli.git
cd bing-webmaster-cli/cli-go
make install # installs to $GOBIN or $(go env GOPATH)/bin
```
## Check and update [#check-and-update]
```bash
bwt version # build info, plus the latest version from the last release check
bwt doctor # configuration, credentials, default site, and PATH; no Bing calls
bwt update --check # is a newer release out? (-o json for scripts)
bwt update # asks, then installs it after SHA-256 verification
```
`bwt update` works on macOS, Linux, and Windows. It downloads the release archive for your platform,
checks it against the release's `checksums.txt`, and replaces the running executable. On Windows the old
executable is renamed to `bwt.exe.old` and deleted the next time `bwt` starts. `--yes` (`-y`) skips the
question, and `--no-input` requires `--yes`. If the install directory is not writable, the update stops and
the old binary keeps working: re-run with `sudo`, or reinstall with the install script into a directory you
own. A `bwt` in a Go bin directory (`$GOBIN`, `$GOPATH/bin`, or `~/go/bin`) came from a source build, so
`bwt update` tells you to run `git pull && make install` in your checkout instead of replacing it.
### Update notice [#update-notice]
In an interactive terminal, `bwt` checks the github.com release page for a new release at most once a day
(not the GitHub API, so its per-IP rate limit never applies). When one is out, it
prints a notice on stderr after the command's output, at most once a day per version:
```text
A new version of bwt is available: v0.1.3 -> v0.1.4
Update with: bwt update
Release notes: https://github.com/piyush-gambhir/bing-webmaster-cli/releases/tag/v0.1.4
```
Only the one command a day that runs the check waits for its answer, at most 1 second after its output;
every other command uses the cached answer and never waits. `bwt update` and `bwt update --check` store
what they find in the same cache. The check never runs (no network, no output) when:
* stderr is not a terminal (pipes, scripts, coding agents),
* `CI` is set,
* `--quiet` or `BWT_QUIET=1` is on,
* `BWT_NO_UPDATE_NOTIFIER` or `NO_UPDATE_NOTIFIER` is set to any value, or
* the command is `update`, `version`, `completion`, or `help`.
To turn it off for good, add `export BWT_NO_UPDATE_NOTIFIER=1` to your shell profile.
# Output formats (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/output-formats)
## Formats [#formats]
`-o table` is the default. `-o json`, `-o yaml`, and `-o csv` are available on every command that
returns data.
```bash
bwt sites list # table
bwt stats queries -o json # JSON for scripts and agents
bwt stats pages -o csv > pages.csv # spreadsheet-ready
```
## stdout and stderr [#stdout-and-stderr]
Data goes to **stdout**. Notes, hints, and errors go to **stderr**, so piping stdout always gives you
clean data. `--quiet` drops informational notes, and `--verbose` logs each request's method, redacted
URL, and HTTP status to stderr.
## JSON [#json]
* **Bing's field names are kept** (`Url`, `Clicks`, `Impressions`, `DailyQuota`), so Bing's own
documentation still applies to the data.
* **Most commands print Bing's data as it is:** an object, or a list such as `sites list`,
`sitemaps list`, and `crawl issues`.
* **Commands that filter, page, or compute add an envelope**, with the CLI's own fields in snake\_case.
The `stats` listings say where the rows came from and whether anything was filtered locally:
```json
{
"site": "https://www.example.com/",
"method": "GetQueryStats",
"update_cadence": "weekly",
"filtered_locally": true,
"row_count": 20,
"rows": [{ "Query": "example", "Clicks": 12, "Impressions": 340 }]
}
```
Paged listings (`url children`, `url children-traffic`, `links counts`, `links list`) use `site`,
`method`, `pages_fetched`, `complete`, `row_count`, and `rows`. `stats summary` reports `window_days`,
`current`, and with `--compare`, `previous` and `change`.
* **Dates become RFC 3339.** Bing sends Microsoft JSON dates such as `/Date(1315349995284-0700)/`;
`bwt` prints `2011-09-06T15:59:55.284-07:00`, keeping Bing's offset.
* **Bing's `__type` metadata is removed.** `--raw` prints Bing's wire JSON exactly as received.
## Errors [#errors]
Every failure exits with status `1`. With `-o json` or `-o yaml`, stderr carries a structured error:
```json
{
"api_error_code": 3,
"api_error_name": "InvalidApiKey",
"error": "Bing GetUserSites failed: InvalidApiKey (code 3, HTTP 400): the API key is invalid; ...",
"http_status": 400,
"method": "GetUserSites"
}
```
`retry_after` is added when Bing sends a `Retry-After` header. The error text includes a hint for the
common cases:
| `api_error_name` | Meaning |
| -------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `InvalidApiKey` | The key is wrong, regenerated, or not active yet; run `bwt auth login` |
| `NotAuthorized` | The site URL does not match `bwt sites list` exactly, or your account lacks access |
| `InvalidUrl`, `InvalidParameter` | Bing rejected a URL or value; check the scheme, trailing slash, and casing |
| `ThrottleUser`, `ThrottleHost` | Bing is rate limiting; wait. `bwt` never retries automatically |
| `UnknownError` | Bing gave no reason. Seen on URL methods for sites without crawl data; never read it as "not indexed" |
| `NotFound`, `AlreadyExists` | The item is missing, or already there |
API keys and bearer tokens never appear in errors or logs.
# Quick start (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/quickstart)
## 1. Log in [#1-log-in]
```bash
bwt auth login
```
`bwt` opens Bing Webmaster Tools. Under **Settings > API Access > API Key**, generate or copy your key
and paste it at the hidden prompt. The key is checked, saved in your OS keychain, and your only site
(or the one you pick) becomes the default.
## 2. Check your sites [#2-check-your-sites]
```bash
bwt sites list
bwt sites use https://www.example.com/ # change the default site
bwt auth status # the active credential and site
```
Use site URLs exactly as `sites list` prints them, with the scheme and trailing slash. `--site` (or
`-s`) picks a site for one command, and a bare host such as `example.com` works when it matches one
of your sites.
## 3. Read your performance [#3-read-your-performance]
```bash
bwt stats summary --compare previous # the latest 28 days against the 28 before
bwt stats queries --sort clicks --limit 20
bwt stats pages --sort impressions --limit 20 -o csv > pages.csv
```
## 4. Check crawl health [#4-check-crawl-health]
```bash
bwt crawl stats
bwt crawl issues
bwt sitemaps list
bwt quota
```
## 5. Tell search engines what changed [#5-tell-search-engines-what-changed]
```bash
bwt submit urls https://www.example.com/new-page --dry-run # see the request first
bwt submit urls https://www.example.com/new-page
bwt indexnow key generate # then upload KEY.txt to your site's root
bwt indexnow key check
bwt indexnow submit https://www.example.com/new-page
```
A new site, or one with little traffic, returns no performance or crawl rows for a while. `bwt` says
so on stderr rather than leaving you with an unexplained empty table.
## Discovering commands [#discovering-commands]
```bash
bwt --help
bwt stats --help
bwt api methods # every Bing method and the command that calls it
```
# API coverage (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/reference/api-coverage)
Generated from the operation registry and the `bwt` command tree on `main`. Tests fail when a documented method has no
command or when a command's read or write classification disagrees with the registry.
The registry is checked against the pinned documentation snapshot described in [Compatibility](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/compatibility):
62 methods, of which 57 are implemented, 2 are implemented as experimental, and 3 are never implemented.
Effect is behavior, not HTTP verb: `read` methods are allowed under `--read-only`; `write` methods are blocked.
Experimental commands print a notice on every run: Bing still documents them, but a live check failed (GetSiteMoves returned HTTP 404).
## Sites [#sites]
| Method | HTTP | Effect | Status | Command | Notes |
| -------------- | ---- | ------ | ----------- | --------------------------------- | -------------------------- |
| `GetUserSites` | GET | read | implemented | `bwt sites list`, `bwt users add` | |
| `AddSite` | POST | write | implemented | `bwt sites add` | |
| `VerifySite` | POST | write | implemented | `bwt sites verify` | changes verification state |
| `RemoveSite` | POST | write | implemented | `bwt sites remove` | |
## Users and roles [#users-and-roles]
| Method | HTTP | Effect | Status | Command | Notes |
| ---------------- | ---- | ------ | ----------- | ------------------------------------ | ----- |
| `GetSiteRoles` | GET | read | implemented | `bwt users list`, `bwt users remove` | |
| `AddSiteRoles` | POST | write | implemented | `bwt users add` | |
| `RemoveSiteRole` | POST | write | implemented | `bwt users remove` | |
## URL and content submission [#url-and-content-submission]
| Method | HTTP | Effect | Status | Command | Notes |
| --------------------------- | ---- | ------ | ----------- | ------------------------------ | -------------------------------------------------------------------------------------- |
| `SubmitUrl` | POST | write | implemented | `bwt submit urls` | |
| `SubmitUrlBatch` | POST | write | implemented | `bwt submit urls` | 500 URLs per request |
| `GetUrlSubmissionQuota` | GET | read | implemented | `bwt quota`, `bwt submit urls` | |
| `SubmitContent` | POST | write | implemented | `bwt submit content` | works with an API key (verified 2026-10-04); content can be indexed despite robots.txt |
| `GetContentSubmissionQuota` | GET | read | implemented | `bwt quota` | |
## Sitemaps and feeds [#sitemaps-and-feeds]
| Method | HTTP | Effect | Status | Command | Notes |
| ---------------- | ---- | ------ | ----------- | --------------------- | ----- |
| `GetFeeds` | GET | read | implemented | `bwt sitemaps list` | |
| `GetFeedDetails` | GET | read | implemented | `bwt sitemaps get` | |
| `SubmitFeed` | POST | write | implemented | `bwt sitemaps submit` | |
| `RemoveFeed` | POST | write | implemented | `bwt sitemaps remove` | |
## Search performance [#search-performance]
| Method | HTTP | Effect | Status | Command | Notes |
| ------------------------- | ---- | ------ | ----------- | ---------------------------------------- | --------------------------- |
| `GetQueryStats` | GET | read | implemented | `bwt stats queries` | top queries; updated weekly |
| `GetPageStats` | GET | read | implemented | `bwt stats pages` | top pages; updated weekly |
| `GetQueryPageStats` | GET | read | implemented | `bwt stats query-pages` | |
| `GetPageQueryStats` | GET | read | implemented | `bwt stats page-queries` | |
| `GetQueryPageDetailStats` | GET | read | implemented | `bwt stats detail` | |
| `GetQueryTrafficStats` | GET | read | implemented | `bwt stats query-traffic` | updated daily |
| `GetRankAndTrafficStats` | GET | read | implemented | `bwt stats summary`, `bwt stats traffic` | updated daily |
## Crawl [#crawl]
| Method | HTTP | Effect | Status | Command | Notes |
| ------------------- | ---- | ------ | ----------- | ---------------------------------------------- | ----- |
| `GetCrawlStats` | GET | read | implemented | `bwt crawl stats` | |
| `GetCrawlIssues` | GET | read | implemented | `bwt crawl issues` | |
| `GetCrawlSettings` | GET | read | implemented | `bwt crawl set-settings`, `bwt crawl settings` | |
| `SaveCrawlSettings` | POST | write | implemented | `bwt crawl set-settings` | |
## URL information [#url-information]
| Method | HTTP | Effect | Status | Command | Notes |
| --------------------------- | ---- | ------ | ----------- | -------------------------- | --------------------- |
| `GetUrlInfo` | GET | read | implemented | `bwt url info` | |
| `GetUrlTrafficInfo` | GET | read | implemented | `bwt url traffic` | |
| `GetChildrenUrlInfo` | POST | read | implemented | `bwt url children` | a read that uses POST |
| `GetChildrenUrlTrafficInfo` | GET | read | implemented | `bwt url children-traffic` | |
## Links [#links]
| Method | HTTP | Effect | Status | Command | Notes |
| ------------------- | ---- | ------ | ----------- | -------------------------- | ----- |
| `GetLinkCounts` | GET | read | implemented | `bwt links counts` | |
| `GetUrlLinks` | GET | read | implemented | `bwt links list` | |
| `GetConnectedPages` | GET | read | implemented | `bwt connected-pages list` | |
| `AddConnectedPage` | POST | write | implemented | `bwt connected-pages add` | |
## Keyword research [#keyword-research]
| Method | HTTP | Effect | Status | Command | Notes |
| -------------------- | ---- | ------ | ----------- | ---------------------- | ----- |
| `GetKeyword` | GET | read | implemented | `bwt keywords get` | |
| `GetKeywordStats` | GET | read | implemented | `bwt keywords stats` | |
| `GetRelatedKeywords` | GET | read | implemented | `bwt keywords related` | |
## Query parameters [#query-parameters]
| Method | HTTP | Effect | Status | Command | Notes |
| ----------------------------- | ---- | ------ | ----------- | ----------------------------------------- | ----- |
| `GetQueryParameters` | GET | read | implemented | `bwt params list` | |
| `AddQueryParameter` | POST | write | implemented | `bwt params add` | |
| `RemoveQueryParameter` | POST | write | implemented | `bwt params remove` | |
| `EnableDisableQueryParameter` | POST | write | implemented | `bwt params disable`, `bwt params enable` | |
## Blocked URLs [#blocked-urls]
| Method | HTTP | Effect | Status | Command | Notes |
| ------------------ | ---- | ------ | ----------- | ------------------------------------ | ----- |
| `GetBlockedUrls` | GET | read | implemented | `bwt block list`, `bwt block remove` | |
| `AddBlockedUrl` | POST | write | implemented | `bwt block add` | |
| `RemoveBlockedUrl` | POST | write | implemented | `bwt block remove` | |
## Page preview blocks [#page-preview-blocks]
| Method | HTTP | Effect | Status | Command | Notes |
| ---------------------------- | ---- | ------ | ----------- | --------------------------- | ----- |
| `GetActivePagePreviewBlocks` | GET | read | implemented | `bwt preview-blocks list` | |
| `AddPagePreviewBlock` | POST | write | implemented | `bwt preview-blocks add` | |
| `RemovePagePreviewBlock` | POST | write | implemented | `bwt preview-blocks remove` | |
## Deep links [#deep-links]
| Method | HTTP | Effect | Status | Command | Notes |
| --------------------- | ---- | ------ | ----------- | ---------------------------- | ----------------------------------------------------- |
| `GetDeepLinkBlocks` | GET | read | implemented | `bwt deeplink-blocks list` | verified 2026-10-04 |
| `AddDeepLinkBlock` | POST | write | implemented | `bwt deeplink-blocks add` | verified 2026-10-04; market must be lowercase (en-us) |
| `RemoveDeepLinkBlock` | POST | write | implemented | `bwt deeplink-blocks remove` | verified 2026-10-04; market must be lowercase (en-us) |
| `GetDeepLink` | GET | read | obsolete | Never implemented | marked Obsolete by Microsoft; use GetDeepLinkBlocks |
| `GetDeepLinkAlgoUrls` | GET | read | obsolete | Never implemented | marked Obsolete by Microsoft; no longer used |
| `UpdateDeepLink` | POST | write | obsolete | Never implemented | marked Obsolete by Microsoft; use deep-link blocking |
## Geo-targeting [#geo-targeting]
| Method | HTTP | Effect | Status | Command | Notes |
| ----------------------------- | ---- | ------ | ----------- | ---------------- | -------------------------------------------------------- |
| `GetCountryRegionSettings` | GET | read | implemented | `bwt geo list` | verified 2026-10-04 |
| `AddCountryRegionSettings` | POST | write | implemented | `bwt geo add` | verified 2026-10-04; country code must be lowercase (us) |
| `RemoveCountryRegionSettings` | POST | write | implemented | `bwt geo remove` | verified 2026-10-04; country code must be lowercase (us) |
## Site moves [#site-moves]
| Method | HTTP | Effect | Status | Command | Notes |
| ---------------- | ---- | ------ | ------------ | ----------------------------------- | ---------------------------------------------- |
| `GetSiteMoves` | GET | read | experimental | `bwt experimental site-move list` | returned HTTP 404 in a live check (2026-10-04) |
| `SubmitSiteMove` | POST | write | experimental | `bwt experimental site-move submit` | current behavior unverified |
## Fetch as Bingbot [#fetch-as-bingbot]
| Method | HTTP | Effect | Status | Command | Notes |
| ---------------------- | ---- | ------ | ----------- | ------------------- | ------------------------- |
| `FetchUrl` | POST | write | implemented | `bwt fetch request` | schedules a Bingbot fetch |
| `GetFetchedUrls` | GET | read | implemented | `bwt fetch list` | |
| `GetFetchedUrlDetails` | GET | read | implemented | `bwt fetch get` | |
## Beyond the Bing Webmaster API [#beyond-the-bing-webmaster-api]
| Feature | Handled by | Notes |
| ----------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| IndexNow protocol | `bwt indexnow key generate`, `bwt indexnow key check`, `bwt indexnow submit` | Needs no Bing credentials; the key is hosted on the site. Submissions reach every participating engine. |
| SOAP and POX (XML) protocols | Never implemented | Retired by Microsoft on 2026-08-31. The CLI uses the JSON endpoints only. |
| AI Performance and citation reports | Not available | Dashboard only (public preview February 2026, expanded June 2026); no public API method. |
| Recommendations and Top Insights | Not available | Dashboard only; no public API method. |
| Site Scan | Not available | Dashboard audit workflow; no public API method. |
| Backlink comparison | Not available | Dashboard only. `bwt links` covers the legacy GetLinkCounts and GetUrlLinks methods. |
| IndexNow Insights | Not available | Dashboard only; no public API method. |
| Bing Search APIs (Web Search API) | Out of scope | A separate product, retired 2025-08-11; it does not affect the Webmaster API. |
# Command reference (https://projects.piyushgambhir.com/bing-webmaster-cli/docs/reference/commands)
Generated from the `bwt` command tree on `main`. The [command guides](https://projects.piyushgambhir.com/bing-webmaster-cli/docs/commands) explain when to use each group.
Global flags apply to every command.
```text
--access-token string Bearer token override (prefer BWT_ACCESS_TOKEN)
--api-key string API key override (prefer BWT_API_KEY or auth login)
--dry-run For writes: print the requests and send nothing
--no-input Never prompt or open a browser
-o, --output string Output format: table, json, yaml, csv (default "table")
--profile string Named profile (or BWT_PROFILE)
-q, --quiet Suppress informational stderr output
--raw Print Bing's wire JSON without date conversion
--read-only Block remote writes, local credential changes, and self-update
-s, --site string Site URL exactly as in sites list, or a bare host (or BWT_SITE)
--timeout duration HTTP request timeout (default 30s)
-v, --verbose Log method, redacted URL, and status to stderr
-y, --yes Confirm destructive commands and updates without a prompt
```
## bwt [#bwt]
Bing Webmaster Tools from your terminal
Read and manage Bing Webmaster Tools data: search performance, crawl health, URL and sitemap
submission, IndexNow, keyword research, and site settings.
Data goes to stdout and diagnostics to stderr. --read-only blocks every state change.
```text
bwt
```
## bwt api [#bwt-api]
Call any Bing Webmaster API method directly
Sends an authenticated request to [https://ssl.bing.com/webmaster/api.svc/json/METHOD](https://ssl.bing.com/webmaster/api.svc/json/METHOD) with the same
redaction, fault handling, and date conversion as other commands. Known methods use their documented
HTTP verb and effect; unknown methods need --http and count as writes, so --read-only refuses them.
Writes ask for confirmation (or --yes): a raw call can remove sites, sitemaps, or users.
\--param values are sent as strings; use --data for typed JSON values (POST only).
```text
bwt api METHOD [flags]
```
```bash
bwt api GetUserSites
bwt api GetQueryStats --param siteUrl=https://example.com/
bwt api SubmitUrlBatch --data '{"siteUrl":"https://example.com/","urlList":["https://example.com/a"]}'
```
```text
--data string JSON object of parameters (POST)
--http string HTTP method for methods not in the registry: GET or POST
--param stringArray Parameter as name=value (repeatable)
```
## bwt api methods [#bwt-api-methods]
List every Bing method: HTTP verb, read/write effect, status, and the command that calls it
```text
bwt api methods
```
```bash
bwt api methods -o json
```
## bwt auth [#bwt-auth]
Log in, inspect credentials, and manage profiles
```text
bwt auth
```
## bwt auth list [#bwt-auth-list]
List saved profiles without secrets
```text
bwt auth list
```
## bwt auth login [#bwt-auth-login]
Save your Bing Webmaster API key and pick a default site
Logs in with your Bing Webmaster Tools API key, which covers every site in your account. In a terminal it
opens Bing Webmaster Tools, shows where the key is (Settings > API Access > API Key), and reads it from a
hidden prompt; piped input is read from stdin. The key is checked with one GetUserSites call before anything
is saved, then stored in the OS keychain, and a default site is chosen. Without an OS keychain, login stops
unless you pass --insecure-storage (a 0600 plaintext file). Bing's OAuth registration rejects loopback
redirect URIs, so there is no browser OAuth login.
changes local configuration.
```text
bwt auth login [flags]
```
```bash
bwt auth login
bwt auth login --profile client-b
printf '%s' "$KEY" | bwt auth login --no-input --profile ci
BWT_API_KEY=... bwt sites list # use a key without saving it
```
```text
--insecure-storage Store the key in a 0600 plaintext file instead of the OS keychain
--no-verify Save without checking the key with Bing (for a key that is not active yet)
```
## bwt auth logout [#bwt-auth-logout]
Delete the profile's saved API key (keeps its site and IndexNow keys)
Deletes the saved API key from the keychain or secrets file. Logging out removes the key from this machine only. To invalidate it, regenerate it in Bing Webmaster Tools > Settings > API Access.
changes local configuration.
```text
bwt auth logout
```
## bwt auth status [#bwt-auth-status]
Show the active credential source without revealing secrets
Local only unless --verify, which makes one GetUserSites call.
```text
bwt auth status [flags]
```
```text
--verify Check access with one GetUserSites call
```
## bwt auth use [#bwt-auth-use]
Set the default profile
changes local configuration.
```text
bwt auth use NAME
```
## bwt block [#bwt-block]
Block URLs from Bing results (Block URLs tool)
```text
bwt block
```
## bwt block add [#bwt-block-add]
Block a page or directory from Bing results
\--request cache-only removes the cached copy; full-removal removes the URL from Bing results until it expires.
There is no default for --request, and full removal asks for confirmation.
changes Bing state (blocked by --read-only); Bing methods: AddBlockedUrl.
```text
bwt block add URL [flags]
```
```text
--request string cache-only or full-removal (required)
--type string page or directory (default "page")
```
## bwt block list [#bwt-block-list]
List blocked URLs
Bing methods: GetBlockedUrls.
```text
bwt block list
```
## bwt block remove [#bwt-block-remove]
Unblock a URL
Looks up the block with GetBlockedUrls and removes exactly that entry.
changes Bing state (blocked by --read-only); Bing methods: GetBlockedUrls, RemoveBlockedUrl.
```text
bwt block remove URL
```
## bwt completion [#bwt-completion]
Generate shell completion script
```text
bwt completion [bash|zsh|fish|powershell]
```
## bwt config [#bwt-config]
Inspect configuration and select profiles
```text
bwt config
```
## bwt config list-profiles [#bwt-config-list-profiles]
List saved profiles without secrets
```text
bwt config list-profiles
```
## bwt config show [#bwt-config-show]
Show the active credential source without revealing secrets
Local only unless --verify, which makes one GetUserSites call.
```text
bwt config show [flags]
```
```text
--verify Check access with one GetUserSites call
```
## bwt config use-profile [#bwt-config-use-profile]
Set the default profile
changes local configuration.
```text
bwt config use-profile NAME
```
## bwt connected-pages [#bwt-connected-pages]
Pages (such as social profiles) connected to your site
```text
bwt connected-pages
```
## bwt connected-pages add [#bwt-connected-pages-add]
Connect a page to your site
changes Bing state (blocked by --read-only); Bing methods: AddConnectedPage.
```text
bwt connected-pages add URL
```
## bwt connected-pages list [#bwt-connected-pages-list]
List connected pages
Bing methods: GetConnectedPages.
```text
bwt connected-pages list
```
## bwt crawl [#bwt-crawl]
Crawl statistics, crawl issues, and crawl settings
```text
bwt crawl
```
## bwt crawl issues [#bwt-crawl-issues]
URLs with crawl issues, with the issue bitmask decoded
Lists URLs Bing had trouble crawling. issue\_labels is decoded locally from the Issues bitmask.
Fixed issues can stay listed for several days, and an empty list does not prove the site has none.
Bing methods: GetCrawlIssues.
```text
bwt crawl issues
```
## bwt crawl set-settings [#bwt-crawl-set-settings]
Change hourly crawl rate or crawl boost
Reads the current crawl settings, applies your changes, and saves the full object.
\--rate takes 24 comma-separated hourly values (Bing does not document the valid range or timezone).
changes Bing state (blocked by --read-only); Bing methods: GetCrawlSettings, SaveCrawlSettings.
```text
bwt crawl set-settings [flags]
```
```bash
bwt crawl set-settings --rate 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,5,4,3,3,4
bwt crawl set-settings --boost on
```
```text
--boost string Crawl boost: on or off
--rate string 24 comma-separated hourly crawl-rate values
```
## bwt crawl settings [#bwt-crawl-settings]
Show crawl rate and crawl boost settings
CrawlRate has 24 hourly values. Bing does not document their valid range or the timezone of the hours.
Bing methods: GetCrawlSettings.
```text
bwt crawl settings
```
## bwt crawl stats [#bwt-crawl-stats]
Daily crawl statistics
Daily counts of crawled pages, pages in the index, crawl errors, and HTTP status classes. Bing updates this daily.
Bing methods: GetCrawlStats.
```text
bwt crawl stats
```
## bwt deeplink-blocks [#bwt-deeplink-blocks]
Block deep links (sitelinks) shown under a result
```text
bwt deeplink-blocks
```
## bwt deeplink-blocks add [#bwt-deeplink-blocks-add]
Block a deep link
changes Bing state (blocked by --read-only); Bing methods: AddDeepLinkBlock.
```text
bwt deeplink-blocks add [flags]
```
```text
--deep-link-url string Deep link URL to block (required)
--market string Market, such as en-US (required)
--search-url string Result URL the deep link appears under (required)
```
## bwt deeplink-blocks list [#bwt-deeplink-blocks-list]
List deep-link blocks
Bing methods: GetDeepLinkBlocks.
```text
bwt deeplink-blocks list
```
## bwt deeplink-blocks remove [#bwt-deeplink-blocks-remove]
Remove a deep-link block
changes Bing state (blocked by --read-only); Bing methods: RemoveDeepLinkBlock.
```text
bwt deeplink-blocks remove [flags]
```
```text
--deep-link-url string Deep link URL to block (required)
--market string Market, such as en-US (required)
--search-url string Result URL the deep link appears under (required)
```
## bwt doctor [#bwt-doctor]
Check configuration, credentials, site selection, and PATH
Runs local checks without network access; --verify adds one GetUserSites call. Exits nonzero when a check fails.
```text
bwt doctor [flags]
```
```text
--verify Also check access with one GetUserSites call
```
## bwt experimental [#bwt-experimental]
Documented Bing methods that did not work in live checks
These methods are still in Bing's documentation, but a live check on 2026-10-04 failed (GetSiteMoves
returned HTTP 404). Each run prints a notice. Confirm results in the Bing Webmaster Tools dashboard.
```text
bwt experimental
```
## bwt experimental site-move [#bwt-experimental-site-move]
Site moves (Bing's site move tool)
```text
bwt experimental site-move
```
## bwt experimental site-move list [#bwt-experimental-site-move-list]
List submitted site moves
experimental; Bing methods: GetSiteMoves.
```text
bwt experimental site-move list
```
## bwt experimental site-move submit [#bwt-experimental-site-move-submit]
Tell Bing that content moved to a new location
changes Bing state (blocked by --read-only); experimental; Bing methods: SubmitSiteMove.
```text
bwt experimental site-move submit [flags]
```
```text
--from string Source URL (required)
--scope string domain, host, or directory (required)
--to string Target URL (required)
--type string local or global (required)
```
## bwt fetch [#bwt-fetch]
Fetch as Bingbot: request a fetch and read the results
```text
bwt fetch
```
## bwt fetch get [#bwt-fetch-get]
Show a fetched URL's status, headers, and document
The table shows the status. --save writes what Bingbot fetched (its crawl record and the response) to a
file; -o json includes it too.
Bing methods: GetFetchedUrlDetails.
```text
bwt fetch get URL [flags]
```
```bash
bwt fetch get https://www.example.com/ --save fetched.txt
```
```text
--save string Write the fetched document to this file
```
## bwt fetch list [#bwt-fetch-list]
List fetch requests and whether they completed
Bing methods: GetFetchedUrls.
```text
bwt fetch list
```
## bwt fetch request [#bwt-fetch-request]
Ask Bingbot to fetch a URL
Schedules a Bingbot fetch. Check the result later with bwt fetch list and bwt fetch get.
changes Bing state (blocked by --read-only); Bing methods: FetchUrl.
```text
bwt fetch request URL
```
## bwt geo [#bwt-geo]
Country or region targeting for pages, directories, or hosts
```text
bwt geo
```
## bwt geo add [#bwt-geo-add]
Target a URL to a country or region
changes Bing state (blocked by --read-only); Bing methods: AddCountryRegionSettings.
```text
bwt geo add [flags]
```
```text
--country string Two-letter ISO country code (required)
--type string page, directory, domain, or subdomain (default "page")
--url string Page, directory, or host URL (required)
```
## bwt geo list [#bwt-geo-list]
List targeting settings
Bing methods: GetCountryRegionSettings.
```text
bwt geo list
```
## bwt geo remove [#bwt-geo-remove]
Remove a targeting setting
changes Bing state (blocked by --read-only); Bing methods: RemoveCountryRegionSettings.
```text
bwt geo remove [flags]
```
```text
--country string Two-letter ISO country code (required)
--type string page, directory, domain, or subdomain (default "page")
--url string Page, directory, or host URL (required)
```
## bwt indexnow [#bwt-indexnow]
Notify Bing and other engines of new or changed URLs with IndexNow
IndexNow needs no Bing login: you host a key file on your site and submit URLs with the key.
A submission to one participating endpoint is shared with the other IndexNow engines.
Keys are public by design (served at [https://host/KEY.txt](https://host/KEY.txt)), so the CLI keeps them in the config file.
```text
bwt indexnow
```
## bwt indexnow key [#bwt-indexnow-key]
Create and check the IndexNow key for a host
```text
bwt indexnow key
```
## bwt indexnow key check [#bwt-indexnow-key-check]
Fetch the key file and confirm it matches
```text
bwt indexnow key check [flags]
```
```text
--host string Host to check (default: the selected site's host)
--key string Key to check (default: the saved key)
--key-location string Key file URL (default: https://host/KEY.txt)
```
## bwt indexnow key generate [#bwt-indexnow-key-generate]
Create a new key and save it for a host
Creates a 32-character hexadecimal key and shows where to host it. The key is saved in the selected
profile unless --no-save. Upload a text file named KEY.txt containing only the key to the site root,
then run bwt indexnow key check.
changes local configuration.
```text
bwt indexnow key generate [flags]
```
```text
--host string Host the key is for (default: the selected site's host)
--no-save Print the key without saving it
```
## bwt indexnow submit [#bwt-indexnow-submit]
Submit new, changed, or deleted URLs with IndexNow
Groups URLs by host and sends up to 10,000 per request, one request at a time. Stops at the first
rejected batch. 200 and 202 mean received (202: key validation pending); neither means indexed.
changes Bing state (blocked by --read-only).
```text
bwt indexnow submit [URL...] [flags]
```
```bash
bwt indexnow submit https://example.com/new-post
bwt indexnow submit --sitemap https://example.com/sitemap.xml --changed-since 2026-10-01
bwt indexnow submit --file changed.txt --endpoint bing
```
```text
--changed-since string With --sitemap: only URLs whose lastmod is on or after YYYY-MM-DD
--endpoint string indexnow (api.indexnow.org), bing, or an https URL (default "indexnow")
--file string Read URLs from a file, one per line (- for stdin)
--key string IndexNow key for every host (default: saved key per host, or BWT_INDEXNOW_KEY)
--key-location string Key file URL (single host only)
--sitemap string Read URLs from a sitemap or sitemap index
```
## bwt keywords [#bwt-keywords]
Bing keyword research (market data, not your site's performance)
Keyword research reports Bing search demand for a query in a market. It is not filtered to your site.
Bing does not document the accepted date syntax for these methods; the CLI sends YYYY-MM-DD.
```text
bwt keywords
```
## bwt keywords get [#bwt-keywords-get]
Impressions for one query over a date range
Bing methods: GetKeyword.
```text
bwt keywords get QUERY [flags]
```
```text
--country string Market country code, such as us or gb (default "us")
--end string End date YYYY-MM-DD (default: today, UTC)
--language string Market language, such as en-US (default "en-US")
--start string Start date YYYY-MM-DD (default: 30 days before --end)
```
## bwt keywords related [#bwt-keywords-related]
Related queries with impressions over a date range
Bing methods: GetRelatedKeywords.
```text
bwt keywords related QUERY [flags]
```
```text
--country string Market country code, such as us or gb (default "us")
--end string End date YYYY-MM-DD (default: today, UTC)
--language string Market language, such as en-US (default "en-US")
--start string Start date YYYY-MM-DD (default: 30 days before --end)
```
## bwt keywords stats [#bwt-keywords-stats]
Weekly impression history for one query
Bing methods: GetKeywordStats.
```text
bwt keywords stats QUERY [flags]
```
```text
--country string Market country code, such as us or gb (default "us")
--language string Market language, such as en-US (default "en-US")
```
## bwt links [#bwt-links]
Inbound links Bing has found
Bing's legacy link methods can return empty results for sites that have links; empty is not proof of none.
```text
bwt links
```
## bwt links counts [#bwt-links-counts]
Pages on your site with inbound link counts
Pages start at 0. --all follows Bing's TotalPages (bounded by --max-pages).
Bing methods: GetLinkCounts.
```text
bwt links counts [flags]
```
```text
--all Fetch pages until the end (bounded by --max-pages)
--max-pages int Upper bound on pages fetched with --all (default 100)
--page int Page to fetch, starting at 0
```
## bwt links list [#bwt-links-list]
Inbound links to one page, with anchor text
Pages start at 0. --all follows Bing's TotalPages (bounded by --max-pages).
Bing methods: GetUrlLinks.
```text
bwt links list URL [flags]
```
```text
--all Fetch pages until the end (bounded by --max-pages)
--max-pages int Upper bound on pages fetched with --all (default 100)
--page int Page to fetch, starting at 0
```
## bwt login [#bwt-login]
Alias for auth login
Logs in with your Bing Webmaster Tools API key, which covers every site in your account. In a terminal it
opens Bing Webmaster Tools, shows where the key is (Settings > API Access > API Key), and reads it from a
hidden prompt; piped input is read from stdin. The key is checked with one GetUserSites call before anything
is saved, then stored in the OS keychain, and a default site is chosen. Without an OS keychain, login stops
unless you pass --insecure-storage (a 0600 plaintext file). Bing's OAuth registration rejects loopback
redirect URIs, so there is no browser OAuth login.
changes local configuration.
```text
bwt login [flags]
```
```bash
bwt auth login
bwt auth login --profile client-b
printf '%s' "$KEY" | bwt auth login --no-input --profile ci
BWT_API_KEY=... bwt sites list # use a key without saving it
```
```text
--insecure-storage Store the key in a 0600 plaintext file instead of the OS keychain
--no-verify Save without checking the key with Bing (for a key that is not active yet)
```
## bwt params [#bwt-params]
URL query parameters Bing should ignore when normalizing URLs
```text
bwt params
```
## bwt params add [#bwt-params-add]
Add a parameter to ignore
changes Bing state (blocked by --read-only); Bing methods: AddQueryParameter.
```text
bwt params add NAME
```
## bwt params disable [#bwt-params-disable]
Disable a parameter
changes Bing state (blocked by --read-only); Bing methods: EnableDisableQueryParameter.
```text
bwt params disable NAME
```
## bwt params enable [#bwt-params-enable]
Enable a parameter
changes Bing state (blocked by --read-only); Bing methods: EnableDisableQueryParameter.
```text
bwt params enable NAME
```
## bwt params list [#bwt-params-list]
List normalization parameters
Bing methods: GetQueryParameters.
```text
bwt params list
```
## bwt params remove [#bwt-params-remove]
Remove a parameter
changes Bing state (blocked by --read-only); Bing methods: RemoveQueryParameter.
```text
bwt params remove NAME
```
## bwt preview-blocks [#bwt-preview-blocks]
Block or allow page previews (snippets) in Bing results
```text
bwt preview-blocks
```
## bwt preview-blocks add [#bwt-preview-blocks-add]
Block the preview for a URL
\--reason is Bing's BlockReason number. Microsoft does not publish the enum values; existing blocks in
preview-blocks list show the values in use.
changes Bing state (blocked by --read-only); Bing methods: AddPagePreviewBlock.
```text
bwt preview-blocks add URL [flags]
```
```text
--reason string BlockReason number (required)
```
## bwt preview-blocks list [#bwt-preview-blocks-list]
List active page preview blocks
Bing methods: GetActivePagePreviewBlocks.
```text
bwt preview-blocks list
```
## bwt preview-blocks remove [#bwt-preview-blocks-remove]
Remove a preview block
changes Bing state (blocked by --read-only); Bing methods: RemovePagePreviewBlock.
```text
bwt preview-blocks remove URL
```
## bwt quota [#bwt-quota]
Remaining URL and content submission quota
Shows Bing's daily and monthly counters exactly as returned. Quotas are site-specific; nothing is assumed.
Bing methods: GetUrlSubmissionQuota, GetContentSubmissionQuota.
```text
bwt quota
```
## bwt sitemaps [#bwt-sitemaps]
Sitemaps and feeds submitted to Bing
```text
bwt sitemaps
```
## bwt sitemaps get [#bwt-sitemaps-get]
Show the sitemaps inside a sitemap index
Bing methods: GetFeedDetails.
```text
bwt sitemaps get URL
```
## bwt sitemaps list [#bwt-sitemaps-list]
List submitted sitemaps and feeds
Bing methods: GetFeeds.
```text
bwt sitemaps list
```
## bwt sitemaps remove [#bwt-sitemaps-remove]
Remove a sitemap or feed
changes Bing state (blocked by --read-only); Bing methods: RemoveFeed.
```text
bwt sitemaps remove URL
```
## bwt sitemaps submit [#bwt-sitemaps-submit]
Submit a sitemap or feed URL
Supports XML sitemaps, sitemap indexes, RSS 2.0, Atom 0.3/1.0, and text feeds.
changes Bing state (blocked by --read-only); Bing methods: SubmitFeed.
```text
bwt sitemaps submit URL
```
## bwt sites [#bwt-sites]
List, add, verify, remove, and select sites
```text
bwt sites
```
## bwt sites add [#bwt-sites-add]
Add a site to your account (it still needs verification)
Adds the site to your account. Adding is harmless if the site is already there.
Verify ownership afterwards with an XML file, meta tag, or DNS record, then run bwt sites verify.
changes Bing state (blocked by --read-only); Bing methods: AddSite.
```text
bwt sites add SITE
```
## bwt sites list [#bwt-sites-list]
List the sites in your Bing Webmaster account
Lists your sites. Use these URLs exactly (scheme and trailing slash) in other commands.
JSON also includes AuthenticationCode and DnsVerificationCode for verification.
Bing methods: GetUserSites.
```text
bwt sites list
```
## bwt sites remove [#bwt-sites-remove]
Remove a site from your account
changes Bing state (blocked by --read-only); Bing methods: RemoveSite.
```text
bwt sites remove SITE
```
## bwt sites use [#bwt-sites-use]
Set the profile's default site (local)
Saves SITE as the default for the selected profile. A bare host is matched against your sites.
changes local configuration.
```text
bwt sites use SITE
```
## bwt sites verify [#bwt-sites-verify]
Ask Bing to verify ownership of a site
Asks Bing to check the site's verification file, meta tag, or DNS record. Prints verified: false when Bing could not confirm ownership.
changes Bing state (blocked by --read-only); Bing methods: VerifySite.
```text
bwt sites verify SITE
```
## bwt stats [#bwt-stats]
Search performance: Bing's top queries, pages, and traffic
Bing returns its own top rows with no date range, row limit, or paging on the server.
\--since, --until, --limit, and --sort filter and sort locally; JSON records filtered\_locally.
Positions are shown as Bing returns them (their scale is undocumented).
```text
bwt stats
```
## bwt stats detail [#bwt-stats-detail]
Position detail for one query and page
Bing returns its own top rows with no date range, row limit, or paging on the server.
\--since, --until, --limit, and --sort filter and sort locally; JSON records filtered\_locally.
Positions are shown as Bing returns them (their scale is undocumented).
Bing updates this data weekly.
Bing methods: GetQueryPageDetailStats.
```text
bwt stats detail QUERY URL [flags]
```
```text
--asc Sort ascending
--limit int Keep at most N rows after sorting (local)
--since string Keep rows on or after this day (YYYY-MM-DD, local filter)
--sort string Sort locally by date, clicks, impressions, ctr, query, position, avg-click-position, or avg-impression-position (descending)
--until string Keep rows on or before this day (YYYY-MM-DD, local filter)
```
## bwt stats page-queries [#bwt-stats-page-queries]
Queries that lead to a page
Bing returns its own top rows with no date range, row limit, or paging on the server.
\--since, --until, --limit, and --sort filter and sort locally; JSON records filtered\_locally.
Positions are shown as Bing returns them (their scale is undocumented).
Bing updates this data weekly.
Bing methods: GetPageQueryStats.
```text
bwt stats page-queries URL [flags]
```
```text
--asc Sort ascending
--limit int Keep at most N rows after sorting (local)
--since string Keep rows on or after this day (YYYY-MM-DD, local filter)
--sort string Sort locally by date, clicks, impressions, ctr, query, position, avg-click-position, or avg-impression-position (descending)
--until string Keep rows on or before this day (YYYY-MM-DD, local filter)
```
## bwt stats pages [#bwt-stats-pages]
Top pages
Bing returns its own top rows with no date range, row limit, or paging on the server.
\--since, --until, --limit, and --sort filter and sort locally; JSON records filtered\_locally.
Positions are shown as Bing returns them (their scale is undocumented).
Bing updates this data weekly.
Bing methods: GetPageStats.
```text
bwt stats pages [flags]
```
```text
--asc Sort ascending
--limit int Keep at most N rows after sorting (local)
--since string Keep rows on or after this day (YYYY-MM-DD, local filter)
--sort string Sort locally by date, clicks, impressions, ctr, query, position, avg-click-position, or avg-impression-position (descending)
--until string Keep rows on or before this day (YYYY-MM-DD, local filter)
```
## bwt stats queries [#bwt-stats-queries]
Top queries
Bing returns its own top rows with no date range, row limit, or paging on the server.
\--since, --until, --limit, and --sort filter and sort locally; JSON records filtered\_locally.
Positions are shown as Bing returns them (their scale is undocumented).
Bing updates this data weekly.
Bing methods: GetQueryStats.
```text
bwt stats queries [flags]
```
```text
--asc Sort ascending
--limit int Keep at most N rows after sorting (local)
--since string Keep rows on or after this day (YYYY-MM-DD, local filter)
--sort string Sort locally by date, clicks, impressions, ctr, query, position, avg-click-position, or avg-impression-position (descending)
--until string Keep rows on or before this day (YYYY-MM-DD, local filter)
```
## bwt stats query-pages [#bwt-stats-query-pages]
Pages that rank for a query
Bing returns its own top rows with no date range, row limit, or paging on the server.
\--since, --until, --limit, and --sort filter and sort locally; JSON records filtered\_locally.
Positions are shown as Bing returns them (their scale is undocumented).
Bing updates this data weekly.
Bing methods: GetQueryPageStats.
```text
bwt stats query-pages QUERY [flags]
```
```text
--asc Sort ascending
--limit int Keep at most N rows after sorting (local)
--since string Keep rows on or after this day (YYYY-MM-DD, local filter)
--sort string Sort locally by date, clicks, impressions, ctr, query, position, avg-click-position, or avg-impression-position (descending)
--until string Keep rows on or before this day (YYYY-MM-DD, local filter)
```
## bwt stats query-traffic [#bwt-stats-query-traffic]
Traffic history for one query (top queries only)
Bing returns its own top rows with no date range, row limit, or paging on the server.
\--since, --until, --limit, and --sort filter and sort locally; JSON records filtered\_locally.
Positions are shown as Bing returns them (their scale is undocumented).
Bing updates this data daily.
Bing methods: GetQueryTrafficStats.
```text
bwt stats query-traffic QUERY [flags]
```
```text
--asc Sort ascending
--limit int Keep at most N rows after sorting (local)
--since string Keep rows on or after this day (YYYY-MM-DD, local filter)
--sort string Sort locally by date, clicks, impressions, ctr, query, position, avg-click-position, or avg-impression-position (descending)
--until string Keep rows on or before this day (YYYY-MM-DD, local filter)
```
## bwt stats summary [#bwt-stats-summary]
Totals over the latest N days of site traffic, computed locally
Sums GetRankAndTrafficStats over the N calendar days ending at the latest day Bing returned.
CTR is recomputed from the sums. --compare previous adds the preceding N days; percentage changes
are null when the earlier value is zero, and the CTR change is in percentage points.
Bing methods: GetRankAndTrafficStats.
```text
bwt stats summary [flags]
```
```text
--compare string Compare with: previous
--days int Window length in days (default 28)
```
## bwt stats traffic [#bwt-stats-traffic]
Site clicks and impressions by day
Bing returns its own top rows with no date range, row limit, or paging on the server.
\--since, --until, --limit, and --sort filter and sort locally; JSON records filtered\_locally.
Positions are shown as Bing returns them (their scale is undocumented).
Bing updates this data daily.
Bing methods: GetRankAndTrafficStats.
```text
bwt stats traffic [flags]
```
```text
--asc Sort ascending
--limit int Keep at most N rows after sorting (local)
--since string Keep rows on or after this day (YYYY-MM-DD, local filter)
--sort string Sort locally by date, clicks, impressions, ctr, query, position, avg-click-position, or avg-impression-position (descending)
--until string Keep rows on or before this day (YYYY-MM-DD, local filter)
```
## bwt status [#bwt-status]
Alias for auth status
Local only unless --verify, which makes one GetUserSites call.
```text
bwt status [flags]
```
```text
--verify Check access with one GetUserSites call
```
## bwt submit [#bwt-submit]
Submit URLs to Bing (prefer indexnow submit for new or changed URLs)
```text
bwt submit
```
## bwt submit content [#bwt-submit-content]
Push a page's full HTTP response to Bing (content submission)
Sends a complete HTTP response (status line, headers, blank line, body) for URL, base64-encoded, up to 10 MB.
Works with an API key. Submitted content may be indexed even if robots.txt disallows it (NOINDEX is
honored). Capture a response with: curl -s --http1.1 -i [https://example.com/page](https://example.com/page) -o page.http
changes Bing state (blocked by --read-only); Bing methods: SubmitContent.
```text
bwt submit content URL [flags]
```
```bash
curl -s --http1.1 -i https://www.example.com/ -o home.http
bwt submit content https://www.example.com/ --file home.http
```
```text
--dynamic-serving string none, pc, mobile, amp, tablet, or nonvisual (default "none")
--file string File with the full HTTP response (required)
--structured-data string File with structured data, normally JSON-LD
```
## bwt submit urls [#bwt-submit-urls]
Submit URLs with Bing's URL Submission API
Submits URLs for crawling. One URL uses SubmitUrl; more are sent in batches of up to 500 with
SubmitUrlBatch, one after another. On a failure the command reports the batches Bing accepted and
stops; it never resubmits automatically because repeated submissions spend quota.
Accepted means Bing received the URLs; it does not mean they are indexed.
changes Bing state (blocked by --read-only); Bing methods: SubmitUrl, SubmitUrlBatch, GetUrlSubmissionQuota.
```text
bwt submit urls [URL...] [flags]
```
```bash
bwt submit urls https://example.com/new-page
bwt submit urls --file urls.txt --check-quota
```
```text
--batch-size int URLs per batch (1-500) (default 500)
--check-quota Read the URL submission quota first
--file string Read URLs from a file, one per line (- for stdin)
```
## bwt update [#bwt-update]
Update bwt to the latest release (SHA-256 verified)
Downloads the latest GitHub release for this OS and architecture, verifies it against the release's
checksums.txt, and replaces the running bwt executable. Works on macOS, Linux, and Windows; on Windows
the old executable is renamed to bwt.exe.old and deleted on a later run.
Asks "Update now? \[Y/n]" when stdin is a terminal; --yes skips the question, and --no-input requires
\--yes. --check only reports the current and latest versions. A bwt in a Go bin directory ($GOBIN,
$GOPATH/bin, or \~/go/bin) is not replaced: rebuild it from your checkout instead. --read-only blocks
installing but allows --check.
Update notice: in an interactive terminal, bwt checks the github.com releases page (not the GitHub API,
so its rate limit never applies) for a new release at most once a day and, after a command's output,
prints a notice on stderr. The command that runs the day's check waits up to 1 second after its output
for the answer; other commands never wait. bwt update and update --check store their result in the same
cache. It never checks when stderr is not a terminal, when CI is set, with --quiet, or when
BWT\_NO\_UPDATE\_NOTIFIER or NO\_UPDATE\_NOTIFIER is set (to anything).
```text
bwt update [flags]
```
```bash
bwt update --check
bwt update
bwt update --yes --no-input
```
```text
--check Only report the current and latest versions (always checks the github.com releases page)
```
## bwt url [#bwt-url]
What Bing knows about a URL and the URLs under it
Bing's URL data has no explicit indexed verdict. IsPage and HttpStatus describe crawling, not indexing.
```text
bwt url
```
## bwt url children [#bwt-url-children]
URLs under a URL, with crawl details and filters
Lists URLs below URL. Pages start at 0; --all continues until Bing returns an empty page.
This is a read even though Bing implements it with POST.
Bing methods: GetChildrenUrlInfo.
```text
bwt url children URL [flags]
```
```text
--all Fetch pages until the end (bounded by --max-pages)
--crawl-date string Crawled within: any, last-week, last-two-weeks, last-three-weeks (default "any")
--discovered string Discovered within: any, last-week, last-month (default "any")
--doc-flags string Comma list: blocked-by-robots, malware
--http string Comma list: 2xx, 3xx, 301, 302, 4xx, 5xx, other
--max-pages int Upper bound on pages fetched with --all (default 100)
--page int Page to fetch, starting at 0
```
## bwt url children-traffic [#bwt-url-children-traffic]
Clicks and impressions for URLs under a URL
Bing methods: GetChildrenUrlTrafficInfo.
```text
bwt url children-traffic URL [flags]
```
```text
--all Fetch pages until the end (bounded by --max-pages)
--max-pages int Upper bound on pages fetched with --all (default 100)
--page int Page to fetch, starting at 0
```
## bwt url info [#bwt-url-info]
Crawl details for one URL
Shows last crawl, discovery date, HTTP status, size, anchors, and child count. A zero status or IsPage=false is not an indexing verdict.
Bing methods: GetUrlInfo.
```text
bwt url info URL
```
## bwt url traffic [#bwt-url-traffic]
Clicks and impressions for one URL (window undocumented)
Bing methods: GetUrlTrafficInfo.
```text
bwt url traffic URL
```
## bwt users [#bwt-users]
Users and roles delegated on a site
```text
bwt users
```
## bwt users add [#bwt-users-add]
Delegate access to a user
Grants EMAIL a role on the site (or on --delegated-url, a host under it).
\--auth-code defaults to the delegated site's AuthenticationCode from your site list.
changes Bing state (blocked by --read-only); Bing methods: AddSiteRoles, GetUserSites.
```text
bwt users add EMAIL [flags]
```
```text
--auth-code string Authentication code of the delegated site (default: looked up)
--delegated-url string Site or host to delegate (default: the selected site)
--role string Role: admin, read-only, or read-write (required)
```
## bwt users list [#bwt-users-list]
List users with access to the site
Bing methods: GetSiteRoles.
```text
bwt users list [flags]
```
```text
--all-subdomains Include users of all subdomains
```
## bwt users remove [#bwt-users-remove]
Remove a user's delegated access
Looks up the user's role with GetSiteRoles and removes exactly that role. Several matches are an error;
narrow them with --delegated-url.
changes Bing state (blocked by --read-only); Bing methods: GetSiteRoles, RemoveSiteRole.
```text
bwt users remove EMAIL [flags]
```
```text
--delegated-url string Only the role on this site or host
```
## bwt version [#bwt-version]
Print build information
Prints the version, commit, and build date. latest and update\_available come from the last
release check (see bwt update --help) and appear only when one is cached; version never uses the network.
```text
bwt version
```