Skip to main content
Kernel proxies enable you to route browser traffic through different types of proxy servers, providing enhanced privacy, flexibility, and bot detection avoidance. Proxies can be created once and reused across multiple browser sessions.

Proxy Types

Kernel supports five types of proxies:
  1. Datacenter - Traffic routed through commercial data centers
  2. ISP - Traffic routed through data centers, using residential IP addresses leased from from internet service providers
  3. Residential - Traffic routed through real residential IP addresses
  4. Mobile - Traffic routed through mobile carrier networks
  5. Custom - Your own proxy servers
Datacenter has the fastest speed, while residential and mobile are least detectable. ISP is a balance between the options, with less-flexible geotargeting. Kernel recommends using the first option in the list that works for your use case.
ISP proxies provide a static exit IP that persists across sessions — every browser session attached to the proxy exits through the same IP, and it only changes in rare ISP-initiated replacement events. This makes them suitable for IP allowlists or managed auth health checks that must egress from a single IP.Datacenter proxies use rotating exit IPs — a new exit IP is assigned per request, so different requests within the same browser session can exit through different IPs. For a stable IP across requests and sessions, use an ISP proxy or a custom (BYO) proxy pointed at infrastructure you control.Residential and mobile proxies use rotating exit IPs that may change per connection — see Residential Proxies and Mobile Proxies for details.

Create a proxy

Create a proxy configuration from the types above that can be reused across browser sessions:
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

const proxy = await kernel.proxies.create({ type: 'datacenter' });
console.log(proxy.id);
from kernel import Kernel

kernel = Kernel()

proxy = kernel.proxies.create(type="datacenter")
print(proxy.id)
package main

import (
	"context"
	"fmt"

	"github.com/kernel/kernel-go-sdk"
)

func main() {
	ctx := context.Background()
	client := kernel.NewClient()

	proxy, err := client.Proxies.New(ctx, kernel.ProxyNewParams{
		Type: kernel.ProxyNewParamsTypeDatacenter,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(proxy.ID)
}

List your proxies

View all proxy configurations in your organization:
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

const proxies = await kernel.proxies.list();
console.log(proxies);
from kernel import Kernel

kernel = Kernel()

proxies = kernel.proxies.list()
print(proxies)
package main

import (
	"context"
	"fmt"

	"github.com/kernel/kernel-go-sdk"
)

func main() {
	ctx := context.Background()
	client := kernel.NewClient()

	proxies, err := client.Proxies.List(ctx)
	if err != nil {
		panic(err)
	}
	fmt.Println(proxies)
}

Use with browsers

Once created, you can attach a proxy to any browser session using the proxy_id parameter:
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

const proxy = await kernel.proxies.create({
  type: 'residential',
  name: 'my-us-residential',
  config: {
    country: 'US',
  },
});

const browser = await kernel.browsers.create({
  proxy_id: proxy.id,
});
from kernel import Kernel

kernel = Kernel()

proxy = kernel.proxies.create(
    type="residential",
    name="my-us-residential",
    config={
        "country": "US",
    }
)

browser = kernel.browsers.create(proxy_id=proxy.id)
package main

import (
	"context"

	"github.com/kernel/kernel-go-sdk"
)

func main() {
	ctx := context.Background()
	client := kernel.NewClient()

	proxy, err := client.Proxies.New(ctx, kernel.ProxyNewParams{
		Type: kernel.ProxyNewParamsTypeResidential,
		Name: kernel.String("my-us-residential"),
		Config: kernel.ProxyNewParamsConfigUnion{
			OfProxyNewsConfigResidentialProxyConfig: &kernel.ProxyNewParamsConfigResidentialProxyConfig{
				Country: kernel.String("US"),
			},
		},
	})
	if err != nil {
		panic(err)
	}

	browser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{
		ProxyID: kernel.String(proxy.ID),
	})
	if err != nil {
		panic(err)
	}
	_ = browser
}

Check proxy health

Before attaching a proxy to a browser session, run a health check to verify credentials and connectivity. Pass an optional url to test reachability against a specific target instead of Kernel’s default test URLs.
await kernel.proxies.check(proxy.id, { url: 'https://example.com' });
kernel.proxies.check(id=proxy.id, url="https://example.com")
client.Proxies.Check(ctx, proxy.ID, kernel.ProxyCheckParams{
    URL: kernel.String("https://example.com"),
})
For ISP and datacenter proxies the exit IP is stable, so a successful check against a url reliably indicates that subsequent sessions will reach the same target from the same IP. For residential and mobile proxies the exit node changes between requests, so the check validates credentials and connectivity but not site-specific reachability. When url is provided, the result does not update the proxy’s stored health status.

Bypass hosts

Configure specific hostnames to bypass the proxy and connect directly. This is useful for accessing internal services, metadata endpoints, or reducing latency for trusted domains.
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

const proxy = await kernel.proxies.create({
  type: 'datacenter',
  name: 'proxy-with-bypass',
  config: {
    country: 'US',
  },
  bypass_hosts: [
    'localhost',
    'internal.company.local',
    'metadata.google.internal',
    '*.amazonaws.com',
  ],
});
from kernel import Kernel

kernel = Kernel()

proxy = kernel.proxies.create(
    type="datacenter",
    name="proxy-with-bypass",
    config={
        "country": "US",
    },
    bypass_hosts=[
        "localhost",
        "internal.company.local",
        "metadata.google.internal",
        "*.amazonaws.com",
    ]
)
package main

import (
	"context"

	"github.com/kernel/kernel-go-sdk"
)

func main() {
	ctx := context.Background()
	client := kernel.NewClient()

	proxy, err := client.Proxies.New(ctx, kernel.ProxyNewParams{
		Type: kernel.ProxyNewParamsTypeDatacenter,
		Name: kernel.String("proxy-with-bypass"),
		Config: kernel.ProxyNewParamsConfigUnion{
			OfProxyNewsConfigDatacenterProxyConfig: &kernel.ProxyNewParamsConfigDatacenterProxyConfig{
				Country: kernel.String("US"),
			},
		},
		BypassHosts: []string{
			"localhost",
			"internal.company.local",
			"metadata.google.internal",
			"*.amazonaws.com",
		},
	})
	if err != nil {
		panic(err)
	}
	_ = proxy
}

Bypass host rules

  • Exact hostnames: example.com, api.service.local
  • Wildcard subdomains: *.example.com matches api.example.com, cdn.example.com, etc.
  • Maximum 100 entries per proxy
  • Maximum 253 characters per hostname
  • Hostnames are case-insensitive and automatically normalized
  • Ports, paths, and URL schemes are not allowed
  • IP addresses are not supported—use hostnames only
Bypass hosts is available on Start-Up and Enterprise plans.

Update a browser’s proxy

You can hot-swap the proxy on a running browser session without restarting it. This updates the proxy configuration immediately — all subsequent network requests from the browser will use the new proxy.
The browser’s network is momentarily disconnected during a proxy hot swap. Any in-flight requests may fail.
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

// Create two proxy configurations
const proxyA = await kernel.proxies.create({
  type: 'isp',
  name: 'proxy-a',
  config: { country: 'US' },
});

const proxyB = await kernel.proxies.create({
  type: 'residential',
  name: 'proxy-b',
  config: { country: 'DE' },
});

// Launch a browser with the first proxy
const browser = await kernel.browsers.create({
  proxy_id: proxyA.id,
});

// Hot-swap to a different proxy
await kernel.browsers.update(browser.session_id, {
  proxy_id: proxyB.id,
});

// Remove the proxy entirely (route directly to the internet)
await kernel.browsers.update(browser.session_id, {
  proxy_id: '',
});
from kernel import Kernel

kernel = Kernel()

# Create two proxy configurations
proxy_a = kernel.proxies.create(
    type="isp",
    name="proxy-a",
    config={"country": "US"},
)

proxy_b = kernel.proxies.create(
    type="residential",
    name="proxy-b",
    config={"country": "DE"},
)

# Launch a browser with the first proxy
browser = kernel.browsers.create(
    proxy_id=proxy_a.id,
)

# Hot-swap to a different proxy
kernel.browsers.update(
    browser.session_id,
    proxy_id=proxy_b.id,
)

# Remove the proxy entirely (route directly to the internet)
kernel.browsers.update(
    browser.session_id,
    proxy_id="",
)
package main

import (
	"context"

	"github.com/kernel/kernel-go-sdk"
)

func main() {
	ctx := context.Background()
	client := kernel.NewClient()

	// Create two proxy configurations
	proxyA, err := client.Proxies.New(ctx, kernel.ProxyNewParams{
		Type: kernel.ProxyNewParamsTypeIsp,
		Name: kernel.String("proxy-a"),
		Config: kernel.ProxyNewParamsConfigUnion{
			OfProxyNewsConfigIspProxyConfig: &kernel.ProxyNewParamsConfigIspProxyConfig{
				Country: kernel.String("US"),
			},
		},
	})
	if err != nil {
		panic(err)
	}

	proxyB, err := client.Proxies.New(ctx, kernel.ProxyNewParams{
		Type: kernel.ProxyNewParamsTypeResidential,
		Name: kernel.String("proxy-b"),
		Config: kernel.ProxyNewParamsConfigUnion{
			OfProxyNewsConfigResidentialProxyConfig: &kernel.ProxyNewParamsConfigResidentialProxyConfig{
				Country: kernel.String("DE"),
			},
		},
	})
	if err != nil {
		panic(err)
	}

	// Launch a browser with the first proxy
	browser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{
		ProxyID: kernel.String(proxyA.ID),
	})
	if err != nil {
		panic(err)
	}

	// Hot-swap to a different proxy
	if _, err := client.Browsers.Update(ctx, browser.SessionID, kernel.BrowserUpdateParams{
		ProxyID: kernel.String(proxyB.ID),
	}); err != nil {
		panic(err)
	}

	// Remove the proxy entirely (route directly to the internet)
	if _, err := client.Browsers.Update(ctx, browser.SessionID, kernel.BrowserUpdateParams{
		ProxyID: kernel.String(""),
	}); err != nil {
		panic(err)
	}
}
The update is synchronous — when the call returns, the proxy swap is fully applied and all new browser traffic routes through the updated proxy. The swap typically completes in 2–3 seconds.
If you swap the proxy on a browser acquired from a pool, the browser will be reset back to the pool’s default proxy configuration when it is released. Releasing the browser will be delayed by the swap duration (~2-3 seconds) while the proxy is restored to the pool default.

Bring your own proxy

Attach a custom proxy_id to any browser — stealth or non-stealth — and Kernel’s anti-detection config still applies. For full anti-detection without the managed proxy or CAPTCHA solver, launch a non-stealth browser with your own proxy_id:
const browser = await kernel.browsers.create({
  stealth: false,
  proxy_id: myProxy.id,
});
browser = kernel.browsers.create(
    stealth=False,
    proxy_id=my_proxy.id,
)
browser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{
	Stealth: kernel.Bool(false),
	ProxyID: kernel.String(myProxy.ID),
})
if err != nil {
	panic(err)
}
_ = browser

Disable default proxy on stealth browsers

Stealth browsers are automatically assigned a proxy. To disable this on a running stealth browser and route traffic directly, set disable_default_proxy to true:
await kernel.browsers.update(browser.session_id, {
  disable_default_proxy: true,
});
kernel.browsers.update(
    browser.session_id,
    disable_default_proxy=True,
)
if _, err := client.Browsers.Update(ctx, browser.SessionID, kernel.BrowserUpdateParams{
	DisableDefaultProxy: kernel.Bool(true),
}); err != nil {
	panic(err)
}
disable_default_proxy can only be used with stealth browsers and cannot be combined with proxy_id.

Delete a proxy

When no longer needed, delete the proxy configuration:
import Kernel from '@onkernel/sdk';

const kernel = new Kernel();

await kernel.proxies.delete('id');
from kernel import Kernel

kernel = Kernel()
kernel.proxies.delete("id")
package main

import (
	"context"

	"github.com/kernel/kernel-go-sdk"
)

func main() {
	ctx := context.Background()
	client := kernel.NewClient()

	if err := client.Proxies.Delete(ctx, "id"); err != nil {
		panic(err)
	}
}
Deleting a proxy immediately reconfigures associated browsers to route directly to the internet.