Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.49.0"
".": "0.50.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 111
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-49a1a92e00d1eb87e91e8527275cb0705fce2edea30e70fea745f134dd451fbd.yml
openapi_spec_hash: 0ffef6a95f9d9b1096180fc5e4c5b39c
config_hash: 9818dd634f87b677410eefd013d7a179
configured_endpoints: 112
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-686a9addd4f9356ca26ff3ff04e1a11466d77a412859829075566394922b715d.yml
openapi_spec_hash: 7a9e9c2023400d44bcbfb87b7ec07708
config_hash: 08d55086449943a8fec212b870061a3f
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 0.50.0 (2026-04-20)

Full Changelog: [v0.49.0...v0.50.0](https://github.com/kernel/kernel-go-sdk/compare/v0.49.0...v0.50.0)

### Features

* add POST /browsers/{id}/curl and /curl/raw endpoints ([94b52ae](https://github.com/kernel/kernel-go-sdk/commit/94b52aeac38b20c8ea60e3c016443e0ccc680451))
* remove paid plan gating from project endpoints ([f3cbeb3](https://github.com/kernel/kernel-go-sdk/commit/f3cbeb32ca629fefbadaf5449acd0d7aa438e4c5))


### Bug Fixes

* include MFA and sign-in options in CUA SSO-only step response ([45db2eb](https://github.com/kernel/kernel-go-sdk/commit/45db2ebc96e4d6fbeec34cc43ed13ad4d0bd7de2))

## 0.49.0 (2026-04-10)

Full Changelog: [v0.48.0...v0.49.0](https://github.com/kernel/kernel-go-sdk/compare/v0.48.0...v0.49.0)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->

```sh
go get -u 'github.com/kernel/kernel-go-sdk@v0.49.0'
go get -u 'github.com/kernel/kernel-go-sdk@v0.50.0'
```

<!-- x-release-please-end -->
Expand Down
2 changes: 2 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Response Types:
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserGetResponse">BrowserGetResponse</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserUpdateResponse">BrowserUpdateResponse</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserListResponse">BrowserListResponse</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserCurlResponse">BrowserCurlResponse</a>

Methods:

Expand All @@ -90,6 +91,7 @@ Methods:
- <code title="patch /browsers/{id}">client.Browsers.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserService.Update">Update</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserUpdateParams">BrowserUpdateParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserUpdateResponse">BrowserUpdateResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /browsers">client.Browsers.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserListParams">BrowserListParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk/packages/pagination">pagination</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk/packages/pagination#OffsetPagination">OffsetPagination</a>[<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserListResponse">BrowserListResponse</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="delete /browsers">client.Browsers.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserDeleteParams">BrowserDeleteParams</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>
- <code title="post /browsers/{id}/curl">client.Browsers.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserService.Curl">Curl</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserCurlParams">BrowserCurlParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserCurlResponse">BrowserCurlResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="delete /browsers/{id}">client.Browsers.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserService.DeleteByID">DeleteByID</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>
- <code title="post /browsers/{id}/extensions">client.Browsers.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserService.LoadExtensions">LoadExtensions</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserLoadExtensionsParams">BrowserLoadExtensionsParams</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>

Expand Down
8 changes: 8 additions & 0 deletions authconnection.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,9 @@ type ManagedAuthDiscoveredField struct {
//
// Any of "text", "email", "password", "tel", "number", "url", "code", "totp".
Type string `json:"type" api:"required"`
// Contextual help text near the field that tells the user what to enter (e.g.,
// "Enter the phone ending in (**_) _**-\*\*92")
Hint string `json:"hint"`
// If this field is associated with an MFA option, the type of that option (e.g.,
// password field linked to "Enter password" option)
//
Expand All @@ -420,6 +423,7 @@ type ManagedAuthDiscoveredField struct {
Name respjson.Field
Selector respjson.Field
Type respjson.Field
Hint respjson.Field
LinkedMfaType respjson.Field
Placeholder respjson.Field
Required respjson.Field
Expand Down Expand Up @@ -963,6 +967,9 @@ type AuthConnectionFollowResponseManagedAuthStateDiscoveredField struct {
//
// Any of "text", "email", "password", "tel", "number", "url", "code", "totp".
Type string `json:"type" api:"required"`
// Contextual help text near the field that tells the user what to enter (e.g.,
// "Enter the phone ending in (**_) _**-\*\*92")
Hint string `json:"hint"`
// If this field is associated with an MFA option, the type of that option (e.g.,
// password field linked to "Enter password" option)
//
Expand All @@ -978,6 +985,7 @@ type AuthConnectionFollowResponseManagedAuthStateDiscoveredField struct {
Name respjson.Field
Selector respjson.Field
Type respjson.Field
Hint respjson.Field
LinkedMfaType respjson.Field
Placeholder respjson.Field
Required respjson.Field
Expand Down
90 changes: 90 additions & 0 deletions browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,20 @@ func (r *BrowserService) Delete(ctx context.Context, body BrowserDeleteParams, o
return err
}

// Sends an HTTP request through Chrome's HTTP request stack, inheriting the
// browser's TLS fingerprint, cookies, proxy configuration, and headers. Returns a
// structured JSON response with status, headers, body, and timing.
func (r *BrowserService) Curl(ctx context.Context, id string, body BrowserCurlParams, opts ...option.RequestOption) (res *BrowserCurlResponse, err error) {
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
return nil, err
}
path := fmt.Sprintf("browsers/%s/curl", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
return res, err
}

// Delete a browser session by ID
func (r *BrowserService) DeleteByID(ctx context.Context, id string, opts ...option.RequestOption) (err error) {
opts = slices.Concat(r.Options, opts)
Expand Down Expand Up @@ -609,6 +623,33 @@ func (r *BrowserListResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Structured response from the browser curl request.
type BrowserCurlResponse struct {
// Response body (UTF-8 string or base64 depending on request).
Body string `json:"body" api:"required"`
// Total request duration in milliseconds.
DurationMs int64 `json:"duration_ms" api:"required"`
// Response headers (multi-value).
Headers map[string][]string `json:"headers" api:"required"`
// HTTP status code from target.
Status int64 `json:"status" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Body respjson.Field
DurationMs respjson.Field
Headers respjson.Field
Status respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}

// Returns the unmodified JSON received from the API
func (r BrowserCurlResponse) RawJSON() string { return r.JSON.raw }
func (r *BrowserCurlResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

type BrowserNewParams struct {
// If true, enables GPU acceleration for the browser session. Requires Start-Up or
// Enterprise plan and headless=false.
Expand Down Expand Up @@ -770,6 +811,55 @@ func (r BrowserDeleteParams) URLQuery() (v url.Values, err error) {
})
}

type BrowserCurlParams struct {
// Target URL (must be http or https).
URL string `json:"url" api:"required"`
// Request body (for POST/PUT/PATCH).
Body param.Opt[string] `json:"body,omitzero"`
// Request timeout in milliseconds.
TimeoutMs param.Opt[int64] `json:"timeout_ms,omitzero"`
// Custom headers merged with browser defaults.
Headers map[string]string `json:"headers,omitzero"`
// HTTP method.
//
// Any of "GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS".
Method BrowserCurlParamsMethod `json:"method,omitzero"`
// Encoding for the response body. Use base64 for binary content.
//
// Any of "utf8", "base64".
ResponseEncoding BrowserCurlParamsResponseEncoding `json:"response_encoding,omitzero"`
paramObj
}

func (r BrowserCurlParams) MarshalJSON() (data []byte, err error) {
type shadow BrowserCurlParams
return param.MarshalObject(r, (*shadow)(&r))
}
func (r *BrowserCurlParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// HTTP method.
type BrowserCurlParamsMethod string

const (
BrowserCurlParamsMethodGet BrowserCurlParamsMethod = "GET"
BrowserCurlParamsMethodHead BrowserCurlParamsMethod = "HEAD"
BrowserCurlParamsMethodPost BrowserCurlParamsMethod = "POST"
BrowserCurlParamsMethodPut BrowserCurlParamsMethod = "PUT"
BrowserCurlParamsMethodPatch BrowserCurlParamsMethod = "PATCH"
BrowserCurlParamsMethodDelete BrowserCurlParamsMethod = "DELETE"
BrowserCurlParamsMethodOptions BrowserCurlParamsMethod = "OPTIONS"
)

// Encoding for the response body. Use base64 for binary content.
type BrowserCurlParamsResponseEncoding string

const (
BrowserCurlParamsResponseEncodingUtf8 BrowserCurlParamsResponseEncoding = "utf8"
BrowserCurlParamsResponseEncodingBase64 BrowserCurlParamsResponseEncoding = "base64"
)

type BrowserLoadExtensionsParams struct {
// List of extensions to upload and activate
Extensions []BrowserLoadExtensionsParamsExtension `json:"extensions,omitzero" api:"required"`
Expand Down
36 changes: 36 additions & 0 deletions browser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,42 @@ func TestBrowserDelete(t *testing.T) {
}
}

func TestBrowserCurlWithOptionalParams(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.Browsers.Curl(
context.TODO(),
"id",
kernel.BrowserCurlParams{
URL: "url",
Body: kernel.String("body"),
Headers: map[string]string{
"foo": "string",
},
Method: kernel.BrowserCurlParamsMethodGet,
ResponseEncoding: kernel.BrowserCurlParamsResponseEncodingUtf8,
TimeoutMs: kernel.Int(1000),
},
)
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 TestBrowserDeleteByID(t *testing.T) {
t.Skip("Mock server tests are disabled")
baseURL := "http://localhost:4010"
Expand Down
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

package internal

const PackageVersion = "0.49.0" // x-release-please-version
const PackageVersion = "0.50.0" // x-release-please-version
4 changes: 2 additions & 2 deletions project.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func NewProjectService(opts ...option.RequestOption) (r ProjectService) {
return
}

// Create a new project within the authenticated organization. Requires a paid plan
// and the projects feature flag.
// Create a new project within the authenticated organization. Requires the
// projects feature flag.
func (r *ProjectService) New(ctx context.Context, body ProjectNewParams, opts ...option.RequestOption) (res *Project, err error) {
opts = slices.Concat(r.Options, opts)
path := "projects"
Expand Down
Loading