Skip to content

Search API

Errors, limits, and billing

Handle API failures, request limits, retries, and completed-request billing.

Error responses

API failures use a stable JSON error body. Branch on the HTTP status and machine-readable reason, not the human-readable message. Every error body carries request_id, the same reference as the X-Request-ID response header. Include it when contacting support.

  • 400 — inspect validation when present, correct every listed request field, then retry.
  • 401 — provide a valid, active API key.
  • 402 — review billing and spend limits before retrying.
  • 403 — use a key with Search API permission.
  • 429 — wait for Retry-After, then retry with backoff.
  • Other 502 or 503 responses — retry temporary service failures with capped backoff and jitter.

Validation errors

A 400 response may include validation, the same bounded report returned by MCP at structuredContent.error.validation:

json
{
  "code": "invalid_request",
  "reason": "malformed_request",
  "message": "invalid request: request body violates the public contract",
  "recovery": null,
  "validation": {
    "contract": "SearchPostRequest",
    "issues": [
      {
        "code": "required",
        "path": "/query",
        "suggestion": "Add the required `query` field."
      }
    ],
    "truncated": false
  },
  "request_id": "6f1c2a9e-3b7d-4c55-9a0e-2f8d41b7c3a1"
}

contract names the published request schema. Each issue has a stable code, an RFC 6901 path, and a suggestion. When allowed_values is present, use one of those exact JSON scalar values. A root error uses an empty path.

Correct every listed issue before retrying. If truncated is true, validate the corrected request again because the report omitted additional issues. Do not retry an unchanged rejected request. Stop if the same output fails again, and use a small fixed repair ceiling for each request. Validation errors are not transient, so backoff does not repair them.

Result and request limits

limit accepts 1 through 50 results. The API has no pagination. Changing the limit can change ranking, so do not combine separate calls as pages of one result set.

Rate limits are enforced by the active account and key policy. The API returns 429 and Retry-After when a request should wait; this documentation does not publish a fixed numeric rate that could differ from the configured policy.

Each successful search, and each 429 from an account or key limit, reports the limit that binds the request in three headers. The limits are token buckets that refill continuously, so they describe the bucket with the fewest requests left:

  • X-RateLimit-Limit — the number of requests the bucket holds when it is full.
  • X-RateLimit-Remaining — the number of requests it admits now.
  • X-RateLimit-Reset — the whole seconds until it is full again.

A rate-limited response carries reason rate_limit_exceeded and a recovery whose kind is retry; retry_after_ms holds the delay when one is known. Direct HTTP failures carry Retry-After as the RFC 9110 retry header in whole seconds. Responses with 429 are emitted with Cache-Control: no-store, preserving the RFC 6585 caching requirement.

Billing

Balanced costs $4 per 1,000 completed requests. A failed search execution is not charged. Account spend limits can reject a request with 402 before execution.

The documentation console sends real API requests. Normal billing, spend limits, and rate limits apply.

Recovery checklist

  1. Record the HTTP status and the request_id, which equals X-Request-ID.
  2. Read the stable error reason.
  3. Correct non-retryable failures before sending another request.
  4. Honor Retry-After and use jitter for retryable failures.

Commands

No matching commands

Confirm it's you