API reference
Constructor: new Unbrowse(options). Every method returns a typed promise. Network errors, 429, and 5xx are auto-retried with exponential backoff + jitter (default 2 retries; override per call).
Constructor options
new Unbrowse({
apiKey?: string; // env UNBROWSE_API_KEY
baseURL?: string; // env UNBROWSE_BASE_URL, default https://beta-api.unbrowse.ai
timeout?: number; // ms, default 60_000
maxRetries?: number; // default 2
fetch?: typeof fetch; // inject for tracing or mocking
defaultHeaders?: Record<string, string>;
logLevel?: "off" | "error" | "warn" | "info" | "debug"; // env UNBROWSE_LOG
});Top-level methods
resolve(input)
Find captured endpoints that match an intent. Returns a ranked shortlist.
await unbrowse.resolve({
intent: "find tomorrow's calendar events",
contextUrl?: "https://calendar.google.com",
domain?: "calendar.google.com",
limit?: 5,
});
// → { status, available_operations: AvailableEndpoint[], next_step?, _request_id }execute(input)
Execute one of the shortlisted endpoints. Auto-sets an Idempotency-Key so a network-retry never double-charges.
await unbrowse.execute({
endpoint_id?: string;
url?: string;
method?: string;
params?: Record<string, unknown>;
body?: unknown;
raw?: boolean; // bypass extract
extract?: string; // JSONPath into the response
limit?: number;
idempotency_key?: string; // override the auto-key
transport?: "worker-proxy" | "direct";
proxy?: "direct" | "residential";
});
// → { success, status_code, data, raw, trace, _request_id }search(input)
Public discovery — search the marketplace by intent and optional domain.
await unbrowse.search({
intent: "github trending repos",
domain?: "github.com",
limit?: 10,
});
// → { hits: SearchHit[], _request_id }health()
await unbrowse.health();
// → { status: "ok" | "degraded", version?, uptime_s? }Skill management
// Publish a captured skill to the marketplace.
// Wraps POST /v1/skills.
await unbrowse.publish({
name: "github.com search",
intent_signature: "search github code",
domain: "github.com",
description: "search github via the public API",
endpoints: [/* EndpointDescriptor[] */],
markup_bps: 2500, // optional, [500, 8000] = 5-80% platform cut on x402 settle
});
// → { skill_id, version, publish_status }
// Annotate an endpoint with a tip, constraint, or gotcha.
// Wraps POST /v1/skills/:id/endpoints/:eid/annotate.
await unbrowse.annotate({
skillId: "abc123",
endpointId: "ep1",
text: "rate limit is 60/hr per token",
constraint: "per_page:format:1-100", // optional structured constraint
});
// → { ok: true, annotation_id }Payment provider
// Sync the agent's chosen x402 settlement rail.
// Wraps POST /v1/account/payment-provider. Allowed values:
// "pay_sh" pay-cli + TouchID + USDC (x402 MPP)
// "lobster_cash" @crossmint/lobster-cli + virtual card + Solana
// "external_solana" bring-your-own signer (via `unbrowse wallet`)
// "privy_embedded" Privy auto-created wallet (web sign-in)
// "privy_embedded_solana" bound automatically via /v1/auth/privy/start
// "skip" free tier (sponsor middleware covers $1/day/agent)
await unbrowse.paymentProvider("privy_embedded");
// → { agent_id, wallet_provider, wallet_address }Per-skill markup_bps (Flex x402)
SkillManifest accepts an optional markup_bps field that overrides the global PLATFORM_BPS constant when computing x402 splits. Clamped to [500, 8000] (5-80%) at compute time. The owner-share (1500 bps when DNS-claimed) and the indexer pool auto-rebalance from the remainder. Set per skill at publish time to charge different rates per route.
Account resource
await unbrowse.account.me(); // current user
await unbrowse.account.credits(); // balance, used, granted (USD)
await unbrowse.account.sponsorStatus(); // daily sponsor remainingKeys resource
await unbrowse.keys.list(); // { keys: ApiKey[] }
await unbrowse.keys.create({ name: "prod" });
// → { keyId, key (plaintext, ONCE), name, created_at, message }
await unbrowse.keys.revoke(keyId);
await unbrowse.keys.rotate(keyId); // revokes old, returns new keyKey-management endpoints (/v1/account/keys) authenticate via the magic-link cookie session, not bearer API key. Sign in at the dashboard once to mint the first key; the bearer key covers every other call.
Proxy resource
See Worker proxy + IProyal for the full story.
await unbrowse.proxy.fetch({
url: "https://www.reddit.com/r/singularity/top.json",
method: "GET",
proxy: "residential", // optional, tunnels via IProyal
});
// → { status, headers, body, proxy_used, duration_ms }
await unbrowse.proxy.capabilities();
// → { modes, residential_configured, max_body_bytes, default_timeout_ms }Per-request overrides
await unbrowse.resolve({ intent }, {
timeout: 10_000,
maxRetries: 0,
signal: ac.signal,
headers: { "x-custom": "..." },
idempotencyKey: "user-supplied",
});