Errors
Every SDK method throws on non-2xx. Errors are typed; instanceof works in browser, Node, and edge runtimes. Every error carries the request_id from the x-request-id response header so support can find the corresponding server trace instantly.
Hierarchy
UnbrowseError
├─ UnbrowseAPIError // any 4xx/5xx with body
│ ├─ UnbrowseBadRequestError // 400
│ ├─ UnbrowseAuthenticationError // 401
│ ├─ UnbrowsePaymentRequiredError // 402 (x402 / sponsor exhausted)
│ ├─ UnbrowsePermissionError // 403
│ ├─ UnbrowseNotFoundError // 404
│ ├─ UnbrowseRateLimitError // 429 (carries retry_after_ms)
│ └─ UnbrowseServerError // 5xx
└─ UnbrowseConnectionError // network
└─ UnbrowseTimeoutErrorCommon shape
interface UnbrowseAPIError extends UnbrowseError {
status: number;
body: unknown; // server-returned JSON or text
request_id: string | undefined;
url: string;
method: string;
}Branch by class
import {
Unbrowse,
UnbrowseRateLimitError,
UnbrowsePaymentRequiredError,
UnbrowseAuthenticationError,
} from "@unbrowse/client";
try {
await unbrowse.resolve({ intent });
} catch (e) {
if (e instanceof UnbrowseRateLimitError) {
console.log("rate limited, retry after", e.retry_after_ms, "ms");
} else if (e instanceof UnbrowsePaymentRequiredError) {
// sponsor cap exhausted; e.body is the x402 requirements object
console.log("top up wallet", e.body);
} else if (e instanceof UnbrowseAuthenticationError) {
console.log("rotate your key at /docs#keys");
} else {
throw e;
}
}Auto-retry
The SDK retries 429, 5xx, and network errors automatically with exponential backoff + jitter. The default budget is 2 retries; override with maxRetries on the constructor or per request. Retry-After response headers are honoured for 429.
Including request_id in support requests
Every successful response also carries _request_id as a field, so you can capture it on success-path debug too. Paste it into any support thread and the worker logs surface in one query.