Worker proxy + IProyal

The SDK runs in places where direct outbound fetches don't work: browsers (CORS), edge runtimes (no outbound socket), or against APIs that block datacenter IPs. POST /v1/proxy on the worker fetches the URL for you and returns the response.

Basic worker fetch

const r = await unbrowse.proxy.fetch({
  url: "https://www.reddit.com/r/singularity/top.json",
  method: "GET",
});
// r.status, r.headers, r.body, r.proxy_used: "direct", r.duration_ms

Defaults: proxy: "direct" (worker fetches from its own Cloudflare egress), 30 s timeout, 8 MB body cap, follows redirects, strips internal CF headers from the upstream call.

Residential routing

For geo-fenced or anti-bot targets, ask the worker to tunnel the outbound fetch through a residential IP via IProyal:

const r = await unbrowse.proxy.fetch({
  url: "https://geo-fenced.example.com/api/data",
  proxy: "residential",
});
// r.proxy_used: "residential"

The worker connects to geo.iproyal.com:12321 using cloudflare:sockets, sends an HTTP CONNECT with proxy auth, upgrades to TLS for HTTPS targets, and forwards your request. Returns the raw response (status, headers, body) just like direct mode.

Capability check

Residential mode requires IPROYAL_USER + IPROYAL_PASS as wrangler secrets on the worker. Before requesting it, check what's configured:

const caps = await unbrowse.proxy.capabilities();
// {
//   modes: ["direct", "residential"],
//   residential_configured: true,
//   max_body_bytes: 8388608,
//   default_timeout_ms: 30000,
// }

If residential_configured: false, a proxy: "residential" call will return HTTP 502 with a clear error naming the missing env. Fall back to direct in that case.

Choosing direct vs worker-proxy on execute()

// Default — worker fetches the captured URL on your behalf.
await unbrowse.execute({ endpoint_id, params });

// Same call, with residential egress for the upstream fetch.
await unbrowse.execute({ endpoint_id, params, proxy: "residential" });

// Lower latency, exposes your IP, bypasses sponsor metering.
await unbrowse.execute({ endpoint_id, params, transport: "direct" });

Blocked targets

The worker rejects requests to private RFC1918 ranges, loopback, and link-local addresses with HTTP 400 (error: "blocked_private_host"). HTTP and HTTPS are the only allowed schemes.

Response shape

{
  status: number;                       // upstream HTTP status
  headers: Record<string, string>;      // upstream headers (CF/internal stripped)
  body: string;                         // upstream body (utf-8 text up to 8MB)
  proxy_used: "direct" | "residential";
  duration_ms: number;
  egress_ip?: string;                   // when residential
  _request_id?: string;
}
live total calls endpoints domainspolls every 30s