browserlayer / docsPrivate alphaDashboard ↗
Build integrationsMarkdown

Steps and connector flows

Use steps to record work. Use child flows to compose resumable website operations.

Return data from a step

ts
const title = await ctx.step("read-title", async () => {
  const page = await ctx.browser();
  return page.title();
});

After an input pause, execution starts again at the beginning. A completed step returns its recorded result without rerunning the callback.

Put inside a stepKeep outside
Browser actions, requests, reading saved dataDeterministic mapping and validation
Time and random values used by later workCalls to ctx.run, ctx.input, ctx.publish

Return plain JSON: strings, numbers, booleans, null, arrays and objects. Represent dates as strings. Do not assign results to an outer variable from inside the callback.

Call a connector flow

ts
import listBookings from "../connector/flows/list-bookings.js";

// Inside exec(ctx):
const bookings = await ctx.run(listBookings, {});

Only createFlow connector operations can be called with ctx.run. Endpoints and syncs are entry points, not callable child flows.

The child shares the run, browser and connection. If it requests MFA, the whole run waits. Studio shows the endpoint or sync above its internal flows and steps.

Use stable step names. Repeated names in a sequential loop get separate recorded occurrences automatically. Await durable operations sequentially; do not nest them inside a step callback.

Interrupted actions

SituationOutcome
Completed step, then input pauseCompleted result is reused
Worker lost during an external actionACTION_UNCERTAIN; inspect the website before retrying
Retained browser session lostSESSION_LOST
Local daemon crashesActive local runs fail with LOCAL_SERVICE_INTERRUPTED

Durable execution does not make arbitrary website mutations exactly once.