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.
All v3 APIs return standardized error responses to help you diagnose and resolve issues quickly. This section covers HTTP status codes, error response structure, and common troubleshooting scenarios.
Note
All string enum values are case-insensitive.
HTTP Status Codes
| Status Code | Applies To | Error Category | Description | Common Causes |
|---|---|---|---|---|
| 200 | All APIs | Success | The request succeeded. | - |
| 202 | Browse only | Accepted | Request accepted for processing (live crawl). | On-demand crawling in progress when liveCrawl is "fallback" |
| 400 | All APIs | Bad Request | Invalid request parameters. | Missing required fields, invalid parameter values, malformed JSON |
| 401 | All APIs | Unauthorized | Authentication failed or missing. | Invalid API key, missing x-apikey header |
| 403 | All APIs | Forbidden | Valid credentials but insufficient permissions. | API key lacks required permissions |
| 403 | Browse only | Forbidden | Content filtered or URL excluded. | URL blocked by policy or content filtered |
| 404 | Browse only | Not Found | Document not found. | Invalid or inaccessible URL |
| 410 | All APIs | Gone | HTTPS required. | Request made over HTTP instead of HTTPS |
| 415 | All APIs | Unsupported Media Type | Content type not supported. | Missing or incorrect content-type header |
| 429 | All APIs | Too Many Requests | Rate limit exceeded. For Browse with granular error codes, also returned when too many on-demand crawls are requested. | Too many requests in time window, or excessive live crawl requests |
| 430 | Browse only | Server Error | Too many on-demand crawls (legacy error codes). | Excessive live crawl requests |
| 500 | All APIs | Internal Server Error | Unexpected server error. | Temporary server issue |
| 520 | Browse only | Content Processing Failed | The page was retrieved but no usable content could be produced. | Document processing failed or timed out, or dynamic rendering timed out |
| 523 | Browse only | Crawl Canceled | The URL didn't produce any content because the crawl didn't succeed due to limited site crawl quota. | Limited crawl quota for the source host |
| 524 | Browse only | Crawl Timeout | The URL didn't produce any content because the crawl timed out. | The remote host timed out |
Statuses 520, 523, and 524 are part of granular Browse error codes, which are enabled by default.
Error Response Structure
All error responses follow this schema:
| Field | Type | Description |
|---|---|---|
errorCode |
string | A more detailed error category that helps identify the type of error. |
errorCategory |
string | High-level category: UserError (client-side / non-retryable) or SystemError (server-side / retryable). |
userMessage |
string | Human-readable error description. |
technicalDetails |
string (optional) | Additional technical information or parameter validation details for debugging. |
retryAfter |
string (optional) | Retry guidance. For AuthUserThrottled, AuthUserDailyUsageExceeded, and InternalServerError, a duration with an "s" suffix (for example, "60s"). For Browse granular errors, including TooManyOnDemandCrawls (429), an ISO 8601 UTC timestamp (for example, "2026-10-30T01:01:00Z") that is the earliest time to retry. Omitted when no retry guidance applies. |
requestId |
string (optional) | Unique identifier for the request. |
traceId |
string | Distributed trace ID for debugging and Microsoft support. |
Note
retryAfter uses two formats. AuthUserThrottled, AuthUserDailyUsageExceeded, and InternalServerError responses use a duration such as "60s". Browse 202 Accepted responses and Browse granular errors use an absolute ISO 8601 UTC timestamp such as "2026-10-30T01:01:00Z". The HTTP status alone doesn't determine the format: TooManyOnDemandCrawls returns 429 but uses a timestamp. Retry logic should handle both formats.
Note
202 Accepted responses (e.g., Browse live crawl polling) are not error responses and do not use the error schema above. They include a retryAfter timestamp to indicate when to retry the request.
Example Error Response:
{
"errorCode": "HandlerInvalidInput",
"errorCategory": "UserError",
"userMessage": "Invalid input provided. Please check your request parameters.",
"technicalDetails": "Parameter validation failed: maxResults=100 exceeds maximum=50",
"requestId": "req_abc123",
"traceId": "trace_xyz789"
}
Error Codes Reference
Request Validation Errors
| Error Code | HTTP Status | Category | Description |
|---|---|---|---|
RequestInvalidFormat |
400 | UserError |
Malformed JSON body or invalid request payload structure. |
RequestInvalidMethod |
400 | UserError |
Invalid method or tool name specified in request. |
HandlerInvalidInput |
400 | UserError |
Invalid input parameter values (e.g., empty query, maxResults out of range [1, 50], invalid enum values). For Browse passage requests, query is missing, blank, or longer than 1000 characters. |
RequestBlockedHeader |
400 | UserError |
Request contains a blocklisted debug/variant header (e.g., X-Augmentations, X-DebugOptions, X-XapHostOverride). Use documented URL parameters (?p1=, ?debugoptions=, ?atlahostname=) instead. |
RequestUnsupportedMediaType |
415 | UserError |
The content-type header is missing or not application/json. |
MethodNotAllowed |
405 | UserError |
HTTP method not permitted on the route (e.g., GET on a POST-only endpoint). |
Authentication & Authorization Errors
| Error Code | HTTP Status | Category | Description |
|---|---|---|---|
AuthNoToken |
401 | UserError |
Authentication required. No bearer token or API key provided. |
AuthTokenParse |
401 | UserError |
Invalid authentication token format or token parsing failed. |
AuthInvalidApiKey |
401 | UserError |
The provided API key is invalid or not recognized. |
AuthenticationFailed |
401 | UserError |
General authentication failure. |
AuthExpiredTrial |
401 | UserError |
The trial period has expired. Please upgrade your key. |
AuthMissingEntryId |
400 | UserError |
Missing application identity / entry ID in request context. |
AuthAppIdSelectionRequired |
400 | UserError |
Your identity maps to multiple applications. Specify the target application using the APPID query parameter. See Calling more than one AppID. |
AuthUnauthorizedEntryId |
401 | UserError |
Unauthorized entry ID. Application identity could not be resolved, or the APPID query parameter was sent with API key authentication. |
AuthUnauthorizedAppId |
403 | UserError |
The specified APPID is not associated with your identity. |
AuthUnauthorizedService |
403 | UserError |
Caller is authenticated but unauthorized to access the requested service/vertical. |
AuthBatchEndpointRequired |
403 | UserError |
Application is required to use the batch endpoint (X-FD-Batch: 1) for web search. |
AuthMcpWebForbidden |
403 | UserError |
Application is not permitted to use the MCP web tool. |
AuthContentFormatForbidden |
403 | UserError |
This application only has access to passages. Use contentFormat passage. See Passages and content formats. |
Rate Limiting Errors
| Error Code | HTTP Status | Category | Description |
|---|---|---|---|
AuthUserThrottled |
429 | UserError |
Request frequency exceeds your AppID's rate limit. Check retryAfter. |
AuthUserDailyUsageExceeded |
429 | UserError |
Daily request quota has been reached (resets at 00:00 UTC). Check retryAfter. |
Browse API Specific Errors
Granular error codes are enabled by default for Browse. They identify the specific reason a page couldn't be returned, such as content filtering, a missing document, or a crawl failure, and include retry guidance where applicable. No opt-in or Support request is required.
Granular and legacy codes use the standard error response structure. Browse errors that aren't listed here are reported as InternalServerError (HTTP 500).
Legacy Browse error codes
These codes were used before granular error codes became the default. They're listed for reference when handling older responses.
| Error Code | HTTP Status | Category | Description |
|---|---|---|---|
BrowseApiDocNotFound |
404 | UserError |
Document not found. No content available for the specified URL. |
BrowseApiIsFilteredOut |
403 | UserError |
The result was dropped by content policy, adult filtering, access restrictions, or domain restrictions. |
BrowseApiIsUrlExcluded |
403 | UserError |
The target URL is excluded by robots.txt or crawl exclusion policies. |
BrowseApiTooManyOnDemandCrawls |
430 | UserError |
Too many on-demand live crawl requests in progress. Reduce the live crawl rate. |
Granular Browse error codes
| Error Code | HTTP Status | Category | Typical retryAfter |
userMessage |
Recommended action |
|---|---|---|---|---|---|
InvalidUrl |
400 | UserError |
Omitted | The requested URL is invalid. | Correct the URL before retrying. |
NotSupported |
400 | UserError |
Omitted | The requested URL is not supported. | Use a URL that points to a supported web document. |
URLFilteredOutSpamAdult |
403 | UserError |
About 24 hours | The requested URL was filtered by spam or adult policy. | The page can't be returned. Don't retry before retryAfter. |
URLFilteredOutEncumbrance |
403 | UserError |
About 24 hours | The requested URL was filtered by content restrictions. | The publisher or site policy, such as robots directives or paywall rules, doesn't permit the content to be returned. Don't retry before retryAfter. |
URLFilteredOutSource403Forbidden |
403 | UserError |
About 24 hours | The source denied access to the requested URL. | The source site returned HTTP 403. Don't retry before retryAfter. |
BrowseApiIsFilteredOut |
403 | UserError |
About 24 hours, when supplied | The requested URL was filtered out. | Returned when a page is filtered for a reason that no more specific code covers. Don't retry before retryAfter. |
DocNotFound |
404 | UserError |
Omitted, unless supplied by the crawl service | The requested document was not found. | Verify the URL, or set liveCrawl to "fallback" to request a live crawl. |
TooManyOnDemandCrawls |
429 | UserError |
When supplied by the crawl service | Too many on-demand crawls were requested. | Reduce the live crawl rate. If retryAfter is present, wait until that time before retrying. |
FailedNoContent |
520 | SystemError |
About 5 minutes | Document processing or publishing failed to produce usable content. | Retry after retryAfter. |
DynamicRenderingTimeout |
520 | SystemError |
About 5 minutes | Dynamic page rendering timed out. | Retry after retryAfter, or retry without renderDynamicPages. |
ProcessingTimeout |
520 | SystemError |
About 5 minutes | Document processing timed out. | Retry after retryAfter. |
PolitenessCancellation |
523 | SystemError |
About 5 minutes | The crawl was canceled to respect the source host's crawl limits. | The URL didn't produce any content because the crawl didn't succeed due to limited site crawl quota. Retry after retryAfter. |
HostCrawlTimeout |
524 | SystemError |
About 5 minutes | The source host crawl timed out. | The URL didn't produce any content because the crawl timed out: the remote host didn't respond in time. Retry after retryAfter. |
When a retry delay applies, the response includes retryAfter as an ISO 8601 UTC timestamp in the format yyyy-MM-ddTHH:mm:ssZ, for example "retryAfter": "2026-10-30T01:01:00Z". Don't retry before that time. When retryAfter is omitted, no retry guidance applies.
Example granular error response:
{
"errorCode": "URLFilteredOutEncumbrance",
"errorCategory": "UserError",
"userMessage": "The requested URL was filtered by content restrictions.",
"retryAfter": "2026-10-31T01:00:00Z",
"traceId": "0123456789abcdef0123456789abcdef"
}
Browse passage errors
These errors apply to Browse requests with contentFormat: "passage", including requests from applications without full document access, for which "passage" is the default format. See Browse passage requests.
| Condition | Error Code | HTTP Status | userMessage |
|---|---|---|---|
query missing, empty, whitespace-only, or longer than 1000 characters |
HandlerInvalidInput |
400 | Invalid input provided. Please check your request parameters. |
An application without full document access requests text, html, or markdown |
AuthContentFormatForbidden |
403 | This application only has access to passages. Use contentFormat 'passage'. |
All other Browse outcomes for passage requests use the same status codes and error codes as text, html, and markdown requests. That includes filtered pages, documents not found, a pending live crawl (202 Accepted), and crawl failures.
Service & Infrastructure Errors
| Error Code | HTTP Status | Category | Retryable | Description |
|---|---|---|---|---|
InternalServerError |
500 | SystemError |
Yes (30s) | Internal server error. |
Common Error Scenarios
Authentication errors (401, 403)
Symptom: Authentication failed or forbidden access
Solutions:
- Verify your API key is correct and included in the
x-apikeyheader - Check that your API key has not expired
- Ensure you have the required permissions for the endpoint
- Contact your Microsoft representative if issues persist
Example:
# Correct authentication
curl -X POST "https://api.microsoft.ai/v3/search/web" \
-H "x-apikey: your-valid-key-here" \
-H "content-type: application/json" \
-d '{"query": "test"}'
Rate limiting (429)
Symptom: Rate limit exceeded or daily quota exhausted (AuthUserThrottled or AuthUserDailyUsageExceeded)
Requests above your AppID's rate limit return HTTP 429. Your rate limit is shown in the Web IQ portal.
Solutions:
- Implement exponential backoff retry logic
- Wait for the
retryAfterinterval in the error response (e.g.,"60s") before retrying - Reduce request frequency
- Note that daily quota caps (
AuthUserDailyUsageExceeded) reset daily at 00:00 UTC - To request a higher limit, contact Web IQ Support
Example Response:
{
"errorCode": "AuthUserThrottled",
"errorCategory": "UserError",
"userMessage": "Rate limit exceeded. Please reduce your request frequency.",
"retryAfter": "60s",
"requestId": "req_123",
"traceId": "trace_456"
}
Invalid parameters (400)
Symptom: Bad request due to invalid parameters
Common Issues:
- Required fields missing (e.g.,
queryparameter) - Parameter values out of range (e.g.,
maxResults> 50) - Invalid parameter types (e.g., string instead of integer)
- Unsupported parameter values (e.g., invalid
contentFormat)
Solutions:
- Validate all required parameters are present
- Check parameter values against documented constraints
- Ensure proper JSON formatting
Server and infrastructure errors (500)
Symptom: Unexpected internal server or upstream service error (InternalServerError)
Solutions:
- Check the
retryAfterfield (defaults to"30s") and retry the request after waiting - Implement retry with exponential backoff and jitter
- If the issue persists, contact Microsoft support with the
traceIdprovided in the response
Example Response:
{
"errorCode": "InternalServerError",
"errorCategory": "SystemError",
"userMessage": "The service is temporarily unavailable. Please try again later.",
"technicalDetails": "An internal service error occurred. Please contact support if the issue persists.",
"retryAfter": "30s",
"traceId": "trace_456"
}
Browse API accepted response (202)
Symptom: Accepted response (202) with url and retryAfter fields in the response body
Explanation: When liveCrawl is "fallback" and the URL isn't found in the index, the API can start a crawl asynchronously and return 202 Accepted. Live crawling is subject to publisher politeness restrictions and availability; "fallback" doesn't guarantee an actual crawl. The same behavior applies to every contentFormat, including passage.
Handling:
- Check for HTTP status 202.
- Read
retryAfterfrom the response body. It's an ISO 8601 UTC timestamp (for example,"2026-10-30T01:01:00Z") that is the earliest time to retry. - Wait until that time.
- Send the same request again. The
urlfield contains the URL to request; it defaults to the URL you requested. - Limit the number of polling attempts. A crawl that can't complete eventually returns an error, such as
HostCrawlTimeout(524) orFailedNoContent(520).
# Initial request
curl -X POST "https://api.microsoft.ai/v3/browse" \
-H "x-apikey: your-key" \
-H "content-type: application/json" \
-d '{"url": "https://example.com", "contentFormat": "passage", "query": "information about this domain", "liveCrawl": "fallback"}'
# Example response when the URL isn't indexed: 202 Accepted with "retryAfter": "2026-10-30T01:01:00Z"
# Wait until that time, then send the same request again
Best practices
- Always check status codes - Don't assume success
- Use traceId for support - Include traceId when contacting support
- Implement retry logic - Use exponential backoff for transient errors
- Handle 202 responses - For Browse API with live crawl, wait until the
retryAftertime and retry - Handle both
retryAfterformats - Use the duration forAuthUserThrottled,AuthUserDailyUsageExceeded, andInternalServerError, and the ISO 8601 timestamp for Browse 202 and granular errors, includingTooManyOnDemandCrawls(429) - Validate before sending - Check parameters locally to avoid 400 errors
- Use HTTPS only - HTTP requests will return 410 errors