Skip to main content
Functions are currently only available in the us-west-2 region.

Defining Functions

Basic Function

import { defineFn } from "@browserbasehq/sdk-functions";
import { chromium } from "playwright-core";

defineFn("function-name", async (ctx, params) => {
  const browser = await chromium.connectOverCDP(ctx.session.connectUrl);
  const context = browser.contexts()[0];
  const page = context?.pages()[0];

  // Your automation code here

  return { result: "your data" };
});

Function parameters

  • Function name - Unique identifier for your Function (used in the “invoke function” HTTP request)
  • Handler - Async function that receives:
    • ctx - Context object with session information
    • params - Parameters passed when invoking the Function
  • Options - Optional configuration object for session settings
Make sure that you give each Function in your codebase a unique name! Function names are unique per project. The name parameter serves as a Function’s “Logical ID” (a unique, human-friendly identifier), meaning reusing a name string could lead to overwriting an existing built Function with the same name.

Context object

The ctx parameter provides access to the browser session:
{
  session: {
    connectUrl: string;  // CDP connection URL
    id: string;          // Session ID
  }
}

Function response

Return any JSON-serializable data from your Function:
return {
  success: true,
  data: { ... },
  message: "Operation complete"
};

Session configuration

Configure browser session settings using the third parameter:
defineFn(
  "verified-function",
  async (ctx, params) => {
    // Your function code
  },
  {
    sessionConfig: {
      browserSettings: {
        verified: true,
        solveCaptchas: true,
      },
      proxies: true,
    },
  }
);

Available options

Functions are currently only available in the us-west-2 region.
Most session creation options are supported:

Complete example

Here’s a full example that fills out a contact form:
import { defineFn } from "@browserbasehq/sdk-functions";
import { chromium } from "playwright-core";

defineFn(
  "fill-contact-form",
  async (ctx, params) => {
    const browser = await chromium.connectOverCDP(ctx.session.connectUrl);
    const context = browser.contexts()[0];
    const page = context?.pages()[0];

    if (!page) {
      console.error("Failed to create a page");
      return { error: "No page available" };
    }

    try {
      // Navigate to the contact page
      await page.goto("https://www.browserbase.com/contact");

      // Fill out the form
      await page.locator("#firstName").fill("Browser");
      await page.locator("#lastName").fill("Functions");
      await page.locator("#email-label").fill("demo@browserbase.com");
      await page.locator("#jobTitle-label").fill("Professional robot");
      await page.locator("#companyName-label").fill("Browserbase");

      // Select an option from dropdown
      await page.locator("button#helpOption").click();
      await page.locator("#helpOption-demo").click();

      return {
        success: true,
        message: "Form filled successfully"
      };
    } catch (error: unknown) {
      console.error("Error filling form:", error);
      return {
        error: "Failed to fill form",
        details: String(error)
      };
    }
  },
  {
    sessionConfig: {
      browserSettings: {
        verified: true,
      },
    },
  }
);

Publishing Functions

Multiple Functions (single file)

Define multiple Functions in a single file:
index.ts
import { defineFn } from "@browserbasehq/sdk-functions";
import { chromium } from "playwright-core";

// Function 1: Screenshot
defineFn("take-screenshot", async (ctx, params) => {
  const browser = await chromium.connectOverCDP(ctx.session.connectUrl);
  const page = browser.contexts()[0]?.pages()[0];

  await page.goto(params.url);
  const screenshot = await page.screenshot({ encoding: "base64" });

  return { screenshot };
});

// Function 2: Extract Text
defineFn("extract-text", async (ctx, params) => {
  const browser = await chromium.connectOverCDP(ctx.session.connectUrl);
  const page = browser.contexts()[0]?.pages()[0];

  await page.goto(params.url);
  const text = await page.textContent(params.selector);

  return { text };
});
Both Functions will be deployed when you run pnpm bb publish index.ts.

Multiple Functions (multiple files)

Define multiple Functions in multiple files:
index.ts
import { defineFn } from "@browserbasehq/sdk-functions";
import { chromium } from "playwright-core";

import "screenshot-fn.ts"
// Import any other files that contain `defineFn` calls in the same way

// Function 1: Screenshot
defineFn("take-screenshot", async (ctx, params) => {
  const browser = await chromium.connectOverCDP(ctx.session.connectUrl);
  const page = browser.contexts()[0]?.pages()[0];

  await page.goto(params.url);
  const screenshot = await page.screenshot({ encoding: "base64" });

  return { screenshot };
});
screenshot-fn.ts
import { defineFn } from "@browserbasehq/sdk-functions";
import { chromium } from "playwright-core";

// Function 2: Extract Text
defineFn("extract-text", async (ctx, params) => {
  const browser = await chromium.connectOverCDP(ctx.session.connectUrl);
  const page = browser.contexts()[0]?.pages()[0];

  await page.goto(params.url);
  const text = await page.textContent(params.selector);

  return { text };
});
Both Functions will be deployed when you run pnpm bb publish index.ts.

Invoke a Function

Get build result

Retrieve information about the Function(s) built or updated by a build:
curl https://api.browserbase.com/v1/functions/builds/BUILD_ID \
  -H "x-bb-api-key: $BB_API_KEY"
This returns Function ID(s) needed for invocation.

Pass parameters to Functions

Access parameters in your Function handler:
defineFn("parameterized-function", async (ctx, params) => {
  const { url, searchTerm } = params;

  // Use parameters in your automation
  await page.goto(url);
  await page.fill("#search", searchTerm);

  return { searched: searchTerm };
});
Invoke with parameters:
curl -X POST https://api.browserbase.com/v1/functions/FUNCTION_ID/invoke \
  -H "Content-Type: application/json" \
  -H "x-bb-api-key: $BB_API_KEY" \
  -d '{
    "params": {
      "url": "https://example.com",
      "searchTerm": "browser automation"
    }
  }'

Override session settings at invocation time

The sessionConfig you set in defineFn applies to every invocation as the default, but you can override most session settings per invocation by passing sessionCreateParams in the invoke request body. The runtime deep-merges your invocation-time fields over the deploy-time defaults: values you pass at invoke win, and any deploy-time fields you don’t override still apply. This is useful when you want a single deployed Function to accept a different browser context, proxy configuration, or user metadata per call:
curl -X POST https://api.browserbase.com/v1/functions/FUNCTION_ID/invoke \
  -H "Content-Type: application/json" \
  -H "x-bb-api-key: $BB_API_KEY" \
  -d '{
    "params": { "url": "https://example.com" },
    "sessionCreateParams": {
      "browserSettings": {
        "context": {
          "id": "YOUR_CONTEXT_ID",
          "persist": true
        }
      }
    }
  }'
Most fields on sessionCreateParams mirror the body of Create a SessionbrowserSettings, proxies, extensionId, userMetadata, and so on. You can’t configure region or keepAlive per invocation. Functions accept timeout, but cap it between 60 and 900 seconds (15 minutes) and default it to 900. See Invoke a Function for the full schema.

Best practices

Error handling

Browserbase runners catch unhandled errors and report them. If you want to gracefully handle errors (for example, return information on the failure), wrap your automation code in try-catch blocks:
defineFn("safe-function", async (ctx, params) => {
  try {
    const browser = await chromium.connectOverCDP(ctx.session.connectUrl);
    const page = browser.contexts()[0]?.pages()[0];

    // Your automation code

    return { success: true };
  } catch (error) {
    console.error("Function error:", error);
    return {
      success: false,
      error: String(error)
    };
  }
});

Timeouts

Set appropriate timeouts for navigation and actions when using Playwright:
await page.goto(url, { timeout: 30000 });
await page.waitForSelector("#element", { timeout: 10000 });

Logging

Use console methods for debugging - logs are captured and available in invocation logs:
console.log("Starting navigation to:", url);
console.warn("Potential issue detected:", warning);
console.error("Critical error:", error);

Session cleanup

Browser sessions automatically close when your Function completes. No manual cleanup is required.

Monitoring and debugging

Every Function invocation creates a browser session that you can inspect as with any other Browserbase session:
  1. Session recordings - View the Function execution in the Session Inspector
  2. Console logs - See all logged messages during execution
  3. Network activity - Inspect HTTP requests and responses
  4. Performance metrics - Monitor execution time and resource usage

Session recordings

Learn how to debug Functions using session recordings

Secrets

Secrets management for Functions environments is coming soon! This will allow you to securely store and access sensitive values like API keys, tokens, and credentials within your deployed Functions without passing them as parameters.
Availability: Support for Secrets is a top priority on the current roadmap. This feature isn’t yet available in beta; contact support@browserbase.com to get on the waitlist and stay tuned for the latest updates.

Next steps

Session configuration

Learn about all available session configuration options

Verified

Configure browser identity for your functions

Browser contexts

Persist authentication and session state

API reference

Complete Browserbase API documentation