browserlayer / docsPrivate alphaDashboard ↗

Start here

Websites → endpoints and syncsInstallRun your first endpointAtlas walkthrough

Build integrations

Project structureCapture a websiteBuild with your coding agentEndpointsSteps and connector flowsTyped referencesAuthenticationUser input and MFABrowser interactions and HTTPSync recordsCheckpoints and deletionsTest an integrationDebug in Studio

Use in your app

Connect accounts with hosted LinkCall an endpointConsume sync recordsReceive webhooks

Deploy

Deploy and verify

Reference

SDK referenceHTTP APICLI reference
Build integrationsMarkdown

Browser interactions and HTTP

Use Playwright for controls and ctx.http for requests made by the website.

Interact with the page

ts
await ctx.step("open-bookings", async () => {
  const page = await ctx.browser();
  await page.getByRole("link", { name: "Bookings" }).click();
  await page.getByRole("heading", { name: "Your bookings" }).waitFor();
});

Read JSON through the browser

ts
const bookings = await ctx.step("read-bookings", async () => {
  const response = await ctx.http.get("/api/bookings");
  if (response.status !== 200) {
    throw new FlowError("BOOKINGS_UNAVAILABLE", "Could not read bookings");
  }
  return Booking.array().parse(JSON.parse(response.body));
});

Import FlowError from @browserlayer/sdk and your Booking schema. Navigate to the website before making relative requests.

Response fieldType
urlstring
statusnumber
headersstring map
bodystring; parse JSON explicitly

Requests run inside the page with its cookies and origin restrictions. HTTP error statuses are returned normally. Transport failures throw BROWSER_REQUEST_FAILED. There are no automatic request retries.

Submit a request

ts
await ctx.step("submit", () =>
  ctx.http.request("/api/preferences", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ language: "en" }),
    timeoutMs: 20_000,
  }),
);

Observe after an action

ts
await ctx.observe(
  "confirmation",
  async () => {
    const page = await ctx.browser();
    if (await page.getByText("Preferences saved").isVisible()) return true;
    return undefined;
  },
  { timeoutMs: 20_000 },
);

Observation polls without repeating the preceding action. Keep it read-only. Timeout throws OBSERVATION_TIMEOUT.

← User input and MFASync records →
On this pageInteract with the pageRead JSON through the browserSubmit a requestObserve after an action