From 4dff833cd3c1ba5452a1c018d08540dcb11fd176 Mon Sep 17 00:00:00 2001
From: tnsardesai <18272584+tnsardesai@users.noreply.github.com>
Date: Fri, 18 Sep 2026 08:13:48 +0000
Subject: [PATCH 1/7] Document browser location controls
---
browsers/location.mdx | 131 +++++++++++++++++++++++++++++++++++++
introduction/configure.mdx | 1 +
2 files changed, 132 insertions(+)
create mode 100644 browsers/location.mdx
diff --git a/browsers/location.mdx b/browsers/location.mdx
new file mode 100644
index 00000000..3e588f70
--- /dev/null
+++ b/browsers/location.mdx
@@ -0,0 +1,131 @@
+---
+title: "Browser Location"
+description: "Align a browser session's timezone and locale with its proxy geography or set explicit overrides"
+---
+
+KERNEL selects one timezone and formatting locale for each browser session. By default, it resolves each field from the browser's effective proxy geography and falls back to the browser's region while resolution is pending or unavailable.
+
+The setting applies across browser contexts, pages, frames, workers, `Intl`, `navigator.language`, `navigator.languages`, and future `Accept-Language` headers. Updating it doesn't restart Chromium or reload pages.
+
+
+Location controls timezone and language behavior. It doesn't set geolocation coordinates, grant geolocation permission, change the system clock, translate browser UI, or guarantee a bot-detection outcome.
+
+
+## Set location when creating a browser
+
+Set either field independently. Omit a field to let KERNEL select it automatically.
+
+
+```typescript TypeScript
+import Kernel from '@onkernel/sdk';
+
+const kernel = new Kernel();
+const browser = await kernel.browsers.create({
+ proxy: { name: 'berlin-checkout' },
+ location: {
+ timezone: 'Europe/Berlin',
+ locale: 'de-DE',
+ },
+});
+
+console.log(browser.location);
+```
+
+```python Python
+from kernel import Kernel
+
+kernel = Kernel()
+browser = kernel.browsers.create(
+ proxy={"name": "berlin-checkout"},
+ location={
+ "timezone": "Europe/Berlin",
+ "locale": "de-DE",
+ },
+)
+
+print(browser.location)
+```
+
+
+`timezone` accepts supported IANA identifiers such as `America/Los_Angeles`. `locale` accepts canonical BCP 47 tags such as `en-US` or `de-DE`. KERNEL validates the complete request before changing the session.
+
+## Update a running browser
+
+Use `browsers.update()` to set an override without restarting Chromium:
+
+
+```typescript TypeScript
+const browser = await kernel.browsers.update('01j8m3w6q2d7av9n5k4f1p8c', {
+ location: {
+ timezone: 'America/Los_Angeles',
+ locale: 'en-US',
+ },
+});
+```
+
+```python Python
+browser = kernel.browsers.update(
+ "01j8m3w6q2d7av9n5k4f1p8c",
+ location={
+ "timezone": "America/Los_Angeles",
+ "locale": "en-US",
+ },
+)
+```
+
+
+PATCH semantics are field-specific:
+
+- omit `location` or one of its fields to leave that field unchanged
+- set a string to create or replace a session override
+- set a field to `null` in TypeScript or `None` in Python to clear that override and resume automatic selection
+
+
+```typescript TypeScript
+const browser = await kernel.browsers.update('01j8m3w6q2d7av9n5k4f1p8c', {
+ location: {
+ timezone: null,
+ },
+});
+```
+
+```python Python
+browser = kernel.browsers.update(
+ "01j8m3w6q2d7av9n5k4f1p8c",
+ location={"timezone": None},
+)
+```
+
+
+Clearing one field doesn't clear the other. Explicit overrides also survive proxy changes for the rest of that session.
+
+## Read effective location
+
+Browser responses include the effective values, per-field provenance, and convergence state:
+
+```json
+{
+ "location": {
+ "timezone": "Europe/Berlin",
+ "locale": "de-DE",
+ "timezone_source": "proxy_metadata",
+ "locale_source": "proxy_metadata",
+ "pending": false
+ }
+}
+```
+
+`timezone_source` and `locale_source` can be `override`, `proxy_metadata`, `geoip`, `exit_ip`, or `metro`. KERNEL resolves the fields independently, so their sources can differ.
+
+When `pending` is `true`, the API has accepted the desired policy but the running browser hasn't finished converging. Browser creation and proxy updates don't wait for external geography discovery. KERNEL keeps the current values during a delayed or failed lookup and applies a valid late result in the background.
+
+## Runtime behavior
+
+- New pages, frames, workers, and network contexts start with the latest applied defaults.
+- Existing pages and workers receive the update without a reload.
+- Existing `Intl` formatter objects and application-level caches can retain values captured before the update. Create a new formatter when you need the latest default.
+- Future requests use the updated language preference. Requests already in flight aren't rewritten.
+- Customer CDP emulation remains separate from the session default and can temporarily override what a particular target reports.
+- Location overrides last only for the browser session. Profiles don't save them.
+
+For rotating residential and mobile proxies, KERNEL resolves location when the proxy is attached or explicitly changed. It doesn't chase silent exit-IP rotation, and one discovery request doesn't represent destination-specific routes for every website.
diff --git a/introduction/configure.mdx b/introduction/configure.mdx
index c0b41925..3b999fc1 100644
--- a/introduction/configure.mdx
+++ b/introduction/configure.mdx
@@ -91,6 +91,7 @@ browser = kernel.browsers.create(
Often agents don't require these, but they're there when you do:
- **[Regions](/browsers/regions):** run browsers in `us-east`, `eu-west`, or `ap-southeast`, closer to your code and your users.
+- **[Location](/browsers/location):** align the browser's timezone and locale with its proxy geography, or set explicit overrides without restarting Chromium.
- **[Extensions](/browsers/extensions):** load unpacked Chrome extensions into a browser.
- **[Chrome policies](/browsers/chrome-policies):** apply Chrome enterprise policies, such as startup pages and bookmarks.
- **[Private networking](/browsers/private-networking):** reach services behind a VPN or tunnel from inside the browser session.
From f12daff55862308997611a4716a2cf351651d223 Mon Sep 17 00:00:00 2001
From: tnsardesai <18272584+tnsardesai@users.noreply.github.com>
Date: Fri, 9 Oct 2026 10:43:50 +0000
Subject: [PATCH 2/7] Describe browser location validation and normalization
---
browsers/location.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/browsers/location.mdx b/browsers/location.mdx
index 3e588f70..5608d0e3 100644
--- a/browsers/location.mdx
+++ b/browsers/location.mdx
@@ -47,7 +47,7 @@ print(browser.location)
```
-`timezone` accepts supported IANA identifiers such as `America/Los_Angeles`. `locale` accepts canonical BCP 47 tags such as `en-US` or `de-DE`. KERNEL validates the complete request before changing the session.
+`timezone` accepts IANA identifiers such as `America/Los_Angeles`. `locale` accepts BCP 47 tags such as `en-US` or `de-DE` that the browser formats dates and numbers for with that exact region. KERNEL normalizes spelling and deprecated codes, so `en-us` becomes `en-US` and `iw-IL` becomes `he-IL`. KERNEL validates the complete request before changing the session and returns a `400` with code `invalid_browser_location` for an unsupported value such as `en-QQ`.
## Update a running browser
From 032fb4024c464d40491abd70770b5741e7c66081 Mon Sep 17 00:00:00 2001
From: tnsardesai <18272584+tnsardesai@users.noreply.github.com>
Date: Fri, 9 Oct 2026 18:31:38 +0000
Subject: [PATCH 3/7] Document explicit browser location with region defaults
Location is set explicitly per session; omitted or cleared fields use the default for the browser's region. Proxy-based selection is not documented until it ships.
---
browsers/location.mdx | 34 +++++++++++++++-------------------
introduction/configure.mdx | 2 +-
2 files changed, 16 insertions(+), 20 deletions(-)
diff --git a/browsers/location.mdx b/browsers/location.mdx
index 5608d0e3..21b73ed7 100644
--- a/browsers/location.mdx
+++ b/browsers/location.mdx
@@ -1,19 +1,19 @@
---
title: "Browser Location"
-description: "Align a browser session's timezone and locale with its proxy geography or set explicit overrides"
+description: "Set a browser session's timezone and locale, or use the defaults for its region"
---
-KERNEL selects one timezone and formatting locale for each browser session. By default, it resolves each field from the browser's effective proxy geography and falls back to the browser's region while resolution is pending or unavailable.
+Each browser session has one timezone and one formatting locale. By default, both come from the region the browser runs in, for example `America/New_York` and `en-US` for a browser in `us-east`. Set either field to override it for the session.
The setting applies across browser contexts, pages, frames, workers, `Intl`, `navigator.language`, `navigator.languages`, and future `Accept-Language` headers. Updating it doesn't restart Chromium or reload pages.
-Location controls timezone and language behavior. It doesn't set geolocation coordinates, grant geolocation permission, change the system clock, translate browser UI, or guarantee a bot-detection outcome.
+Location controls timezone and language behavior. It doesn't set geolocation coordinates, grant geolocation permission, change the system clock, translate browser UI, or guarantee a bot-detection outcome. KERNEL doesn't derive location from a browser's proxy; to match a proxy's country, set the location explicitly.
## Set location when creating a browser
-Set either field independently. Omit a field to let KERNEL select it automatically.
+Set either field independently. An omitted field uses the default for the browser's region.
```typescript TypeScript
@@ -21,7 +21,6 @@ import Kernel from '@onkernel/sdk';
const kernel = new Kernel();
const browser = await kernel.browsers.create({
- proxy: { name: 'berlin-checkout' },
location: {
timezone: 'Europe/Berlin',
locale: 'de-DE',
@@ -36,7 +35,6 @@ from kernel import Kernel
kernel = Kernel()
browser = kernel.browsers.create(
- proxy={"name": "berlin-checkout"},
location={
"timezone": "Europe/Berlin",
"locale": "de-DE",
@@ -78,7 +76,7 @@ PATCH semantics are field-specific:
- omit `location` or one of its fields to leave that field unchanged
- set a string to create or replace a session override
-- set a field to `null` in TypeScript or `None` in Python to clear that override and resume automatic selection
+- set a field to `null` in TypeScript or `None` in Python to clear that override and return to the default for the browser's region
```typescript TypeScript
@@ -97,35 +95,33 @@ browser = kernel.browsers.update(
```
-Clearing one field doesn't clear the other. Explicit overrides also survive proxy changes for the rest of that session.
+Clearing one field doesn't clear the other. Overrides stay in place when you change the browser's proxy.
## Read effective location
-Browser responses include the effective values, per-field provenance, and convergence state:
+Browser responses include the effective values, where each came from, and convergence state:
```json
{
"location": {
- "timezone": "Europe/Berlin",
- "locale": "de-DE",
- "timezone_source": "proxy_metadata",
- "locale_source": "proxy_metadata",
+ "timezone": "America/Los_Angeles",
+ "locale": "en-US",
+ "timezone_source": "override",
+ "locale_source": "metro",
"pending": false
}
}
```
-`timezone_source` and `locale_source` can be `override`, `proxy_metadata`, `geoip`, `exit_ip`, or `metro`. KERNEL resolves the fields independently, so their sources can differ.
+`timezone_source` and `locale_source` are `override` for a value set on the session and `metro` for the default of the browser's region. The fields are independent, so their sources can differ.
-When `pending` is `true`, the API has accepted the desired policy but the running browser hasn't finished converging. Browser creation and proxy updates don't wait for external geography discovery. KERNEL keeps the current values during a delayed or failed lookup and applies a valid late result in the background.
+When `pending` is `true`, the API has accepted the change but the running browser hasn't finished applying it. Browser creation doesn't wait for it.
## Runtime behavior
-- New pages, frames, workers, and network contexts start with the latest applied defaults.
+- New pages, frames, workers, and network contexts start with the latest applied values.
- Existing pages and workers receive the update without a reload.
- Existing `Intl` formatter objects and application-level caches can retain values captured before the update. Create a new formatter when you need the latest default.
- Future requests use the updated language preference. Requests already in flight aren't rewritten.
- Customer CDP emulation remains separate from the session default and can temporarily override what a particular target reports.
-- Location overrides last only for the browser session. Profiles don't save them.
-
-For rotating residential and mobile proxies, KERNEL resolves location when the proxy is attached or explicitly changed. It doesn't chase silent exit-IP rotation, and one discovery request doesn't represent destination-specific routes for every website.
+- Location overrides last only for the browser session. Profiles don't save them, and a browser returned to a pool loses them before its next lease.
diff --git a/introduction/configure.mdx b/introduction/configure.mdx
index 3b999fc1..bf791a33 100644
--- a/introduction/configure.mdx
+++ b/introduction/configure.mdx
@@ -91,7 +91,7 @@ browser = kernel.browsers.create(
Often agents don't require these, but they're there when you do:
- **[Regions](/browsers/regions):** run browsers in `us-east`, `eu-west`, or `ap-southeast`, closer to your code and your users.
-- **[Location](/browsers/location):** align the browser's timezone and locale with its proxy geography, or set explicit overrides without restarting Chromium.
+- **[Location](/browsers/location):** set the browser's timezone and locale for the session without restarting Chromium; otherwise they follow the browser's region.
- **[Extensions](/browsers/extensions):** load unpacked Chrome extensions into a browser.
- **[Chrome policies](/browsers/chrome-policies):** apply Chrome enterprise policies, such as startup pages and bookmarks.
- **[Private networking](/browsers/private-networking):** reach services behind a VPN or tunnel from inside the browser session.
From 47bb68572180be2233b9b38c32c19680e314a63c Mon Sep 17 00:00:00 2001
From: tnsardesai <18272584+tnsardesai@users.noreply.github.com>
Date: Fri, 9 Oct 2026 23:05:59 +0000
Subject: [PATCH 4/7] Link browser location defaults to regions
---
browsers/location.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/browsers/location.mdx b/browsers/location.mdx
index 21b73ed7..4c7c9425 100644
--- a/browsers/location.mdx
+++ b/browsers/location.mdx
@@ -3,7 +3,7 @@ title: "Browser Location"
description: "Set a browser session's timezone and locale, or use the defaults for its region"
---
-Each browser session has one timezone and one formatting locale. By default, both come from the region the browser runs in, for example `America/New_York` and `en-US` for a browser in `us-east`. Set either field to override it for the session.
+Each browser session has one timezone and one formatting locale. By default, both come from the [region](/browsers/regions) the browser runs in, for example `America/New_York` and `en-US` for a browser in `us-east`. Set either field to override it for the session.
The setting applies across browser contexts, pages, frames, workers, `Intl`, `navigator.language`, `navigator.languages`, and future `Accept-Language` headers. Updating it doesn't restart Chromium or reload pages.
From 9e2dddb026dc64b7d551c02b16389f2ea3278977 Mon Sep 17 00:00:00 2001
From: tnsardesai <18272584+tnsardesai@users.noreply.github.com>
Date: Tue, 13 Oct 2026 19:17:13 +0000
Subject: [PATCH 5/7] Document synchronous browser location updates
---
browsers/location.mdx | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/browsers/location.mdx b/browsers/location.mdx
index 4c7c9425..7702fe15 100644
--- a/browsers/location.mdx
+++ b/browsers/location.mdx
@@ -47,9 +47,11 @@ print(browser.location)
`timezone` accepts IANA identifiers such as `America/Los_Angeles`. `locale` accepts BCP 47 tags such as `en-US` or `de-DE` that the browser formats dates and numbers for with that exact region. KERNEL normalizes spelling and deprecated codes, so `en-us` becomes `en-US` and `iw-IL` becomes `he-IL`. KERNEL validates the complete request before changing the session and returns a `400` with code `invalid_browser_location` for an unsupported value such as `en-QQ`.
+The create call returns after the browser applies the location, so the first page you open already uses it. If the browser can't apply it, KERNEL discards the browser and returns a `500`. Retry the request to get a new browser.
+
## Update a running browser
-Use `browsers.update()` to set an override without restarting Chromium:
+Use `browsers.update()` to set an override without restarting Chromium. The update returns after the running browser applies the new location:
```typescript TypeScript
@@ -97,9 +99,15 @@ browser = kernel.browsers.update(
Clearing one field doesn't clear the other. Overrides stay in place when you change the browser's proxy.
+When an update doesn't take effect, the error tells you what to do next:
+
+- `409` with code `conflict`: another update changed the browser's location at the same time. Retry the request.
+- `400` with code `browser_location_unsupported`: the browser runs an image that can't change location. Create a new browser.
+- `500`: the browser didn't confirm the new location. Retry the request.
+
## Read effective location
-Browser responses include the effective values, where each came from, and convergence state:
+Browser responses include the effective values and where each came from:
```json
{
@@ -107,16 +115,13 @@ Browser responses include the effective values, where each came from, and conver
"timezone": "America/Los_Angeles",
"locale": "en-US",
"timezone_source": "override",
- "locale_source": "metro",
- "pending": false
+ "locale_source": "metro"
}
}
```
`timezone_source` and `locale_source` are `override` for a value set on the session and `metro` for the default of the browser's region. The fields are independent, so their sources can differ.
-When `pending` is `true`, the API has accepted the change but the running browser hasn't finished applying it. Browser creation doesn't wait for it.
-
## Runtime behavior
- New pages, frames, workers, and network contexts start with the latest applied values.
From 4e345722d1b242cb0e0fb0be0d14f4374b6ba9ae Mon Sep 17 00:00:00 2001
From: tnsardesai <18272584+tnsardesai@users.noreply.github.com>
Date: Tue, 13 Oct 2026 20:15:31 +0000
Subject: [PATCH 6/7] Document that reused pool browsers keep their location
---
browsers/location.mdx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/browsers/location.mdx b/browsers/location.mdx
index 7702fe15..a44957b3 100644
--- a/browsers/location.mdx
+++ b/browsers/location.mdx
@@ -129,4 +129,5 @@ Browser responses include the effective values and where each came from:
- Existing `Intl` formatter objects and application-level caches can retain values captured before the update. Create a new formatter when you need the latest default.
- Future requests use the updated language preference. Requests already in flight aren't rewritten.
- Customer CDP emulation remains separate from the session default and can temporarily override what a particular target reports.
-- Location overrides last only for the browser session. Profiles don't save them, and a browser returned to a pool loses them before its next lease.
+- Location overrides last only for the browser session, and profiles don't save them.
+- A pooled browser released with `reuse: true` keeps its location for the next acquirer, as it keeps cookies and open tabs. Release with `reuse: false` to get a fresh browser.
From 39ef7771845086eb2f7572fa5f2d97b3b54a48aa Mon Sep 17 00:00:00 2001
From: tnsardesai <18272584+tnsardesai@users.noreply.github.com>
Date: Tue, 13 Oct 2026 20:57:33 +0000
Subject: [PATCH 7/7] Document the unsupported-image create response
---
browsers/location.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/browsers/location.mdx b/browsers/location.mdx
index a44957b3..fd5edbc5 100644
--- a/browsers/location.mdx
+++ b/browsers/location.mdx
@@ -47,7 +47,7 @@ print(browser.location)
`timezone` accepts IANA identifiers such as `America/Los_Angeles`. `locale` accepts BCP 47 tags such as `en-US` or `de-DE` that the browser formats dates and numbers for with that exact region. KERNEL normalizes spelling and deprecated codes, so `en-us` becomes `en-US` and `iw-IL` becomes `he-IL`. KERNEL validates the complete request before changing the session and returns a `400` with code `invalid_browser_location` for an unsupported value such as `en-QQ`.
-The create call returns after the browser applies the location, so the first page you open already uses it. If the browser can't apply it, KERNEL discards the browser and returns a `500`. Retry the request to get a new browser.
+The create call returns after the browser applies the location, so the first page you open already uses it. If the browser can't apply it, KERNEL discards the browser and returns a `500`. Retry the request to get a new browser. If the assigned browser's image can't change location, KERNEL discards it and returns a `400` with code `browser_location_unsupported` instead. Try again later, or create the browser without `location`.
## Update a running browser