diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 6772f01..6f257c8 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.71.0"
+ ".": "0.72.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index ef32d38..10d9022 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 124
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-4fb45d71a99648425c84bdc8e5780920105cede4ee2d4eac67276d0609ac1e94.yml
-openapi_spec_hash: 1f04cb5b36e92db81dfa264c2a59c32a
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-4c243ff089133bd49322d98a6943647589972f71ecadc993fe9e5029972b3995.yml
+openapi_spec_hash: a2cb637a19a070d07a1a4343c75444ee
config_hash: fb167e754ebb3a14649463725891c9d0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2a23788..014bb49 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.72.0 (2026-06-26)
+
+Full Changelog: [v0.71.0...v0.72.0](https://github.com/kernel/kernel-go-sdk/compare/v0.71.0...v0.72.0)
+
+### Bug Fixes
+
+* **api:** browser pool profile omits save_changes (BrowserPoolProfile) ([5e31861](https://github.com/kernel/kernel-go-sdk/commit/5e31861edf251908db94a60e32f5f15507a6f272))
+
## 0.71.0 (2026-06-26)
Full Changelog: [v0.70.0...v0.71.0](https://github.com/kernel/kernel-go-sdk/compare/v0.70.0...v0.71.0)
diff --git a/README.md b/README.md
index 5375aa5..14f9663 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ Or to pin the version:
```sh
-go get -u 'github.com/kernel/kernel-go-sdk@v0.71.0'
+go get -u 'github.com/kernel/kernel-go-sdk@v0.72.0'
```
diff --git a/aliases.go b/aliases.go
index fb2a35c..4e4c322 100644
--- a/aliases.go
+++ b/aliases.go
@@ -33,13 +33,6 @@ type BrowserExtension = shared.BrowserExtension
// This is an alias to an internal type.
type BrowserExtensionParam = shared.BrowserExtensionParam
-// Profile selection for the browser session. Provide either id or name. If
-// specified, the matching profile will be loaded into the browser session.
-// Profiles must be created beforehand.
-//
-// This is an alias to an internal type.
-type BrowserProfile = shared.BrowserProfile
-
// Profile selection for the browser session. Provide either id or name. If
// specified, the matching profile will be loaded into the browser session.
// Profiles must be created beforehand.
diff --git a/api.md b/api.md
index 09422fc..c119a4c 100644
--- a/api.md
+++ b/api.md
@@ -8,7 +8,6 @@
- shared.AppAction
- shared.BrowserExtension
-- shared.BrowserProfile
- shared.BrowserViewport
- shared.ErrorDetail
- shared.ErrorEvent
diff --git a/browserpool.go b/browserpool.go
index 62d2422..651a721 100644
--- a/browserpool.go
+++ b/browserpool.go
@@ -42,7 +42,10 @@ func NewBrowserPoolService(opts ...option.RequestOption) (r BrowserPoolService)
return
}
-// Create a new browser pool with the specified configuration and size.
+// Create a new browser pool with the specified configuration and size. Pooled
+// browsers load their profile read-only: any save_changes on the profile is
+// ignored (not rejected), so pooled browsers never persist changes back to the
+// profile.
func (r *BrowserPoolService) New(ctx context.Context, body BrowserPoolNewParams, opts ...option.RequestOption) (res *BrowserPool, err error) {
opts = slices.Concat(r.Options, opts)
path := "browser_pools"
@@ -62,7 +65,9 @@ func (r *BrowserPoolService) Get(ctx context.Context, idOrName string, opts ...o
return res, err
}
-// Updates the configuration used to create browsers in the pool.
+// Updates the configuration used to create browsers in the pool. As with creation,
+// save_changes on the pool profile is ignored (not rejected); pooled browsers
+// never persist changes back to the profile.
func (r *BrowserPoolService) Update(ctx context.Context, idOrName string, body BrowserPoolUpdateParams, opts ...option.RequestOption) (res *BrowserPool, err error) {
opts = slices.Concat(r.Options, opts)
if idOrName == "" {
@@ -209,10 +214,13 @@ type BrowserPoolBrowserPoolConfig struct {
KioskMode bool `json:"kiosk_mode"`
// Optional name for the browser pool. Must be unique within the project.
Name string `json:"name"`
- // Profile selection for the browser session. Provide either id or name. If
- // specified, the matching profile will be loaded into the browser session.
- // Profiles must be created beforehand.
- Profile shared.BrowserProfile `json:"profile"`
+ // Profile selection for browsers in a pool. Provide either id or name. The
+ // matching profile is loaded into every browser in the pool. Profiles must be
+ // created beforehand. Unlike single browser sessions, pools load the profile
+ // read-only and never persist changes back to it, so save_changes is omitted here.
+ // Any save_changes value sent on a pool profile is silently ignored rather than
+ // rejected, so callers reusing a single-session profile object will not error.
+ Profile BrowserPoolBrowserPoolConfigProfile `json:"profile"`
// Optional proxy to associate to the browser session. Must reference a proxy in
// the same project as the browser session.
ProxyID string `json:"proxy_id"`
@@ -267,6 +275,33 @@ func (r *BrowserPoolBrowserPoolConfig) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// Profile selection for browsers in a pool. Provide either id or name. The
+// matching profile is loaded into every browser in the pool. Profiles must be
+// created beforehand. Unlike single browser sessions, pools load the profile
+// read-only and never persist changes back to it, so save_changes is omitted here.
+// Any save_changes value sent on a pool profile is silently ignored rather than
+// rejected, so callers reusing a single-session profile object will not error.
+type BrowserPoolBrowserPoolConfigProfile struct {
+ // Profile ID to load for browsers in this pool
+ ID string `json:"id"`
+ // Profile name to load for browsers in this pool (instead of id). Must be 1-255
+ // characters, using letters, numbers, dots, underscores, or hyphens.
+ Name string `json:"name"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ Name respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r BrowserPoolBrowserPoolConfigProfile) RawJSON() string { return r.JSON.raw }
+func (r *BrowserPoolBrowserPoolConfigProfile) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
type BrowserPoolAcquireResponse struct {
// Websocket URL for Chrome DevTools Protocol connections to the browser session
CdpWsURL string `json:"cdp_ws_url" api:"required"`
@@ -405,10 +440,13 @@ type BrowserPoolNewParams struct {
ChromePolicy map[string]any `json:"chrome_policy,omitzero"`
// List of browser extensions to load into the session. Provide each by id or name.
Extensions []shared.BrowserExtensionParam `json:"extensions,omitzero"`
- // Profile selection for the browser session. Provide either id or name. If
- // specified, the matching profile will be loaded into the browser session.
- // Profiles must be created beforehand.
- Profile shared.BrowserProfileParam `json:"profile,omitzero"`
+ // Profile selection for browsers in a pool. Provide either id or name. The
+ // matching profile is loaded into every browser in the pool. Profiles must be
+ // created beforehand. Unlike single browser sessions, pools load the profile
+ // read-only and never persist changes back to it, so save_changes is omitted here.
+ // Any save_changes value sent on a pool profile is silently ignored rather than
+ // rejected, so callers reusing a single-session profile object will not error.
+ Profile BrowserPoolNewParamsProfile `json:"profile,omitzero"`
// Initial browser window size in pixels with optional refresh rate. If omitted,
// image defaults apply (1920x1080@25). For GPU images, the default is
// 1920x1080@60. Arbitrary viewport dimensions and refresh rates are accepted.
@@ -433,6 +471,29 @@ func (r *BrowserPoolNewParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// Profile selection for browsers in a pool. Provide either id or name. The
+// matching profile is loaded into every browser in the pool. Profiles must be
+// created beforehand. Unlike single browser sessions, pools load the profile
+// read-only and never persist changes back to it, so save_changes is omitted here.
+// Any save_changes value sent on a pool profile is silently ignored rather than
+// rejected, so callers reusing a single-session profile object will not error.
+type BrowserPoolNewParamsProfile struct {
+ // Profile ID to load for browsers in this pool
+ ID param.Opt[string] `json:"id,omitzero"`
+ // Profile name to load for browsers in this pool (instead of id). Must be 1-255
+ // characters, using letters, numbers, dots, underscores, or hyphens.
+ Name param.Opt[string] `json:"name,omitzero"`
+ paramObj
+}
+
+func (r BrowserPoolNewParamsProfile) MarshalJSON() (data []byte, err error) {
+ type shadow BrowserPoolNewParamsProfile
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *BrowserPoolNewParamsProfile) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
type BrowserPoolUpdateParams struct {
// Whether to discard all idle browsers and rebuild the pool immediately. Defaults
// to false.
@@ -474,10 +535,13 @@ type BrowserPoolUpdateParams struct {
ChromePolicy map[string]any `json:"chrome_policy,omitzero"`
// List of browser extensions to load into the session. Provide each by id or name.
Extensions []shared.BrowserExtensionParam `json:"extensions,omitzero"`
- // Profile selection for the browser session. Provide either id or name. If
- // specified, the matching profile will be loaded into the browser session.
- // Profiles must be created beforehand.
- Profile shared.BrowserProfileParam `json:"profile,omitzero"`
+ // Profile selection for browsers in a pool. Provide either id or name. The
+ // matching profile is loaded into every browser in the pool. Profiles must be
+ // created beforehand. Unlike single browser sessions, pools load the profile
+ // read-only and never persist changes back to it, so save_changes is omitted here.
+ // Any save_changes value sent on a pool profile is silently ignored rather than
+ // rejected, so callers reusing a single-session profile object will not error.
+ Profile BrowserPoolUpdateParamsProfile `json:"profile,omitzero"`
// Initial browser window size in pixels with optional refresh rate. If omitted,
// image defaults apply (1920x1080@25). For GPU images, the default is
// 1920x1080@60. Arbitrary viewport dimensions and refresh rates are accepted.
@@ -502,6 +566,29 @@ func (r *BrowserPoolUpdateParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// Profile selection for browsers in a pool. Provide either id or name. The
+// matching profile is loaded into every browser in the pool. Profiles must be
+// created beforehand. Unlike single browser sessions, pools load the profile
+// read-only and never persist changes back to it, so save_changes is omitted here.
+// Any save_changes value sent on a pool profile is silently ignored rather than
+// rejected, so callers reusing a single-session profile object will not error.
+type BrowserPoolUpdateParamsProfile struct {
+ // Profile ID to load for browsers in this pool
+ ID param.Opt[string] `json:"id,omitzero"`
+ // Profile name to load for browsers in this pool (instead of id). Must be 1-255
+ // characters, using letters, numbers, dots, underscores, or hyphens.
+ Name param.Opt[string] `json:"name,omitzero"`
+ paramObj
+}
+
+func (r BrowserPoolUpdateParamsProfile) MarshalJSON() (data []byte, err error) {
+ type shadow BrowserPoolUpdateParamsProfile
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *BrowserPoolUpdateParamsProfile) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
type BrowserPoolListParams struct {
// Limit the number of browser pools to return.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
diff --git a/browserpool_test.go b/browserpool_test.go
index 9de8eea..751cc53 100644
--- a/browserpool_test.go
+++ b/browserpool_test.go
@@ -40,10 +40,9 @@ func TestBrowserPoolNewWithOptionalParams(t *testing.T) {
Headless: kernel.Bool(false),
KioskMode: kernel.Bool(true),
Name: kernel.String("my-pool"),
- Profile: shared.BrowserProfileParam{
- ID: kernel.String("id"),
- Name: kernel.String("name"),
- SaveChanges: kernel.Bool(true),
+ Profile: kernel.BrowserPoolNewParamsProfile{
+ ID: kernel.String("id"),
+ Name: kernel.String("name"),
},
ProxyID: kernel.String("proxy_id"),
StartURL: kernel.String("https://example.com"),
@@ -116,10 +115,9 @@ func TestBrowserPoolUpdateWithOptionalParams(t *testing.T) {
Headless: kernel.Bool(false),
KioskMode: kernel.Bool(true),
Name: kernel.String("my-pool"),
- Profile: shared.BrowserProfileParam{
- ID: kernel.String("id"),
- Name: kernel.String("name"),
- SaveChanges: kernel.Bool(true),
+ Profile: kernel.BrowserPoolUpdateParamsProfile{
+ ID: kernel.String("id"),
+ Name: kernel.String("name"),
},
ProxyID: kernel.String("proxy_id"),
Size: kernel.Int(10),
diff --git a/internal/version.go b/internal/version.go
index 8f679d4..7b8ed86 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "0.71.0" // x-release-please-version
+const PackageVersion = "0.72.0" // x-release-please-version
diff --git a/shared/shared.go b/shared/shared.go
index 366ff9e..2d07e6d 100644
--- a/shared/shared.go
+++ b/shared/shared.go
@@ -95,43 +95,6 @@ func (r *BrowserExtensionParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Profile selection for the browser session. Provide either id or name. If
-// specified, the matching profile will be loaded into the browser session.
-// Profiles must be created beforehand.
-type BrowserProfile struct {
- // Profile ID to load for this browser session
- ID string `json:"id"`
- // Profile name to load for this browser session (instead of id). Must be 1-255
- // characters, using letters, numbers, dots, underscores, or hyphens.
- Name string `json:"name"`
- // If true, save changes made during the session back to the profile when the
- // session ends.
- SaveChanges bool `json:"save_changes"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Name respjson.Field
- SaveChanges respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r BrowserProfile) RawJSON() string { return r.JSON.raw }
-func (r *BrowserProfile) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// ToParam converts this BrowserProfile to a BrowserProfileParam.
-//
-// Warning: the fields of the param type will not be present. ToParam should only
-// be used at the last possible moment before sending a request. Test for this with
-// BrowserProfileParam.Overrides()
-func (r BrowserProfile) ToParam() BrowserProfileParam {
- return param.Override[BrowserProfileParam](json.RawMessage(r.RawJSON()))
-}
-
// Profile selection for the browser session. Provide either id or name. If
// specified, the matching profile will be loaded into the browser session.
// Profiles must be created beforehand.