Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The Microsoft Web IQ Customer Management API creates, reads, updates, and deletes named search scopes for a Web IQ billing account. For an end-to-end portal or API walkthrough, see Filter results with Scopes.
Base URL: https://api.microsoft.ai
Collection route: /v1/customer/billing-accounts/{billingAccountId}/scopes
Authentication and headers
Workloads need an active Microsoft Entra identity and CustomerApiAccess on the target billing account. Request an app-only token with https://api.microsoft.ai/.default. Use authorized-resource discovery to select billingAccountId; do not substitute a customer ID, Azure subscription ID, Web IQ AppID, or Entra application (client) ID.
| Header | Use |
|---|---|
Authorization: Bearer <access-token> |
Required for every management request. Search API keys are not supported for these calls. |
Content-Type: application/json |
Required when sending a JSON body. |
Accept: application/json |
Requests JSON responses. |
If-Match: "<current-etag>" |
Required for replacement, incremental edits, and deletion. Copy the complete strong ETag, including quotes, from a scope read or write. |
Operations
Paths below are relative to the collection route.
| Method | Path | Success | Description |
|---|---|---|---|
POST |
Collection route | 201, definition, ETag, Location |
Create a named scope. |
GET |
Collection route | 200, metadata page |
List scope names, counts, and timestamps, without selector arrays. |
GET |
/{name} |
200, definition, ETag |
Read both complete selector arrays and metadata. |
GET |
/{name}/summary |
200, metadata, ETag |
Read counts and timestamps without selector arrays. |
GET |
/{name}/includeSites or /{name}/excludeSites |
200, site page, ETag |
Page one selector list. |
PUT |
/{name} |
200, definition, ETag |
Replace both arrays; requires If-Match. |
POST |
/{name}/includeSites:add or /{name}/excludeSites:add |
204, ETag |
Add selectors to one list; requires If-Match. |
POST |
/{name}/includeSites:remove or /{name}/excludeSites:remove |
204, ETag |
Remove selectors from one list; requires If-Match. |
DELETE |
/{name} |
204 |
Permanently delete a scope; requires If-Match. |
Scope names identify resources in the account's assigned scope collection. Web IQ AppIDs in the account use that collection. Accounts assigned to the same collection share names, definitions, and changes.
Create a scope
POST /v1/customer/billing-accounts/<billingAccountId>/scopes HTTP/1.1
Host: api.microsoft.ai
Authorization: Bearer <access-token>
Content-Type: application/json
{
"name": "ProductDocs",
"includeSites": ["example.com", "docs.example.org/products"],
"excludeSites": ["ads.example.com"]
}
| Request field | Required | Type | Description |
|---|---|---|---|
name |
Yes | string | 1-128 characters after trimming; ASCII letters, digits, ., _, and -. Case-insensitively unique within the collection. |
includeSites |
Yes | array of strings | Included selectors. Use [] for intentionally empty inclusion, which permits all non-excluded sources. |
excludeSites |
Yes | array of strings | Excluded selectors. Exclusion takes precedence over inclusion regardless of specificity. |
Both arrays must be present. Omitting either property or sending null is not equivalent to [].
HTTP 201 Created returns the normalized definition and the response headers below. Creation is not an update or rename: a duplicate case-insensitive name returns 409 Conflict.
| Response header | Description |
|---|---|
ETag |
Strong, quoted authoring-concurrency token. Preserve the exact value for future If-Match requests. Not a serving-readiness or serving-version token. |
Location |
Root-relative URI of the created scope on the requested billing-account route. |
Response fields
A complete definition contains all the fields below. A metadata response omits includeSites and excludeSites.
| Field | Type | Description |
|---|---|---|
billingAccountId |
string (UUID) | The billing account used in the request. |
name |
string | Scope name, with display casing preserved. Lookup is case-insensitive. |
includeSites |
array of strings | Complete, normalized included selectors. |
excludeSites |
array of strings | Complete, normalized excluded selectors. |
includedSiteCount |
integer | Number of normalized unique included selectors. |
excludedSiteCount |
integer | Number of normalized unique excluded selectors. |
createdAt |
string (date-time) | Creation time in UTC. |
updatedAt |
string (date-time) | Last update time in UTC. |
List and read scopes
Use GET /v1/customer/billing-accounts/{billingAccountId}/scopes/{name} for the complete definition and its current ETag. Append /summary to read only metadata and counts.
Use GET /v1/customer/billing-accounts/{billingAccountId}/scopes?pageSize=50 to list scopes. The response contains metadata objects in items and an optional nextContinuationToken.
| Query parameter | Applies to | Values |
|---|---|---|
pageSize |
Scope list | 1-100; default 50. |
pageSize |
Included or excluded selector list | 1-1,000; default 100. |
continuationToken |
Either list type | Opaque token from that list's preceding page. Pass it unchanged and let the HTTP client URL-encode it. |
Continue until nextContinuationToken is absent or null. Scope metadata is listed in normalized-name order, not as a guaranteed snapshot during concurrent edits.
To page selectors, call GET .../scopes/{name}/includeSites or GET .../scopes/{name}/excludeSites. Each response contains sites, totalCount, nextContinuationToken, and an ETag header. Selector pages follow canonical selector order. Keep tokens with the same scope and list. If an edit makes a selector token stale, the request returns 412; discard the partial enumeration and restart from the first page.
Update or delete a scope
PUT replaces both complete arrays and does not rename the scope:
PUT /v1/customer/billing-accounts/<billingAccountId>/scopes/ProductDocs HTTP/1.1
Host: api.microsoft.ai
Authorization: Bearer <access-token>
Content-Type: application/json
If-Match: "<current-etag>"
{
"includeSites": ["example.com"],
"excludeSites": ["ads.example.com", "example.com/archive"]
}
To change one list without replacing the other, use the corresponding :add or :remove route with a sites array:
POST /v1/customer/billing-accounts/<billingAccountId>/scopes/ProductDocs/excludeSites:add HTTP/1.1
Host: api.microsoft.ai
Authorization: Bearer <access-token>
Content-Type: application/json
If-Match: "<current-etag>"
{
"sites": ["example.com/archive"]
}
Supply 1-10,000 submitted entries. The resulting list must still satisfy its unique-selector and definition-size limits. Adding an already-present canonical selector or removing an absent selector is a no-op. An entirely no-op request preserves the ETag. Successful incremental mutations return 204 with the current ETag and no JSON body.
Use DELETE .../scopes/{name} with If-Match to permanently delete the scope. Remove dependencies from callers first. There is no soft-delete or restore endpoint, and deletion propagates asynchronously. For a shared collection, deletion affects all assigned accounts.
Concurrency and uncertain outcomes
Replace, incremental edits, and delete require the current strong ETag. Do not remove its quotes, construct it from timestamps, or use weak, wildcard, or multiple tags.
On 412 Precondition Failed, read the latest definition, reconcile the intended change with other writers' changes, and retry with the latest ETag. Do not blindly overwrite the latest definition. 428 Precondition Required means If-Match was missing.
If a write times out or the connection drops, read the resource before retrying. A create may have succeeded before a timeout, making the retry return 409; an edit may have changed the ETag, making the retry return 412. When checking a delete, distinguish genuine absence from an authorization failure.
Limits and selector validation
| Constraint | Limit or behavior |
|---|---|
| Name | 1-128 characters after trimming; ASCII letters, digits, ., _, and -. |
| Each selector list | Up to 10,000 normalized unique selectors. Send at most 10,000 distinct entries per array. |
| Each selector | Up to 2,048 characters before trimming and after normalization. |
| Path depth | No separate subdirectory or segment-count limit, subject to selector length and combined definition size. |
| Combined definition | Default 3,670,016 bytes (3.5 MiB), estimated from the serialized serving definition including both lists and metadata. Not the raw HTTP request-body size. |
| Incremental add/remove body | 1-10,000 submitted entries in sites. |
The collection also has a scope-count limit. 409 can indicate exhausted capacity as well as a duplicate name; check the error and existing inventory. Contact Web IQ Support for the effective capacity of your account.
Supported selectors include DNS domains (example.com and all descendant subdomains), IPv4 hosts (192.0.2.10), path prefixes (example.com/products/guides on path-segment boundaries for that host), and exact HTTPS URLs (https://example.com/products/guide). Adding a scheme changes a path prefix into an exact URL.
Wildcards, explicit ports, query strings, fragments, user information, IPv6, dot segments, and encoded path separators are rejected. Raw non-ASCII path characters must be UTF-8 percent-encoded.
Normalization trims surrounding whitespace, lowercases hosts, preserves path casing, sorts canonical selectors, and deduplicates each list independently. An entry can appear in both lists; exclusion always wins. Empty inclusion permits all non-excluded sources. Both arrays empty mean the scope itself imposes no site restriction.
Status codes and errors
Management errors use a different contract from the v3 search error response.
| Status | Meaning | Action |
|---|---|---|
400 |
Invalid name, body, selectors, pagination, definition size, or If-Match format. |
Correct the input; do not retry unchanged. |
401 |
Missing or invalid authentication. | Check token expiry and the https://api.microsoft.ai/.default token-request scope. |
403 |
Principal or account authorization denied. | Verify the workload's active identity and CustomerApiAccess on the account. |
404 |
Requested scope or billing account not found. | Check the account and name. Authorization can deny a request before existence is disclosed. |
409 |
Duplicate name or exhausted collection capacity. | Read the existing inventory and error details; do not blindly retry creation. |
412 |
Stale ETag or stale selector-page token. | Re-read and reconcile the edit, or restart selector pagination. |
428 |
Required If-Match missing. |
Read the resource and send its current quoted strong ETag. |
500 |
Service or dependency failure. | Use bounded retries for reads; reconcile uncertain writes first. |
Scope validation, not-found, conflict, and concurrency errors use this JSON shape:
{
"code": "NotFound",
"message": "The requested scope was not found."
}
The stable code values include InvalidRequest, NotFound, Conflict, PreconditionFailed, and PreconditionRequired. A subCode can also be present. Branch on HTTP status and code, not on the diagnostic message, and accept unknown codes and fields. Malformed or invalid request bodies can instead return application/problem+json validation details. 401 and 403 have no body; dependency failures can use a different shape.
Search propagation
A successful management write or read does not prove that the latest definition is active in search. Propagation is asynchronous. Full global propagation usually takes about 10 minutes, but can take up to 30 minutes in some cases. There is currently no propagation SLA, and these timings are not guaranteed. There is no readiness endpoint or scope versioning yet. The authoring ETag and runtime scopeApplied: true do not identify the version currently served.
For readiness checks and a new-name replacement strategy, see Verify the scope before using it.