diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 7a48e52..d18e944 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "2.12.0"
+ ".": "2.13.0"
}
diff --git a/.stats.yml b/.stats.yml
index f40d116..17cb18b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 23
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase/browserbase-b2831c9c836f039762834825afdc20569587a825d29ac5c3748c78b009bf059b.yml
-openapi_spec_hash: dd85a934900cb6583f12ebf6117be884
-config_hash: 40fbac80e24faaa0dc19e93368bcd821
+configured_endpoints: 27
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase/browserbase-9bab373fc62ce19147560ed3ec29fe09ad59d9a5b406d9ed21a22f15a511d9cb.yml
+openapi_spec_hash: 518fdefff1eabc4bb8a3b54ddf7fa293
+config_hash: d4b0c534eaf7665ea25168e0e824c9d3
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 460a81b..230c535 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 2.13.0 (2026-06-05)
+
+Full Changelog: [v2.12.0...v2.13.0](https://github.com/browserbase/sdk-node/compare/v2.12.0...v2.13.0)
+
+### Features
+
+* [CORE-2194][apps/api] Add BYOC (cert) CRUD to SDKs ([06b3a85](https://github.com/browserbase/sdk-node/commit/06b3a850b9e8955a7770ecdb43cd0820480b7c5f))
+
## 2.12.0 (2026-05-20)
Full Changelog: [v2.11.0...v2.12.0](https://github.com/browserbase/sdk-node/compare/v2.11.0...v2.12.0)
diff --git a/README.md b/README.md
index 2a98f47..e767652 100644
--- a/README.md
+++ b/README.md
@@ -64,17 +64,17 @@ import Browserbase, { toFile } from '@browserbasehq/sdk';
const client = new Browserbase();
// If you have access to Node `fs` we recommend using `fs.createReadStream()`:
-await client.extensions.create({ file: fs.createReadStream('/path/to/file') });
+await client.certificates.create({ file: fs.createReadStream('/path/to/file') });
// Or if you have the web `File` API you can pass a `File` instance:
-await client.extensions.create({ file: new File(['my bytes'], 'file') });
+await client.certificates.create({ file: new File(['my bytes'], 'file') });
// You can also pass a `fetch` `Response`:
-await client.extensions.create({ file: await fetch('https://somesite/file') });
+await client.certificates.create({ file: await fetch('https://somesite/file') });
// Finally, if none of the above are convenient, you can use our `toFile` helper:
-await client.extensions.create({ file: await toFile(Buffer.from('my bytes'), 'file') });
-await client.extensions.create({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });
+await client.certificates.create({ file: await toFile(Buffer.from('my bytes'), 'file') });
+await client.certificates.create({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });
```
## Handling errors
diff --git a/api.md b/api.md
index 11f9afd..04af9b4 100644
--- a/api.md
+++ b/api.md
@@ -1,3 +1,17 @@
+# Certificates
+
+Types:
+
+- Certificate
+- CertificateListResponse
+
+Methods:
+
+- client.certificates.create({ ...params }) -> Certificate
+- client.certificates.retrieve(id) -> Certificate
+- client.certificates.list() -> CertificateListResponse
+- client.certificates.delete(id) -> void
+
# Contexts
Types:
diff --git a/package-lock.json b/package-lock.json
index 1298b90..519523a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@browserbasehq/sdk",
- "version": "2.12.0",
+ "version": "2.13.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@browserbasehq/sdk",
- "version": "2.12.0",
+ "version": "2.13.0",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
diff --git a/package.json b/package.json
index c303732..bfaaf83 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@browserbasehq/sdk",
- "version": "2.12.0",
+ "version": "2.13.0",
"description": "The official Node.js library for the Browserbase API",
"author": "Browserbase ",
"types": "dist/index.d.ts",
diff --git a/src/index.ts b/src/index.ts
index 19c7fb5..68d3aee 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -5,6 +5,12 @@ import * as Core from './core';
import * as Errors from './error';
import * as Uploads from './uploads';
import * as API from './resources/index';
+import {
+ Certificate,
+ CertificateCreateParams,
+ CertificateListResponse,
+ Certificates,
+} from './resources/certificates';
import {
Context,
ContextCreateParams,
@@ -156,6 +162,7 @@ export class Browserbase extends Core.APIClient {
this.apiKey = apiKey;
}
+ certificates: API.Certificates = new API.Certificates(this);
contexts: API.Contexts = new API.Contexts(this);
extensions: API.Extensions = new API.Extensions(this);
fetchAPI: API.FetchAPI = new API.FetchAPI(this);
@@ -206,6 +213,7 @@ export class Browserbase extends Core.APIClient {
static fileFromPath = Uploads.fileFromPath;
}
+Browserbase.Certificates = Certificates;
Browserbase.Contexts = Contexts;
Browserbase.Extensions = Extensions;
Browserbase.FetchAPI = FetchAPI;
@@ -216,6 +224,13 @@ Browserbase.Sessions = Sessions;
export declare namespace Browserbase {
export type RequestOptions = Core.RequestOptions;
+ export {
+ Certificates as Certificates,
+ type Certificate as Certificate,
+ type CertificateListResponse as CertificateListResponse,
+ type CertificateCreateParams as CertificateCreateParams,
+ };
+
export {
Contexts as Contexts,
type Context as Context,
diff --git a/src/resources/certificates.ts b/src/resources/certificates.ts
new file mode 100644
index 0000000..5f6413f
--- /dev/null
+++ b/src/resources/certificates.ts
@@ -0,0 +1,64 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../resource';
+import * as Core from '../core';
+
+export class Certificates extends APIResource {
+ /**
+ * Upload a Certificate
+ */
+ create(body: CertificateCreateParams, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.post('/v1/certificates', Core.multipartFormRequestOptions({ body, ...options }));
+ }
+
+ /**
+ * Get a Certificate
+ */
+ retrieve(id: string, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.get(`/v1/certificates/${id}`, options);
+ }
+
+ /**
+ * List Certificates
+ */
+ list(options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.get('/v1/certificates', options);
+ }
+
+ /**
+ * Delete a Certificate
+ */
+ delete(id: string, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.delete(`/v1/certificates/${id}`, {
+ ...options,
+ headers: { Accept: '*/*', ...options?.headers },
+ });
+ }
+}
+
+export interface Certificate {
+ id: string;
+
+ createdAt: string;
+
+ /**
+ * The Project ID linked to the uploaded Certificate.
+ */
+ projectId: string;
+
+ updatedAt: string;
+}
+
+export type CertificateListResponse = Array;
+
+export interface CertificateCreateParams {
+ file: Core.Uploadable;
+}
+
+export declare namespace Certificates {
+ export {
+ type Certificate as Certificate,
+ type CertificateListResponse as CertificateListResponse,
+ type CertificateCreateParams as CertificateCreateParams,
+ };
+}
diff --git a/src/resources/index.ts b/src/resources/index.ts
index f1ec403..7192b67 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -1,5 +1,11 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+export {
+ Certificates,
+ type Certificate,
+ type CertificateListResponse,
+ type CertificateCreateParams,
+} from './certificates';
export {
Contexts,
type Context,
diff --git a/src/version.ts b/src/version.ts
index e06ef68..31707fe 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '2.12.0'; // x-release-please-version
+export const VERSION = '2.13.0'; // x-release-please-version
diff --git a/tests/api-resources/certificates.test.ts b/tests/api-resources/certificates.test.ts
new file mode 100644
index 0000000..f795a51
--- /dev/null
+++ b/tests/api-resources/certificates.test.ts
@@ -0,0 +1,84 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Browserbase, { toFile } from '@browserbasehq/sdk';
+import { Response } from 'node-fetch';
+
+const client = new Browserbase({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource certificates', () => {
+ test('create: only required params', async () => {
+ const responsePromise = client.certificates.create({
+ file: await toFile(Buffer.from('Example data'), 'README.md'),
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('create: required and optional params', async () => {
+ const response = await client.certificates.create({
+ file: await toFile(Buffer.from('Example data'), 'README.md'),
+ });
+ });
+
+ test('retrieve', async () => {
+ const responsePromise = client.certificates.retrieve('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('retrieve: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.certificates.retrieve('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Browserbase.NotFoundError,
+ );
+ });
+
+ test('list', async () => {
+ const responsePromise = client.certificates.list();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('list: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.certificates.list({ path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Browserbase.NotFoundError,
+ );
+ });
+
+ test('delete', async () => {
+ const responsePromise = client.certificates.delete('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('delete: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.certificates.delete('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Browserbase.NotFoundError,
+ );
+ });
+});