From edcc0e5e25cbce705d36a316b146a6eda30dc4fb Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 9 Jul 2026 23:07:40 +0000
Subject: [PATCH 01/10] docs(openapi): describe unified concurrency limit,
deprecate max_pooled_sessions (CUS-275)
---
.stats.yml | 4 ++--
organizationlimit.go | 21 +++++++++++----------
projectlimit.go | 23 +++++++++++++++--------
3 files changed, 28 insertions(+), 20 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 3f7dec3..c702819 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 125
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-ba32039d3975da7aa6d28e5184f0a44c9fbfe36ab7dbc71985d14e2ecc0867b9.yml
-openapi_spec_hash: a9f32fc90c2add2ae85af828c298e35b
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-db45aab5b114bc0848eab997c85bfc02a653be9f929f8d090ec24187462733ee.yml
+openapi_spec_hash: 82f4282312699f8d54bec207e981efe8
config_hash: 06186eb40e0058a2a87ac251fc07415d
diff --git a/organizationlimit.go b/organizationlimit.go
index 0860565..b1d5859 100644
--- a/organizationlimit.go
+++ b/organizationlimit.go
@@ -36,8 +36,9 @@ func NewOrganizationLimitService(opts ...option.RequestOption) (r OrganizationLi
return
}
-// Get the organization's concurrent session ceiling and the default per-project
-// concurrency cap applied to projects without an explicit override.
+// Get the organization's concurrency limit — the maximum browsers running at once
+// across on-demand sessions and browser pool reservations — and the default
+// per-project concurrency cap applied to projects without an explicit override.
func (r *OrganizationLimitService) Get(ctx context.Context, opts ...option.RequestOption) (res *OrgLimits, err error) {
opts = slices.Concat(r.Options, opts)
path := "org/limits"
@@ -47,8 +48,7 @@ func (r *OrganizationLimitService) Get(ctx context.Context, opts ...option.Reque
// Set the default per-project concurrency cap applied to projects without an
// explicit override. Set the value to 0 to remove the default; omit to leave it
-// unchanged. The default cannot exceed the organization's concurrent session
-// ceiling.
+// unchanged. The default cannot exceed the organization's concurrency limit.
func (r *OrganizationLimitService) Update(ctx context.Context, body OrganizationLimitUpdateParams, opts ...option.RequestOption) (res *OrgLimits, err error) {
opts = slices.Concat(r.Options, opts)
path := "org/limits"
@@ -57,13 +57,14 @@ func (r *OrganizationLimitService) Update(ctx context.Context, body Organization
}
type OrgLimits struct {
- // Default maximum concurrent browser sessions applied to every project that has no
+ // Default maximum concurrent browsers applied to every project that has no
// explicit per-project override. Null means no org-level default, so such projects
// are uncapped (only the org-wide limit applies). Applies to existing and newly
// created projects.
DefaultProjectMaxConcurrentSessions int64 `json:"default_project_max_concurrent_sessions" api:"nullable"`
- // The organization's effective concurrent browser session ceiling, from its plan
- // or an override. Read-only and shared across all projects in the org; a
+ // The organization's effective concurrency limit — the maximum browsers running at
+ // once, covering both on-demand sessions and browser pool reservations — from its
+ // plan or an override. Read-only and shared across all projects in the org; a
// per-project default cannot exceed it.
MaxConcurrentSessions int64 `json:"max_concurrent_sessions"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -82,9 +83,9 @@ func (r *OrgLimits) UnmarshalJSON(data []byte) error {
}
type UpdateOrgLimitsRequestParam struct {
- // Default maximum concurrent browser sessions for projects without an explicit
- // override. Set to 0 to remove the default; omit to leave unchanged. Cannot exceed
- // the organization's concurrent session ceiling.
+ // Default maximum concurrent browsers for projects without an explicit override.
+ // Set to 0 to remove the default; omit to leave unchanged. Cannot exceed the
+ // organization's concurrency limit.
DefaultProjectMaxConcurrentSessions param.Opt[int64] `json:"default_project_max_concurrent_sessions,omitzero"`
paramObj
}
diff --git a/projectlimit.go b/projectlimit.go
index ef8de57..ac288fd 100644
--- a/projectlimit.go
+++ b/projectlimit.go
@@ -69,11 +69,14 @@ type ProjectLimits struct {
// Maximum concurrent app invocations for this project. Null means no project-level
// cap.
MaxConcurrentInvocations int64 `json:"max_concurrent_invocations" api:"nullable"`
- // Maximum concurrent browser sessions for this project. Null means no
- // project-level cap.
- MaxConcurrentSessions int64 `json:"max_concurrent_sessions" api:"nullable"`
- // Maximum pooled sessions capacity for this project. Null means no project-level
+ // Maximum concurrent browsers for this project, covering both on-demand sessions
+ // (`browsers.create()`) and browser pool reservations. Null means no project-level
// cap.
+ MaxConcurrentSessions int64 `json:"max_concurrent_sessions" api:"nullable"`
+ // Deprecated: pooled browsers now count toward `max_concurrent_sessions`. Always
+ // null once the unified concurrency limit is enabled for your organization.
+ //
+ // Deprecated: deprecated
MaxPooledSessions int64 `json:"max_pooled_sessions" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -95,11 +98,15 @@ type UpdateProjectLimitsRequestParam struct {
// Maximum concurrent app invocations for this project. Set to 0 to remove the cap;
// omit to leave unchanged.
MaxConcurrentInvocations param.Opt[int64] `json:"max_concurrent_invocations,omitzero"`
- // Maximum concurrent browser sessions for this project. Set to 0 to remove the
- // cap; omit to leave unchanged.
+ // Maximum concurrent browsers for this project, covering both on-demand sessions
+ // and browser pool reservations. Set to 0 to remove the cap; omit to leave
+ // unchanged.
MaxConcurrentSessions param.Opt[int64] `json:"max_concurrent_sessions,omitzero"`
- // Maximum pooled sessions capacity for this project. Set to 0 to remove the cap;
- // omit to leave unchanged.
+ // Deprecated: pooled browsers now count toward `max_concurrent_sessions`. Requests
+ // that set this field are rejected with a 400 once the unified concurrency limit
+ // is enabled for your organization.
+ //
+ // Deprecated: deprecated
MaxPooledSessions param.Opt[int64] `json:"max_pooled_sessions,omitzero"`
paramObj
}
From c2b2b5e5cf318b2d6c9e964b65274f8de4a57a35 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 10 Jul 2026 13:45:51 +0000
Subject: [PATCH 02/10] feat: Add name-only rename for profiles and proxies
---
.stats.yml | 8 +-
api.md | 3 +
profile.go | 38 +++++-
profile_test.go | 29 +++++
proxy.go | 302 ++++++++++++++++++++++++++++++++++++++++++++++++
proxy_test.go | 29 +++++
6 files changed, 404 insertions(+), 5 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c702819..09109a9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 125
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-db45aab5b114bc0848eab997c85bfc02a653be9f929f8d090ec24187462733ee.yml
-openapi_spec_hash: 82f4282312699f8d54bec207e981efe8
-config_hash: 06186eb40e0058a2a87ac251fc07415d
+configured_endpoints: 127
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-bc33d13e669972493e9ab0da82a71999822dc049eb14b113f446753c917ffcdb.yml
+openapi_spec_hash: 133a2e0d0cdc4023f98b3c2e589cf5d8
+config_hash: 77ee715aa17061166f9a02b264a21b8d
diff --git a/api.md b/api.md
index 43da313..2a11317 100644
--- a/api.md
+++ b/api.md
@@ -264,6 +264,7 @@ Methods:
- client.Profiles.New(ctx context.Context, body kernel.ProfileNewParams) (\*kernel.Profile, error)
- client.Profiles.Get(ctx context.Context, idOrName string) (\*kernel.Profile, error)
+- client.Profiles.Update(ctx context.Context, idOrName string, body kernel.ProfileUpdateParams) (\*kernel.Profile, error)
- client.Profiles.List(ctx context.Context, query kernel.ProfileListParams) (\*pagination.OffsetPagination[kernel.Profile], error)
- client.Profiles.Delete(ctx context.Context, idOrName string) error
- client.Profiles.Download(ctx context.Context, idOrName string) (\*http.Response, error)
@@ -304,6 +305,7 @@ Response Types:
- kernel.ProxyNewResponse
- kernel.ProxyGetResponse
+- kernel.ProxyUpdateResponse
- kernel.ProxyListResponse
- kernel.ProxyCheckResponse
@@ -311,6 +313,7 @@ Methods:
- client.Proxies.New(ctx context.Context, body kernel.ProxyNewParams) (\*kernel.ProxyNewResponse, error)
- client.Proxies.Get(ctx context.Context, id string) (\*kernel.ProxyGetResponse, error)
+- client.Proxies.Update(ctx context.Context, id string, body kernel.ProxyUpdateParams) (\*kernel.ProxyUpdateResponse, error)
- client.Proxies.List(ctx context.Context, query kernel.ProxyListParams) (\*pagination.OffsetPagination[kernel.ProxyListResponse], error)
- client.Proxies.Delete(ctx context.Context, id string) error
- client.Proxies.Check(ctx context.Context, id string, body kernel.ProxyCheckParams) (\*kernel.ProxyCheckResponse, error)
diff --git a/profile.go b/profile.go
index 58304a9..2e6e3cf 100644
--- a/profile.go
+++ b/profile.go
@@ -60,6 +60,24 @@ func (r *ProfileService) Get(ctx context.Context, idOrName string, opts ...optio
return res, err
}
+// Update a profile's name. Names must be unique within the logical project; during
+// the default-project migration, unscoped profiles and profiles in the org default
+// project are treated as the same project. Duplicate-name conflicts are checked
+// before update but are best-effort because there is no backing unique index.
+// Renaming a profile while a browser session references it by name may prevent
+// that session's changes from saving; prefer renaming when the profile is not in
+// use.
+func (r *ProfileService) Update(ctx context.Context, idOrName string, body ProfileUpdateParams, opts ...option.RequestOption) (res *Profile, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if idOrName == "" {
+ err = errors.New("missing required id_or_name parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("profiles/%s", idOrName)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...)
+ return res, err
+}
+
// List profiles with optional filtering and pagination.
func (r *ProfileService) List(ctx context.Context, query ProfileListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[Profile], err error) {
var raw *http.Response
@@ -110,7 +128,9 @@ func (r *ProfileService) Download(ctx context.Context, idOrName string, opts ...
}
type ProfileNewParams struct {
- // Optional name of the profile. Must be unique within the project.
+ // Optional name of the profile. Must be unique within the logical project; during
+ // the default-project migration, unscoped profiles and profiles in the org default
+ // project are treated as the same project.
Name param.Opt[string] `json:"name,omitzero"`
paramObj
}
@@ -123,6 +143,22 @@ func (r *ProfileNewParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+type ProfileUpdateParams struct {
+ // New profile name. Must be unique within the logical project; during the
+ // default-project migration, unscoped profiles and profiles in the org default
+ // project are treated as the same project.
+ Name string `json:"name" api:"required"`
+ paramObj
+}
+
+func (r ProfileUpdateParams) MarshalJSON() (data []byte, err error) {
+ type shadow ProfileUpdateParams
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ProfileUpdateParams) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
type ProfileListParams struct {
// Limit the number of profiles to return.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
diff --git a/profile_test.go b/profile_test.go
index 179bf75..17b1a4c 100644
--- a/profile_test.go
+++ b/profile_test.go
@@ -65,6 +65,35 @@ func TestProfileGet(t *testing.T) {
}
}
+func TestProfileUpdate(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Profiles.Update(
+ context.TODO(),
+ "id_or_name",
+ kernel.ProfileUpdateParams{
+ Name: "my-renamed-profile",
+ },
+ )
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
func TestProfileListWithOptionalParams(t *testing.T) {
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
diff --git a/proxy.go b/proxy.go
index 2de2856..037d47f 100644
--- a/proxy.go
+++ b/proxy.go
@@ -62,6 +62,21 @@ func (r *ProxyService) Get(ctx context.Context, id string, opts ...option.Reques
return res, err
}
+// Update a proxy's name. Proxy names are not unique and are not ID-or-name
+// addressable on this endpoint; duplicate names are allowed. Name-based
+// session-create lookups can remain ambiguous until callers resolve proxies by ID
+// or the API adds a stronger uniqueness contract.
+func (r *ProxyService) Update(ctx context.Context, id string, body ProxyUpdateParams, opts ...option.RequestOption) (res *ProxyUpdateResponse, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("proxies/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...)
+ return res, err
+}
+
// List proxies in the resolved project.
func (r *ProxyService) List(ctx context.Context, query ProxyListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[ProxyListResponse], err error) {
var raw *http.Response
@@ -659,6 +674,278 @@ const (
ProxyGetResponseStatusUnavailable ProxyGetResponseStatus = "unavailable"
)
+// Configuration for routing traffic through a proxy.
+type ProxyUpdateResponse struct {
+ // Proxy type to use. In terms of quality for avoiding bot-detection, from best to
+ // worst: `mobile` > `residential` > `isp` > `datacenter`.
+ //
+ // Any of "datacenter", "isp", "residential", "mobile", "custom".
+ Type ProxyUpdateResponseType `json:"type" api:"required"`
+ ID string `json:"id"`
+ // Hostnames that should bypass the parent proxy and connect directly.
+ BypassHosts []string `json:"bypass_hosts"`
+ // Configuration specific to the selected proxy `type`.
+ Config ProxyUpdateResponseConfigUnion `json:"config"`
+ // IP address that the proxy uses when making requests.
+ IPAddress string `json:"ip_address"`
+ // Timestamp of the last health check performed on this proxy.
+ LastChecked time.Time `json:"last_checked" format:"date-time"`
+ // Readable name of the proxy.
+ Name string `json:"name"`
+ // Protocol to use for the proxy connection.
+ //
+ // Any of "http", "https".
+ Protocol ProxyUpdateResponseProtocol `json:"protocol"`
+ // Current health status of the proxy.
+ //
+ // Any of "available", "unavailable".
+ Status ProxyUpdateResponseStatus `json:"status"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Type respjson.Field
+ ID respjson.Field
+ BypassHosts respjson.Field
+ Config respjson.Field
+ IPAddress respjson.Field
+ LastChecked respjson.Field
+ Name respjson.Field
+ Protocol respjson.Field
+ Status respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ProxyUpdateResponse) RawJSON() string { return r.JSON.raw }
+func (r *ProxyUpdateResponse) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Proxy type to use. In terms of quality for avoiding bot-detection, from best to
+// worst: `mobile` > `residential` > `isp` > `datacenter`.
+type ProxyUpdateResponseType string
+
+const (
+ ProxyUpdateResponseTypeDatacenter ProxyUpdateResponseType = "datacenter"
+ ProxyUpdateResponseTypeIsp ProxyUpdateResponseType = "isp"
+ ProxyUpdateResponseTypeResidential ProxyUpdateResponseType = "residential"
+ ProxyUpdateResponseTypeMobile ProxyUpdateResponseType = "mobile"
+ ProxyUpdateResponseTypeCustom ProxyUpdateResponseType = "custom"
+)
+
+// ProxyUpdateResponseConfigUnion contains all possible properties and values from
+// [ProxyUpdateResponseConfigDatacenter], [ProxyUpdateResponseConfigIsp],
+// [ProxyUpdateResponseConfigResidential], [ProxyUpdateResponseConfigMobile],
+// [ProxyUpdateResponseConfigCustom].
+//
+// Use the methods beginning with 'As' to cast the union to one of its variants.
+type ProxyUpdateResponseConfigUnion struct {
+ Country string `json:"country"`
+ // This field is from variant [ProxyUpdateResponseConfigResidential].
+ Asn string `json:"asn"`
+ City string `json:"city"`
+ // This field is from variant [ProxyUpdateResponseConfigResidential].
+ Os string `json:"os"`
+ State string `json:"state"`
+ // This field is from variant [ProxyUpdateResponseConfigResidential].
+ Zip string `json:"zip"`
+ // This field is from variant [ProxyUpdateResponseConfigCustom].
+ Host string `json:"host"`
+ // This field is from variant [ProxyUpdateResponseConfigCustom].
+ Port int64 `json:"port"`
+ // This field is from variant [ProxyUpdateResponseConfigCustom].
+ HasPassword bool `json:"has_password"`
+ // This field is from variant [ProxyUpdateResponseConfigCustom].
+ Username string `json:"username"`
+ JSON struct {
+ Country respjson.Field
+ Asn respjson.Field
+ City respjson.Field
+ Os respjson.Field
+ State respjson.Field
+ Zip respjson.Field
+ Host respjson.Field
+ Port respjson.Field
+ HasPassword respjson.Field
+ Username respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+func (u ProxyUpdateResponseConfigUnion) AsDatacenter() (v ProxyUpdateResponseConfigDatacenter) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
+func (u ProxyUpdateResponseConfigUnion) AsIsp() (v ProxyUpdateResponseConfigIsp) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
+func (u ProxyUpdateResponseConfigUnion) AsResidential() (v ProxyUpdateResponseConfigResidential) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
+func (u ProxyUpdateResponseConfigUnion) AsMobile() (v ProxyUpdateResponseConfigMobile) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
+func (u ProxyUpdateResponseConfigUnion) AsCustom() (v ProxyUpdateResponseConfigCustom) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
+// Returns the unmodified JSON received from the API
+func (u ProxyUpdateResponseConfigUnion) RawJSON() string { return u.JSON.raw }
+
+func (r *ProxyUpdateResponseConfigUnion) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Configuration for a datacenter proxy.
+type ProxyUpdateResponseConfigDatacenter struct {
+ // ISO 3166 country code. Defaults to US if not provided.
+ Country string `json:"country"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Country respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ProxyUpdateResponseConfigDatacenter) RawJSON() string { return r.JSON.raw }
+func (r *ProxyUpdateResponseConfigDatacenter) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Configuration for an ISP proxy.
+type ProxyUpdateResponseConfigIsp struct {
+ // ISO 3166 country code. Defaults to US if not provided.
+ Country string `json:"country"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Country respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ProxyUpdateResponseConfigIsp) RawJSON() string { return r.JSON.raw }
+func (r *ProxyUpdateResponseConfigIsp) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Configuration for residential proxies.
+type ProxyUpdateResponseConfigResidential struct {
+ // Autonomous system number. See https://bgp.potaroo.net/cidr/autnums.html
+ Asn string `json:"asn"`
+ // City name (no spaces, e.g. `sanfrancisco`). If provided, `country` must also be
+ // provided.
+ City string `json:"city"`
+ // ISO 3166 country code.
+ Country string `json:"country"`
+ // Operating system of the residential device.
+ //
+ // Any of "windows", "macos", "android".
+ //
+ // Deprecated: deprecated
+ Os string `json:"os"`
+ // Two-letter state code.
+ State string `json:"state"`
+ // US ZIP code.
+ Zip string `json:"zip"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Asn respjson.Field
+ City respjson.Field
+ Country respjson.Field
+ Os respjson.Field
+ State respjson.Field
+ Zip respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ProxyUpdateResponseConfigResidential) RawJSON() string { return r.JSON.raw }
+func (r *ProxyUpdateResponseConfigResidential) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Configuration for mobile proxies.
+type ProxyUpdateResponseConfigMobile struct {
+ // Provider city alias. Mobile carrier routing can make observed geo vary.
+ City string `json:"city"`
+ // ISO 3166 country code
+ Country string `json:"country"`
+ // US-only state code. Mobile carrier routing can make observed geo vary.
+ State string `json:"state"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ City respjson.Field
+ Country respjson.Field
+ State respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ProxyUpdateResponseConfigMobile) RawJSON() string { return r.JSON.raw }
+func (r *ProxyUpdateResponseConfigMobile) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Configuration for a custom proxy (e.g., private proxy server).
+type ProxyUpdateResponseConfigCustom struct {
+ // Proxy host address or IP.
+ Host string `json:"host" api:"required"`
+ // Proxy port.
+ Port int64 `json:"port" api:"required"`
+ // Whether the proxy has a password.
+ HasPassword bool `json:"has_password"`
+ // Username for proxy authentication.
+ Username string `json:"username"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Host respjson.Field
+ Port respjson.Field
+ HasPassword respjson.Field
+ Username respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ProxyUpdateResponseConfigCustom) RawJSON() string { return r.JSON.raw }
+func (r *ProxyUpdateResponseConfigCustom) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Protocol to use for the proxy connection.
+type ProxyUpdateResponseProtocol string
+
+const (
+ ProxyUpdateResponseProtocolHTTP ProxyUpdateResponseProtocol = "http"
+ ProxyUpdateResponseProtocolHTTPS ProxyUpdateResponseProtocol = "https"
+)
+
+// Current health status of the proxy.
+type ProxyUpdateResponseStatus string
+
+const (
+ ProxyUpdateResponseStatusAvailable ProxyUpdateResponseStatus = "available"
+ ProxyUpdateResponseStatusUnavailable ProxyUpdateResponseStatus = "unavailable"
+)
+
// Configuration for routing traffic through a proxy.
type ProxyListResponse struct {
// Proxy type to use. In terms of quality for avoiding bot-detection, from best to
@@ -1486,6 +1773,21 @@ const (
ProxyNewParamsProtocolHTTPS ProxyNewParamsProtocol = "https"
)
+type ProxyUpdateParams struct {
+ // New proxy name. Proxy names are trimmed and length-checked only; duplicates are
+ // allowed because proxies are updated by ID, not by name.
+ Name string `json:"name" api:"required"`
+ paramObj
+}
+
+func (r ProxyUpdateParams) MarshalJSON() (data []byte, err error) {
+ type shadow ProxyUpdateParams
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ProxyUpdateParams) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
type ProxyListParams struct {
// Limit the number of proxies to return.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
diff --git a/proxy_test.go b/proxy_test.go
index 6775135..272bab1 100644
--- a/proxy_test.go
+++ b/proxy_test.go
@@ -69,6 +69,35 @@ func TestProxyGet(t *testing.T) {
}
}
+func TestProxyUpdate(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Proxies.Update(
+ context.TODO(),
+ "id",
+ kernel.ProxyUpdateParams{
+ Name: "my-renamed-proxy",
+ },
+ )
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
func TestProxyListWithOptionalParams(t *testing.T) {
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
From fd4fcffa2ad8d35878a189a1a66e9e8aac2df872 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 10 Jul 2026 14:19:09 +0000
Subject: [PATCH 03/10] feat: Document name uniqueness and query match
semantics
---
.stats.yml | 4 ++--
apikey.go | 5 +++--
authconnection.go | 24 ++++++++++++++++++------
browserpool.go | 3 ++-
credential.go | 3 ++-
credentialprovider.go | 3 ++-
extension.go | 3 ++-
profile.go | 2 +-
proxy.go | 3 ++-
9 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 09109a9..b058b75 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 127
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-bc33d13e669972493e9ab0da82a71999822dc049eb14b113f446753c917ffcdb.yml
-openapi_spec_hash: 133a2e0d0cdc4023f98b3c2e589cf5d8
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-6c7cbaefd8a84ec26a1677681f37041323290080dac3fd1a409bb7cd01dd2ae3.yml
+openapi_spec_hash: 75085a25c8a5cdb5417f0dbfad0ed6b6
config_hash: 77ee715aa17061166f9a02b264a21b8d
diff --git a/apikey.go b/apikey.go
index 314d151..f215164 100644
--- a/apikey.go
+++ b/apikey.go
@@ -138,7 +138,8 @@ type APIKey struct {
ExpiresAt time.Time `json:"expires_at" api:"required" format:"date-time"`
// Masked version of the API key
MaskedKey string `json:"masked_key" api:"required"`
- // API key name
+ // Label for the API key. API keys are not addressable by name; use the ID or key
+ // identifier for stable references.
Name string `json:"name" api:"required"`
// Project identifier for project-scoped API keys. Null means org-wide.
ProjectID string `json:"project_id" api:"required"`
@@ -210,7 +211,7 @@ func (r *CreatedAPIKey) UnmarshalJSON(data []byte) error {
}
type APIKeyNewParams struct {
- // API key name (1-255 characters)
+ // Label for the API key (1-255 characters). API keys are not addressable by name.
Name string `json:"name" api:"required"`
// Number of days until expiry, up to 3650. Use null for never.
DaysToExpire param.Opt[int64] `json:"days_to_expire,omitzero"`
diff --git a/authconnection.go b/authconnection.go
index f275e1f..08a383e 100644
--- a/authconnection.go
+++ b/authconnection.go
@@ -767,7 +767,9 @@ type ManagedAuthCreateRequestParam struct {
// - { provider, auto: true } for external provider domain lookup
Credential ManagedAuthCreateRequestCredentialParam `json:"credential,omitzero"`
// Proxy selection. Provide either id or name. The proxy must be in the same
- // project as the resource referencing it.
+ // project as the resource referencing it. When selecting by name, the name must
+ // match exactly one active proxy in the project. Ambiguous names return a 400; use
+ // id for stable references.
Proxy ManagedAuthCreateRequestProxyParam `json:"proxy,omitzero"`
paramObj
}
@@ -806,7 +808,9 @@ func (r *ManagedAuthCreateRequestCredentialParam) UnmarshalJSON(data []byte) err
}
// Proxy selection. Provide either id or name. The proxy must be in the same
-// project as the resource referencing it.
+// project as the resource referencing it. When selecting by name, the name must
+// match exactly one active proxy in the project. Ambiguous names return a 400; use
+// id for stable references.
type ManagedAuthCreateRequestProxyParam struct {
// Proxy ID
ID param.Opt[string] `json:"id,omitzero"`
@@ -969,7 +973,9 @@ type ManagedAuthUpdateRequestParam struct {
// - { provider, auto: true } for external provider domain lookup
Credential ManagedAuthUpdateRequestCredentialParam `json:"credential,omitzero"`
// Proxy selection. Provide either id or name. The proxy must be in the same
- // project as the resource referencing it.
+ // project as the resource referencing it. When selecting by name, the name must
+ // match exactly one active proxy in the project. Ambiguous names return a 400; use
+ // id for stable references.
Proxy ManagedAuthUpdateRequestProxyParam `json:"proxy,omitzero"`
paramObj
}
@@ -1008,7 +1014,9 @@ func (r *ManagedAuthUpdateRequestCredentialParam) UnmarshalJSON(data []byte) err
}
// Proxy selection. Provide either id or name. The proxy must be in the same
-// project as the resource referencing it.
+// project as the resource referencing it. When selecting by name, the name must
+// match exactly one active proxy in the project. Ambiguous names return a 400; use
+// id for stable references.
type ManagedAuthUpdateRequestProxyParam struct {
// Proxy ID
ID param.Opt[string] `json:"id,omitzero"`
@@ -1446,7 +1454,9 @@ type AuthConnectionLoginParams struct {
// When omitted, the connection's record_session default is used.
RecordSession param.Opt[bool] `json:"record_session,omitzero"`
// Proxy selection. Provide either id or name. The proxy must be in the same
- // project as the resource referencing it.
+ // project as the resource referencing it. When selecting by name, the name must
+ // match exactly one active proxy in the project. Ambiguous names return a 400; use
+ // id for stable references.
Proxy AuthConnectionLoginParamsProxy `json:"proxy,omitzero"`
paramObj
}
@@ -1460,7 +1470,9 @@ func (r *AuthConnectionLoginParams) UnmarshalJSON(data []byte) error {
}
// Proxy selection. Provide either id or name. The proxy must be in the same
-// project as the resource referencing it.
+// project as the resource referencing it. When selecting by name, the name must
+// match exactly one active proxy in the project. Ambiguous names return a 400; use
+// id for stable references.
type AuthConnectionLoginParamsProxy struct {
// Proxy ID
ID param.Opt[string] `json:"id,omitzero"`
diff --git a/browserpool.go b/browserpool.go
index 915987d..e8db785 100644
--- a/browserpool.go
+++ b/browserpool.go
@@ -619,7 +619,8 @@ type BrowserPoolListParams struct {
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Offset the number of browser pools to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
- // Search browser pools by name or ID.
+ // Case-insensitive substring match against browser pool name. IDs match by exact
+ // value.
Query param.Opt[string] `query:"query,omitzero" json:"-"`
paramObj
}
diff --git a/credential.go b/credential.go
index c8325e0..1f9cc34 100644
--- a/credential.go
+++ b/credential.go
@@ -288,7 +288,8 @@ type CredentialListParams struct {
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Number of results to skip
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
- // Search credentials by name, domain, or ID.
+ // Case-insensitive substring match against credential name or domain. IDs match by
+ // exact value.
Query param.Opt[string] `query:"query,omitzero" json:"-"`
paramObj
}
diff --git a/credentialprovider.go b/credentialprovider.go
index fc8b35c..77318a2 100644
--- a/credentialprovider.go
+++ b/credentialprovider.go
@@ -361,7 +361,8 @@ type CredentialProviderListParams struct {
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Offset the number of credential providers to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
- // Search credential providers by name or ID.
+ // Case-insensitive substring match against credential provider name. IDs match by
+ // exact value.
Query param.Opt[string] `query:"query,omitzero" json:"-"`
paramObj
}
diff --git a/extension.go b/extension.go
index 8bac50e..672a0c8 100644
--- a/extension.go
+++ b/extension.go
@@ -245,7 +245,8 @@ type ExtensionListParams struct {
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Offset the number of extensions to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
- // Search extensions by name or ID.
+ // Case-insensitive substring match against extension name. IDs match by exact
+ // value.
Query param.Opt[string] `query:"query,omitzero" json:"-"`
paramObj
}
diff --git a/profile.go b/profile.go
index 2e6e3cf..0248006 100644
--- a/profile.go
+++ b/profile.go
@@ -164,7 +164,7 @@ type ProfileListParams struct {
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Offset the number of profiles to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
- // Search profiles by name or ID.
+ // Case-insensitive substring match against profile name or ID.
Query param.Opt[string] `query:"query,omitzero" json:"-"`
paramObj
}
diff --git a/proxy.go b/proxy.go
index 037d47f..3655780 100644
--- a/proxy.go
+++ b/proxy.go
@@ -1793,7 +1793,8 @@ type ProxyListParams struct {
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Offset the number of proxies to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
- // Search proxies by name, host, IP address, or ID.
+ // Case-insensitive substring match against proxy name, host, or IP address. IDs
+ // match by exact value.
Query param.Opt[string] `query:"query,omitzero" json:"-"`
paramObj
}
From 6ffae2ffa5a381af12ff4776ac3d590ed1a724ef Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 10 Jul 2026 14:37:14 +0000
Subject: [PATCH 04/10] feat: Add exact-match name filter to list endpoints
---
.stats.yml | 4 ++--
apikey.go | 5 +++++
apikey_test.go | 1 +
browserpool.go | 5 +++++
browserpool_test.go | 1 +
extension.go | 5 +++++
extension_test.go | 1 +
profile.go | 5 +++++
profile_test.go | 1 +
project.go | 3 +++
project_test.go | 1 +
proxy.go | 4 ++++
proxy_test.go | 1 +
13 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index b058b75..f7ef7fe 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 127
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-6c7cbaefd8a84ec26a1677681f37041323290080dac3fd1a409bb7cd01dd2ae3.yml
-openapi_spec_hash: 75085a25c8a5cdb5417f0dbfad0ed6b6
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-b20fcf2fc1cdb91b51ffd354adcd12d63b950ea98b69e13bee6a78a58498c2cd.yml
+openapi_spec_hash: bc8b527a963dd2c2d74b6f9e6ca56652
config_hash: 77ee715aa17061166f9a02b264a21b8d
diff --git a/apikey.go b/apikey.go
index f215164..03179be 100644
--- a/apikey.go
+++ b/apikey.go
@@ -263,6 +263,11 @@ type APIKeyListParams struct {
IncludeDeleted param.Opt[bool] `query:"include_deleted,omitzero" json:"-"`
// Maximum number of results to return
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
+ // Exact-match filter on API key name using the database collation. In production,
+ // matching is case- and accent-insensitive. Names are not required to be unique,
+ // so multiple keys may match. When status=all or include_deleted=true is set,
+ // soft-deleted keys with the same name may also match.
+ Name param.Opt[string] `query:"name,omitzero" json:"-"`
// Number of results to skip
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
// Case-insensitive substring match against API key name, creator, and project. API
diff --git a/apikey_test.go b/apikey_test.go
index 24d41c6..cd8c963 100644
--- a/apikey_test.go
+++ b/apikey_test.go
@@ -114,6 +114,7 @@ func TestAPIKeyListWithOptionalParams(t *testing.T) {
_, err := client.APIKeys.List(context.TODO(), kernel.APIKeyListParams{
IncludeDeleted: kernel.Bool(true),
Limit: kernel.Int(100),
+ Name: kernel.String("name"),
Offset: kernel.Int(0),
Query: kernel.String("query"),
SortBy: kernel.APIKeyListParamsSortByCreatedAt,
diff --git a/browserpool.go b/browserpool.go
index e8db785..722b9ec 100644
--- a/browserpool.go
+++ b/browserpool.go
@@ -617,6 +617,11 @@ func (r *BrowserPoolUpdateParamsProfile) UnmarshalJSON(data []byte) error {
type BrowserPoolListParams struct {
// Limit the number of browser pools to return.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
+ // Exact-match filter on browser pool name using the database collation. In
+ // production, matching is case- and accent-insensitive. During the default-project
+ // migration, unscoped requests prefer a concrete default-project browser pool over
+ // a legacy unscoped browser pool with the same name.
+ Name param.Opt[string] `query:"name,omitzero" json:"-"`
// Offset the number of browser pools to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
// Case-insensitive substring match against browser pool name. IDs match by exact
diff --git a/browserpool_test.go b/browserpool_test.go
index d144597..2f4c0a5 100644
--- a/browserpool_test.go
+++ b/browserpool_test.go
@@ -157,6 +157,7 @@ func TestBrowserPoolListWithOptionalParams(t *testing.T) {
)
_, err := client.BrowserPools.List(context.TODO(), kernel.BrowserPoolListParams{
Limit: kernel.Int(1),
+ Name: kernel.String("name"),
Offset: kernel.Int(0),
Query: kernel.String("query"),
})
diff --git a/extension.go b/extension.go
index 672a0c8..3102cdd 100644
--- a/extension.go
+++ b/extension.go
@@ -243,6 +243,11 @@ func (r *ExtensionUploadResponse) UnmarshalJSON(data []byte) error {
type ExtensionListParams struct {
// Limit the number of extensions to return.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
+ // Exact-match filter on extension name using the database collation. In
+ // production, matching is case- and accent-insensitive. During the default-project
+ // migration, unscoped requests prefer a concrete default-project extension over a
+ // legacy unscoped extension with the same name.
+ Name param.Opt[string] `query:"name,omitzero" json:"-"`
// Offset the number of extensions to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
// Case-insensitive substring match against extension name. IDs match by exact
diff --git a/extension_test.go b/extension_test.go
index 1944009..dfebd5c 100644
--- a/extension_test.go
+++ b/extension_test.go
@@ -32,6 +32,7 @@ func TestExtensionListWithOptionalParams(t *testing.T) {
)
_, err := client.Extensions.List(context.TODO(), kernel.ExtensionListParams{
Limit: kernel.Int(1),
+ Name: kernel.String("name"),
Offset: kernel.Int(0),
Query: kernel.String("query"),
})
diff --git a/profile.go b/profile.go
index 0248006..54323c2 100644
--- a/profile.go
+++ b/profile.go
@@ -162,6 +162,11 @@ func (r *ProfileUpdateParams) UnmarshalJSON(data []byte) error {
type ProfileListParams struct {
// Limit the number of profiles to return.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
+ // Exact-match filter on profile name using the database collation. In production,
+ // matching is case- and accent-insensitive. During the default-project migration,
+ // unscoped requests prefer a concrete default-project profile over a legacy
+ // unscoped profile with the same name.
+ Name param.Opt[string] `query:"name,omitzero" json:"-"`
// Offset the number of profiles to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
// Case-insensitive substring match against profile name or ID.
diff --git a/profile_test.go b/profile_test.go
index 17b1a4c..842a085 100644
--- a/profile_test.go
+++ b/profile_test.go
@@ -109,6 +109,7 @@ func TestProfileListWithOptionalParams(t *testing.T) {
)
_, err := client.Profiles.List(context.TODO(), kernel.ProfileListParams{
Limit: kernel.Int(1),
+ Name: kernel.String("name"),
Offset: kernel.Int(0),
Query: kernel.String("query"),
})
diff --git a/project.go b/project.go
index e49aad5..7a41fb1 100644
--- a/project.go
+++ b/project.go
@@ -220,6 +220,9 @@ func (r *ProjectUpdateParams) UnmarshalJSON(data []byte) error {
type ProjectListParams struct {
// Maximum number of results to return
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
+ // Exact-match filter on project name using the database collation. In production,
+ // matching is case- and accent-insensitive.
+ Name param.Opt[string] `query:"name,omitzero" json:"-"`
// Number of results to skip
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
// Case-insensitive substring match against project name
diff --git a/project_test.go b/project_test.go
index a8fefba..b40819e 100644
--- a/project_test.go
+++ b/project_test.go
@@ -110,6 +110,7 @@ func TestProjectListWithOptionalParams(t *testing.T) {
)
_, err := client.Projects.List(context.TODO(), kernel.ProjectListParams{
Limit: kernel.Int(100),
+ Name: kernel.String("name"),
Offset: kernel.Int(0),
Query: kernel.String("query"),
})
diff --git a/proxy.go b/proxy.go
index 3655780..fdb2fbf 100644
--- a/proxy.go
+++ b/proxy.go
@@ -1791,6 +1791,10 @@ func (r *ProxyUpdateParams) UnmarshalJSON(data []byte) error {
type ProxyListParams struct {
// Limit the number of proxies to return.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
+ // Exact-match filter on proxy name using the database collation. In production,
+ // matching is case- and accent-insensitive. Names are not required to be unique,
+ // so multiple proxies may match.
+ Name param.Opt[string] `query:"name,omitzero" json:"-"`
// Offset the number of proxies to return.
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
// Case-insensitive substring match against proxy name, host, or IP address. IDs
diff --git a/proxy_test.go b/proxy_test.go
index 272bab1..1d9945d 100644
--- a/proxy_test.go
+++ b/proxy_test.go
@@ -113,6 +113,7 @@ func TestProxyListWithOptionalParams(t *testing.T) {
)
_, err := client.Proxies.List(context.TODO(), kernel.ProxyListParams{
Limit: kernel.Int(1),
+ Name: kernel.String("name"),
Offset: kernel.Int(0),
Query: kernel.String("query"),
})
From b1baff2db6ad583e8998e4ef6d3d711c73817492 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 10 Jul 2026 14:56:02 +0000
Subject: [PATCH 05/10] feat: Make the browser pool OpenAPI contract truthful
---
.stats.yml | 4 +--
browserpool.go | 80 +++++++++++++++++++++++++-------------------------
2 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index f7ef7fe..c403f2c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 127
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-b20fcf2fc1cdb91b51ffd354adcd12d63b950ea98b69e13bee6a78a58498c2cd.yml
-openapi_spec_hash: bc8b527a963dd2c2d74b6f9e6ca56652
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-d7ab1ecb886cb7f86e7ce0926207db423a6650e8e12e7283a71f8682fbb472ae.yml
+openapi_spec_hash: 9323b0ba38d2d50b8506be4d7401c04d
config_hash: 77ee715aa17061166f9a02b264a21b8d
diff --git a/browserpool.go b/browserpool.go
index 722b9ec..4784fd1 100644
--- a/browserpool.go
+++ b/browserpool.go
@@ -206,22 +206,22 @@ func (r *BrowserPool) UnmarshalJSON(data []byte) error {
// Configuration used to create all browsers in this pool
type BrowserPoolBrowserPoolConfig struct {
- // Number of browsers to maintain in the pool. The maximum size is determined by
+ // Number of browsers maintained in the pool. The maximum size is determined by
// your organization's pooled sessions limit (the sum of all pool sizes cannot
// exceed your limit).
Size int64 `json:"size" api:"required"`
// Custom Chrome enterprise policy overrides applied to all browsers in this pool.
// Keys are Chrome enterprise policy names; values must match their expected types.
// Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
- // https://chromeenterprise.google/policies/
+ // https://chromeenterprise.google/policies/ The serialized JSON payload is capped
+ // at 5 MiB.
ChromePolicy map[string]any `json:"chrome_policy"`
// List of browser extensions to load into the session. Provide each by id or name.
Extensions []shared.BrowserExtension `json:"extensions"`
- // Percentage of the pool to fill per minute. Defaults to 10. The cap is 25 for
- // most organizations but can be raised per-organization, so only the lower bound
- // is enforced here.
+ // Percentage of the pool to fill per minute. The cap is 25 for most organizations
+ // but can be raised per-organization, so only the lower bound is enforced here.
FillRatePerMinute int64 `json:"fill_rate_per_minute"`
- // If true, launches the browser using a headless image. Defaults to false.
+ // If true, launches the browser using a headless image.
Headless bool `json:"headless"`
// If true, launches the browser in kiosk mode to hide address bar and tabs in live
// view.
@@ -234,8 +234,8 @@ type BrowserPoolBrowserPoolConfig struct {
// omitted here. Any save_changes value sent on a pool profile is silently ignored
// rather than rejected.
Profile BrowserPoolBrowserPoolConfigProfile `json:"profile"`
- // Optional proxy to associate to the browser session. Must reference a proxy in
- // the same project as the browser session.
+ // Optional proxy associated to the browser session. References a proxy in the same
+ // project as the browser session.
ProxyID string `json:"proxy_id"`
// When true, flush idle browsers when the profile the pool uses is updated, so
// pool browsers pick up the latest profile data. Requires a profile to be set on
@@ -251,7 +251,7 @@ type BrowserPoolBrowserPoolConfig struct {
// mechanisms.
Stealth bool `json:"stealth"`
// Default idle timeout in seconds for browsers acquired from this pool before they
- // are destroyed. Defaults to 600 seconds. Minimum 10, maximum 259200 (72 hours).
+ // are destroyed. Minimum 10, maximum 259200 (72 hours).
TimeoutSeconds int64 `json:"timeout_seconds"`
// Initial browser window size in pixels with optional refresh rate. If omitted,
// image defaults apply (1920x1080@25). For GPU images, the default is
@@ -431,7 +431,7 @@ type BrowserPoolNewParams struct {
// If true, launches the browser using a headless image. Defaults to false.
Headless param.Opt[bool] `json:"headless,omitzero"`
// If true, launches the browser in kiosk mode to hide address bar and tabs in live
- // view.
+ // view. Defaults to false.
KioskMode param.Opt[bool] `json:"kiosk_mode,omitzero"`
// Optional name for the browser pool. Must be unique within the project.
Name param.Opt[string] `json:"name,omitzero"`
@@ -449,7 +449,7 @@ type BrowserPoolNewParams struct {
// chrome:// pages.
StartURL param.Opt[string] `json:"start_url,omitzero"`
// If true, launches the browser in stealth mode to reduce detection by anti-bot
- // mechanisms.
+ // mechanisms. Defaults to false.
Stealth param.Opt[bool] `json:"stealth,omitzero"`
// Default idle timeout in seconds for browsers acquired from this pool before they
// are destroyed. Defaults to 600 seconds. Minimum 10, maximum 259200 (72 hours).
@@ -457,7 +457,8 @@ type BrowserPoolNewParams struct {
// Custom Chrome enterprise policy overrides applied to all browsers in this pool.
// Keys are Chrome enterprise policy names; values must match their expected types.
// Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
- // https://chromeenterprise.google/policies/
+ // https://chromeenterprise.google/policies/ The serialized JSON payload is capped
+ // at 5 MiB.
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"`
@@ -521,46 +522,45 @@ type BrowserPoolUpdateParams struct {
// pool with that stale configuration until it is discarded (by this flag on a
// later update, or by flushing the pool).
DiscardAllIdle param.Opt[bool] `json:"discard_all_idle,omitzero"`
- // Percentage of the pool to fill per minute. Defaults to 10. The cap is 25 for
- // most organizations but can be raised per-organization, so only the lower bound
- // is enforced here.
+ // If provided, replaces the percentage of the pool to fill per minute. The cap is
+ // 25 for most organizations but can be raised per-organization, so only the lower
+ // bound is enforced here.
FillRatePerMinute param.Opt[int64] `json:"fill_rate_per_minute,omitzero"`
- // If true, launches the browser using a headless image. Defaults to false.
+ // If provided, replaces whether browsers launch using a headless image.
Headless param.Opt[bool] `json:"headless,omitzero"`
- // If true, launches the browser in kiosk mode to hide address bar and tabs in live
- // view.
+ // If provided, replaces whether browsers launch in kiosk mode.
KioskMode param.Opt[bool] `json:"kiosk_mode,omitzero"`
- // Optional name for the browser pool. Must be unique within the project.
+ // If provided, replaces the pool name. Empty string is a no-op; the pool name
+ // cannot be cleared or reset to empty once assigned.
Name param.Opt[string] `json:"name,omitzero"`
- // Optional proxy to associate to the browser session. Must reference a proxy in
- // the same project as the browser session.
+ // Empty string clears the previously-selected proxy. Omit this field to leave the
+ // proxy unchanged.
ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
- // When true, flush idle browsers when the profile the pool uses is updated, so
- // pool browsers pick up the latest profile data. Requires a profile to be set on
- // the pool.
+ // If provided, replaces whether idle browsers are flushed when the profile the
+ // pool uses is updated. Requires a profile to be set on the pool.
RefreshOnProfileUpdate param.Opt[bool] `json:"refresh_on_profile_update,omitzero"`
- // Number of browsers to maintain in the pool. The maximum size is determined by
- // your organization's pooled sessions limit (the sum of all pool sizes cannot
- // exceed your limit).
+ // If provided, replaces the number of browsers to maintain in the pool. The
+ // maximum size is determined by your organization's pooled sessions limit (the sum
+ // of all pool sizes cannot exceed your limit).
Size param.Opt[int64] `json:"size,omitzero"`
- // Optional URL to navigate to when a new browser is warmed into the pool.
- // Best-effort: failures to navigate do not fail pool fill. Only applied to
- // newly-warmed browsers; browsers reused via release/acquire keep whatever URL the
- // previous lease left them on. Accepts any URL Chromium can resolve, including
- // chrome:// pages.
+ // If provided, replaces the URL to navigate to when a new browser is warmed into
+ // the pool. Empty string clears the previously-set URL. Omit this field to leave
+ // it unchanged.
StartURL param.Opt[string] `json:"start_url,omitzero"`
- // If true, launches the browser in stealth mode to reduce detection by anti-bot
- // mechanisms.
+ // If provided, replaces whether browsers launch in stealth mode.
Stealth param.Opt[bool] `json:"stealth,omitzero"`
- // Default idle timeout in seconds for browsers acquired from this pool before they
- // are destroyed. Defaults to 600 seconds. Minimum 10, maximum 259200 (72 hours).
+ // If provided, replaces the default idle timeout in seconds for browsers acquired
+ // from this pool before they are destroyed. Minimum 10, maximum 259200 (72 hours).
TimeoutSeconds param.Opt[int64] `json:"timeout_seconds,omitzero"`
- // Custom Chrome enterprise policy overrides applied to all browsers in this pool.
- // Keys are Chrome enterprise policy names; values must match their expected types.
+ // If provided, replaces the custom Chrome enterprise policy overrides applied to
+ // all browsers in this pool. Empty object clears any previously-set policy. Keys
+ // are Chrome enterprise policy names; values must match their expected types.
// Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See
- // https://chromeenterprise.google/policies/
+ // https://chromeenterprise.google/policies/ The serialized JSON payload is capped
+ // at 5 MiB.
ChromePolicy map[string]any `json:"chrome_policy,omitzero"`
- // List of browser extensions to load into the session. Provide each by id or name.
+ // If provided, replaces the extension list. Empty array clears all
+ // previously-selected extensions. Omit this field to leave extensions unchanged.
Extensions []shared.BrowserExtensionParam `json:"extensions,omitzero"`
// Profile configuration for browsers in a pool. Provide either id or name.
// Profiles must be created beforehand. Unlike single browser sessions, pools load
From a09849ac32a842675babeefdf32d136e18a9d812 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 10 Jul 2026 15:32:35 +0000
Subject: [PATCH 06/10] feat: Persist and echo deployment source identity
---
.stats.yml | 4 +-
deployment.go | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c403f2c..f6f6182 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 127
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-d7ab1ecb886cb7f86e7ce0926207db423a6650e8e12e7283a71f8682fbb472ae.yml
-openapi_spec_hash: 9323b0ba38d2d50b8506be4d7401c04d
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-d61b5e5ca18ce30a6b4d05483bcd67969ce0f4aee2e9e8c379be4f22f1362b01.yml
+openapi_spec_hash: 23121d1c1552e41177b472c4c39d154e
config_hash: 77ee715aa17061166f9a02b264a21b8d
diff --git a/deployment.go b/deployment.go
index 3675b23..d00a5d8 100644
--- a/deployment.go
+++ b/deployment.go
@@ -167,6 +167,26 @@ type DeploymentStateEventDeployment struct {
// API key, OAuth, and managed-auth callers, which receive every key with an empty
// string value. Only dashboard sessions receive the actual values.
EnvVars map[string]string `json:"env_vars"`
+ // Hex-encoded SHA-256 checksum of the source archive. For file uploads, this
+ // hashes the uploaded archive; for GitHub-sourced deployments, this hashes the
+ // GitHub archive downloaded by the API. Omitted for deployments created before
+ // this field was recorded.
+ SourceChecksum string `json:"source_checksum"`
+ // For GitHub-sourced deployments, the subpath within the repository that was used
+ // as the deploy root. Omitted when the repo root was used or for file uploads.
+ SourcePath string `json:"source_path"`
+ // For GitHub-sourced deployments, the git ref as requested at deploy time (branch,
+ // tag, or commit SHA — not resolved to a commit). Omitted for file uploads.
+ SourceRef string `json:"source_ref"`
+ // Origin of the deployed source code. This is read-only response provenance;
+ // `file` indicates an uploaded archive and `github` indicates a repository fetched
+ // by the API.
+ //
+ // Any of "file", "github".
+ SourceType string `json:"source_type"`
+ // For GitHub-sourced deployments, the repository URL that was fetched. Omitted for
+ // file uploads.
+ SourceURL string `json:"source_url"`
// Status reason
StatusReason string `json:"status_reason"`
// Timestamp when the deployment was last updated
@@ -179,6 +199,11 @@ type DeploymentStateEventDeployment struct {
Status respjson.Field
EntrypointRelPath respjson.Field
EnvVars respjson.Field
+ SourceChecksum respjson.Field
+ SourcePath respjson.Field
+ SourceRef respjson.Field
+ SourceType respjson.Field
+ SourceURL respjson.Field
StatusReason respjson.Field
UpdatedAt respjson.Field
ExtraFields map[string]respjson.Field
@@ -210,6 +235,26 @@ type DeploymentNewResponse struct {
// API key, OAuth, and managed-auth callers, which receive every key with an empty
// string value. Only dashboard sessions receive the actual values.
EnvVars map[string]string `json:"env_vars"`
+ // Hex-encoded SHA-256 checksum of the source archive. For file uploads, this
+ // hashes the uploaded archive; for GitHub-sourced deployments, this hashes the
+ // GitHub archive downloaded by the API. Omitted for deployments created before
+ // this field was recorded.
+ SourceChecksum string `json:"source_checksum"`
+ // For GitHub-sourced deployments, the subpath within the repository that was used
+ // as the deploy root. Omitted when the repo root was used or for file uploads.
+ SourcePath string `json:"source_path"`
+ // For GitHub-sourced deployments, the git ref as requested at deploy time (branch,
+ // tag, or commit SHA — not resolved to a commit). Omitted for file uploads.
+ SourceRef string `json:"source_ref"`
+ // Origin of the deployed source code. This is read-only response provenance;
+ // `file` indicates an uploaded archive and `github` indicates a repository fetched
+ // by the API.
+ //
+ // Any of "file", "github".
+ SourceType DeploymentNewResponseSourceType `json:"source_type"`
+ // For GitHub-sourced deployments, the repository URL that was fetched. Omitted for
+ // file uploads.
+ SourceURL string `json:"source_url"`
// Status reason
StatusReason string `json:"status_reason"`
// Timestamp when the deployment was last updated
@@ -222,6 +267,11 @@ type DeploymentNewResponse struct {
Status respjson.Field
EntrypointRelPath respjson.Field
EnvVars respjson.Field
+ SourceChecksum respjson.Field
+ SourcePath respjson.Field
+ SourceRef respjson.Field
+ SourceType respjson.Field
+ SourceURL respjson.Field
StatusReason respjson.Field
UpdatedAt respjson.Field
ExtraFields map[string]respjson.Field
@@ -246,6 +296,16 @@ const (
DeploymentNewResponseStatusStopped DeploymentNewResponseStatus = "stopped"
)
+// Origin of the deployed source code. This is read-only response provenance;
+// `file` indicates an uploaded archive and `github` indicates a repository fetched
+// by the API.
+type DeploymentNewResponseSourceType string
+
+const (
+ DeploymentNewResponseSourceTypeFile DeploymentNewResponseSourceType = "file"
+ DeploymentNewResponseSourceTypeGitHub DeploymentNewResponseSourceType = "github"
+)
+
// Deployment record information.
type DeploymentGetResponse struct {
// Unique identifier for the deployment
@@ -264,6 +324,26 @@ type DeploymentGetResponse struct {
// API key, OAuth, and managed-auth callers, which receive every key with an empty
// string value. Only dashboard sessions receive the actual values.
EnvVars map[string]string `json:"env_vars"`
+ // Hex-encoded SHA-256 checksum of the source archive. For file uploads, this
+ // hashes the uploaded archive; for GitHub-sourced deployments, this hashes the
+ // GitHub archive downloaded by the API. Omitted for deployments created before
+ // this field was recorded.
+ SourceChecksum string `json:"source_checksum"`
+ // For GitHub-sourced deployments, the subpath within the repository that was used
+ // as the deploy root. Omitted when the repo root was used or for file uploads.
+ SourcePath string `json:"source_path"`
+ // For GitHub-sourced deployments, the git ref as requested at deploy time (branch,
+ // tag, or commit SHA — not resolved to a commit). Omitted for file uploads.
+ SourceRef string `json:"source_ref"`
+ // Origin of the deployed source code. This is read-only response provenance;
+ // `file` indicates an uploaded archive and `github` indicates a repository fetched
+ // by the API.
+ //
+ // Any of "file", "github".
+ SourceType DeploymentGetResponseSourceType `json:"source_type"`
+ // For GitHub-sourced deployments, the repository URL that was fetched. Omitted for
+ // file uploads.
+ SourceURL string `json:"source_url"`
// Status reason
StatusReason string `json:"status_reason"`
// Timestamp when the deployment was last updated
@@ -276,6 +356,11 @@ type DeploymentGetResponse struct {
Status respjson.Field
EntrypointRelPath respjson.Field
EnvVars respjson.Field
+ SourceChecksum respjson.Field
+ SourcePath respjson.Field
+ SourceRef respjson.Field
+ SourceType respjson.Field
+ SourceURL respjson.Field
StatusReason respjson.Field
UpdatedAt respjson.Field
ExtraFields map[string]respjson.Field
@@ -300,6 +385,16 @@ const (
DeploymentGetResponseStatusStopped DeploymentGetResponseStatus = "stopped"
)
+// Origin of the deployed source code. This is read-only response provenance;
+// `file` indicates an uploaded archive and `github` indicates a repository fetched
+// by the API.
+type DeploymentGetResponseSourceType string
+
+const (
+ DeploymentGetResponseSourceTypeFile DeploymentGetResponseSourceType = "file"
+ DeploymentGetResponseSourceTypeGitHub DeploymentGetResponseSourceType = "github"
+)
+
// Deployment record information.
type DeploymentListResponse struct {
// Unique identifier for the deployment
@@ -318,6 +413,26 @@ type DeploymentListResponse struct {
// API key, OAuth, and managed-auth callers, which receive every key with an empty
// string value. Only dashboard sessions receive the actual values.
EnvVars map[string]string `json:"env_vars"`
+ // Hex-encoded SHA-256 checksum of the source archive. For file uploads, this
+ // hashes the uploaded archive; for GitHub-sourced deployments, this hashes the
+ // GitHub archive downloaded by the API. Omitted for deployments created before
+ // this field was recorded.
+ SourceChecksum string `json:"source_checksum"`
+ // For GitHub-sourced deployments, the subpath within the repository that was used
+ // as the deploy root. Omitted when the repo root was used or for file uploads.
+ SourcePath string `json:"source_path"`
+ // For GitHub-sourced deployments, the git ref as requested at deploy time (branch,
+ // tag, or commit SHA — not resolved to a commit). Omitted for file uploads.
+ SourceRef string `json:"source_ref"`
+ // Origin of the deployed source code. This is read-only response provenance;
+ // `file` indicates an uploaded archive and `github` indicates a repository fetched
+ // by the API.
+ //
+ // Any of "file", "github".
+ SourceType DeploymentListResponseSourceType `json:"source_type"`
+ // For GitHub-sourced deployments, the repository URL that was fetched. Omitted for
+ // file uploads.
+ SourceURL string `json:"source_url"`
// Status reason
StatusReason string `json:"status_reason"`
// Timestamp when the deployment was last updated
@@ -330,6 +445,11 @@ type DeploymentListResponse struct {
Status respjson.Field
EntrypointRelPath respjson.Field
EnvVars respjson.Field
+ SourceChecksum respjson.Field
+ SourcePath respjson.Field
+ SourceRef respjson.Field
+ SourceType respjson.Field
+ SourceURL respjson.Field
StatusReason respjson.Field
UpdatedAt respjson.Field
ExtraFields map[string]respjson.Field
@@ -354,6 +474,16 @@ const (
DeploymentListResponseStatusStopped DeploymentListResponseStatus = "stopped"
)
+// Origin of the deployed source code. This is read-only response provenance;
+// `file` indicates an uploaded archive and `github` indicates a repository fetched
+// by the API.
+type DeploymentListResponseSourceType string
+
+const (
+ DeploymentListResponseSourceTypeFile DeploymentListResponseSourceType = "file"
+ DeploymentListResponseSourceTypeGitHub DeploymentListResponseSourceType = "github"
+)
+
// DeploymentFollowResponseUnion contains all possible properties and values from
// [shared.LogEvent], [DeploymentStateEvent],
// [DeploymentFollowResponseAppVersionSummaryEvent], [shared.ErrorEvent],
From fe39910f8d4822e41e4c7e6efac14aff52cc9c39 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 10 Jul 2026 15:59:32 +0000
Subject: [PATCH 07/10] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index f6f6182..38aa69b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 127
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-d61b5e5ca18ce30a6b4d05483bcd67969ce0f4aee2e9e8c379be4f22f1362b01.yml
-openapi_spec_hash: 23121d1c1552e41177b472c4c39d154e
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-9143bc729ef60beffa0bbd9b601bb095083e41e23c8994553e69302f586882f5.yml
+openapi_spec_hash: bd04c530cfa8188af0e63a784129645d
config_hash: 77ee715aa17061166f9a02b264a21b8d
From b74cae1d226293704baefb943c213c77b83b409b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 10 Jul 2026 19:28:56 +0000
Subject: [PATCH 08/10] feat: Auto-default refresh_on_profile_update when
browser pool profile changes
---
.stats.yml | 4 ++--
browserpool.go | 13 ++++++++-----
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 38aa69b..5882e06 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 127
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-9143bc729ef60beffa0bbd9b601bb095083e41e23c8994553e69302f586882f5.yml
-openapi_spec_hash: bd04c530cfa8188af0e63a784129645d
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-25b48b79d356843aeda41e5e5c3c407c5bd5c12f9548500ffc0a6696e6acd941.yml
+openapi_spec_hash: f710169690ab7aca30c91968e752cff7
config_hash: 77ee715aa17061166f9a02b264a21b8d
diff --git a/browserpool.go b/browserpool.go
index 4784fd1..1f63f3f 100644
--- a/browserpool.go
+++ b/browserpool.go
@@ -238,8 +238,8 @@ type BrowserPoolBrowserPoolConfig struct {
// project as the browser session.
ProxyID string `json:"proxy_id"`
// When true, flush idle browsers when the profile the pool uses is updated, so
- // pool browsers pick up the latest profile data. Requires a profile to be set on
- // the pool.
+ // pool browsers pick up the latest profile data. When a profile is provided during
+ // creation, this defaults to true. Requires a profile to be set on the pool.
RefreshOnProfileUpdate bool `json:"refresh_on_profile_update"`
// Optional URL to navigate to when a new browser is warmed into the pool.
// Best-effort: failures to navigate do not fail pool fill. Only applied to
@@ -439,8 +439,8 @@ type BrowserPoolNewParams struct {
// the same project as the browser session.
ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
// When true, flush idle browsers when the profile the pool uses is updated, so
- // pool browsers pick up the latest profile data. Requires a profile to be set on
- // the pool.
+ // pool browsers pick up the latest profile data. When a profile is provided during
+ // creation, this defaults to true. Requires a profile to be set on the pool.
RefreshOnProfileUpdate param.Opt[bool] `json:"refresh_on_profile_update,omitzero"`
// Optional URL to navigate to when a new browser is warmed into the pool.
// Best-effort: failures to navigate do not fail pool fill. Only applied to
@@ -537,7 +537,10 @@ type BrowserPoolUpdateParams struct {
// proxy unchanged.
ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
// If provided, replaces whether idle browsers are flushed when the profile the
- // pool uses is updated. Requires a profile to be set on the pool.
+ // pool uses is updated. When the pool's profile reference is changed (including
+ // newly attached) and this field is omitted, it defaults to true. Re-sending the
+ // same profile reference leaves this setting unchanged. Clearing the profile also
+ // disables this setting. Requires a profile to be set on the pool.
RefreshOnProfileUpdate param.Opt[bool] `json:"refresh_on_profile_update,omitzero"`
// If provided, replaces the number of browsers to maintain in the pool. The
// maximum size is determined by your organization's pooled sessions limit (the sum
From de83d75e14f7f819f6c6982a7c9833d7a3f45721 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 13 Jul 2026 15:43:38 +0000
Subject: [PATCH 09/10] feat: Support multiple audit log method exclusions
---
.stats.yml | 4 ++--
auditlog.go | 8 ++++----
auditlog_test.go | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 5882e06..a855b9c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 127
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-25b48b79d356843aeda41e5e5c3c407c5bd5c12f9548500ffc0a6696e6acd941.yml
-openapi_spec_hash: f710169690ab7aca30c91968e752cff7
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-f0003e336fc8dc54d9cac4728c847fb80c32d50a9165738c5b70aa83a09bb0f5.yml
+openapi_spec_hash: a2099eec27728b1cfd9032dc71b9bb57
config_hash: 77ee715aa17061166f9a02b264a21b8d
diff --git a/auditlog.go b/auditlog.go
index e487a18..9096e7c 100644
--- a/auditlog.go
+++ b/auditlog.go
@@ -132,8 +132,6 @@ type AuditLogListParams struct {
Start time.Time `query:"start" api:"required" format:"date-time" json:"-"`
// Filter by authentication strategy.
AuthStrategy param.Opt[string] `query:"auth_strategy,omitzero" json:"-"`
- // Filter out results by HTTP method.
- ExcludeMethod param.Opt[string] `query:"exclude_method,omitzero" json:"-"`
// Maximum number of results to return.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Filter by HTTP method.
@@ -144,6 +142,8 @@ type AuditLogListParams struct {
Search param.Opt[string] `query:"search,omitzero" json:"-"`
// Filter by service name.
Service param.Opt[string] `query:"service,omitzero" json:"-"`
+ // Filter out results by HTTP method.
+ ExcludeMethod []string `query:"exclude_method,omitzero" json:"-"`
// Additional user IDs to OR into free-text search.
SearchUserID []string `query:"search_user_id,omitzero" json:"-"`
paramObj
@@ -166,8 +166,6 @@ type AuditLogExportChunkParams struct {
AuthStrategy param.Opt[string] `query:"auth_strategy,omitzero" json:"-"`
// Opaque cursor from X-Next-Cursor for the next chunk of older records.
Cursor param.Opt[string] `query:"cursor,omitzero" json:"-"`
- // Filter out results by HTTP method.
- ExcludeMethod param.Opt[string] `query:"exclude_method,omitzero" json:"-"`
// Maximum number of records to return in this chunk.
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Filter by HTTP method.
@@ -176,6 +174,8 @@ type AuditLogExportChunkParams struct {
Search param.Opt[string] `query:"search,omitzero" json:"-"`
// Filter by service name.
Service param.Opt[string] `query:"service,omitzero" json:"-"`
+ // Filter out results by HTTP method.
+ ExcludeMethod []string `query:"exclude_method,omitzero" json:"-"`
// Encoding for the returned chunk.
//
// Any of "jsonl", "jsonl.gz".
diff --git a/auditlog_test.go b/auditlog_test.go
index a849751..49e1cd2 100644
--- a/auditlog_test.go
+++ b/auditlog_test.go
@@ -35,7 +35,7 @@ func TestAuditLogListWithOptionalParams(t *testing.T) {
End: time.Now(),
Start: time.Now(),
AuthStrategy: kernel.String("auth_strategy"),
- ExcludeMethod: kernel.String("exclude_method"),
+ ExcludeMethod: []string{"string"},
Limit: kernel.Int(1),
Method: kernel.String("method"),
PageToken: kernel.String("page_token"),
@@ -68,7 +68,7 @@ func TestAuditLogExportChunkWithOptionalParams(t *testing.T) {
Start: time.Now(),
AuthStrategy: kernel.String("auth_strategy"),
Cursor: kernel.String("cursor"),
- ExcludeMethod: kernel.String("exclude_method"),
+ ExcludeMethod: []string{"string"},
Format: kernel.AuditLogExportChunkParamsFormatJSONL,
Limit: kernel.Int(1),
Method: kernel.String("method"),
From fbfb965f7a56305351d77806445c52130205f0f9 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 13 Jul 2026 15:44:08 +0000
Subject: [PATCH 10/10] release: 0.77.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 19 +++++++++++++++++++
README.md | 2 +-
internal/version.go | 2 +-
4 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index aa39267..5c03edc 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.76.0"
+ ".": "0.77.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 239a503..f30dfde 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,24 @@
# Changelog
+## 0.77.0 (2026-07-13)
+
+Full Changelog: [v0.76.0...v0.77.0](https://github.com/kernel/kernel-go-sdk/compare/v0.76.0...v0.77.0)
+
+### Features
+
+* Add exact-match name filter to list endpoints ([6ffae2f](https://github.com/kernel/kernel-go-sdk/commit/6ffae2ffa5a381af12ff4776ac3d590ed1a724ef))
+* Add name-only rename for profiles and proxies ([c2b2b5e](https://github.com/kernel/kernel-go-sdk/commit/c2b2b5e5cf318b2d6c9e964b65274f8de4a57a35))
+* Auto-default refresh_on_profile_update when browser pool profile changes ([b74cae1](https://github.com/kernel/kernel-go-sdk/commit/b74cae1d226293704baefb943c213c77b83b409b))
+* Document name uniqueness and query match semantics ([fd4fcff](https://github.com/kernel/kernel-go-sdk/commit/fd4fcffa2ad8d35878a189a1a66e9e8aac2df872))
+* Make the browser pool OpenAPI contract truthful ([b1baff2](https://github.com/kernel/kernel-go-sdk/commit/b1baff2db6ad583e8998e4ef6d3d711c73817492))
+* Persist and echo deployment source identity ([a09849a](https://github.com/kernel/kernel-go-sdk/commit/a09849ac32a842675babeefdf32d136e18a9d812))
+* Support multiple audit log method exclusions ([de83d75](https://github.com/kernel/kernel-go-sdk/commit/de83d75e14f7f819f6c6982a7c9833d7a3f45721))
+
+
+### Documentation
+
+* **openapi:** describe unified concurrency limit, deprecate max_pooled_sessions (CUS-275) ([edcc0e5](https://github.com/kernel/kernel-go-sdk/commit/edcc0e5e25cbce705d36a316b146a6eda30dc4fb))
+
## 0.76.0 (2026-07-09)
Full Changelog: [v0.75.0...v0.76.0](https://github.com/kernel/kernel-go-sdk/compare/v0.75.0...v0.76.0)
diff --git a/README.md b/README.md
index 7e5f139..08388b5 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.76.0'
+go get -u 'github.com/kernel/kernel-go-sdk@v0.77.0'
```
diff --git a/internal/version.go b/internal/version.go
index b3372db..7dfcf69 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "0.76.0" // x-release-please-version
+const PackageVersion = "0.77.0" // x-release-please-version