second studioDocs llms.txtGet started

Recording product UI

POST /v1/recordings (MCP: record_url) opens a public web page in a real browser and films it while following your steps. You describe what to do; Second Studio makes it watchable: a visible cursor that travels to each target, typing at human speed, scrolling in smooth flicks rather than jumps, and a pause after every action. It never ends on an action: the last frame holds.

Steps

Step Fields Does
goto url Navigate to another public URL
click selector, timeout? Move the cursor to the element and click it
hover selector Move the cursor onto the element
type selector, text, delay_ms? (default 85) Click the field and type, key by key
press key (e.g. Enter, Tab) Press a key
scroll pixels (negative scrolls up) Scroll in smooth flicks
wait_for selector, timeout? (s) Wait until the element is visible
hold seconds Hold still so viewers can read

Every step also accepts after (seconds to pause afterwards, default 0.4) and mark (a name for this moment in result.marks). Selectors use Playwright syntax: CSS (#buy, [data-testid=save]) or text (text=Get started).

Without steps, the recording settles on the page, scrolls through it and returns to the top.

{
  "url": "https://example.com",
  "viewport": "mobile",
  "steps": [
    { "type": "hold", "seconds": 2, "mark": "landing" },
    { "type": "click", "selector": "text=Search" },
    { "type": "type", "selector": "input[name=q]", "text": "chicken dinner" },
    { "type": "press", "key": "Enter" },
    { "type": "wait_for", "selector": ".results" },
    { "type": "hold", "seconds": 3, "mark": "results" }
  ]
}

Options

field
viewport desktop 1280×800 (default), laptop 1440×900, hd 1920×1080, mobile 390×844
scale 2 records at 2× device pixels (a 3840×2160 file for hd): crisp text when the edit zooms in
typingDelayMs Per-character typing delay, default 85 (set delay_ms on a step to override)

Steps gained: goto takes wait_for (a selector to wait for on the new page, so a transition is never a frozen or black frame. Otherwise it waits for network idle); network_idle waits for the page to settle; click, hover and type take glide (seconds the cursor travels, default 0.5) and settle (pause before the click, default 0.3). The cursor shows a click ripple.

Every mark for a click, hover or type carries box: the element's bounding box as fractions of the frame (x, y, w, h), so an editor can zoom and draw callouts on exact coordinates.

Viewports

viewport Size
desktop (default) 1280 × 800
mobile 390 × 844 at 2× pixel density, touch enabled

Output

A recording asset (mp4, 30 fps) and result.marks: [{ "name": "landing", "t": 2.41 }, …]. The time of every step, for cutting on the action rather than in the middle of it. Use the recording as a clip in an edit like any other footage.

Limits and rules

Recording a private repository

POST /v1/repo-recordings (MCP: record_repo) builds your app from a GitHub repository in an isolated, throwaway sandbox, starts it with a local database, and records its key flows. Nothing from the build leaves the sandbox except the videos and a redacted build log.

1. Connect GitHub (once, admin)

In the portal open GitHub and logins and press Connect GitHub, or call POST /v1/github/install (MCP: connect_github) and open the url it returns. Pick the repositories to share. The app asks for read-only access to code and metadata. Each recording gets its own key, scoped to one repository, that expires within an hour. GET /v1/github lists linked installations; DELETE /v1/github/installations/{id} unlinks one (uninstall the app on GitHub to remove our access entirely).

If GitHub is not switched on for the service yet, these calls return 503 github_not_configured.

2. Optional: env sets and logins (admin)

Recordings that use an env set, a login or a session need an admin key. Values are encrypted at rest (versioned keys) and never returned: lists show names, variable names and a masked user name. They are decrypted only for the worker, once per run, and scrubbed from build logs, progress and errors. Deleting an env set or login, or disconnecting GitHub, cancels and refunds queued recordings that use it. Adding, changing, deleting and using them is written to the audit log on governed accounts.

3. Record

{ "repo": "acme/web", "ref": "main", "envSetId": "...", "loginId": "...", "maxFlows": 3,
  "flows": [ { "title": "Create a project", "steps": [
    { "type": "goto", "url": "/projects" }, { "type": "cap", "text": "Start a project in one click" },
    { "type": "click", "selector": "text=New project" } ] } ] }
Field
repo owner/name, required
ref branch, tag or commit; default branch if omitted
subdir the app's directory in a monorepo, like apps/web (relative, no ..); repo root if omitted
installationId only when the account has more than one GitHub installation
mode auto (default) or real; both build and run your real app today. mock (a faked backend) is not supported yet and is rejected with 400 invalid_field
flows up to 5 {title, steps}; steps as above plus cap {text} for a caption. goto takes a path like /settings
maxFlows 1 to 5 (default 3). Without flows, we plan this many from the code and README
viewport, scale as for POST /v1/recordings

Price: 20 credits for up to 3 flows, 4 credits per extra flow (max 5), and 3 more when the run signs in with a saved login, an OTP or a storage_state. That is quoted up front (input.quote). The first 25 sandbox minutes (install, build and recording) are included; after that it is 5 credits per started 10 minutes, charged at completion (result.overtimeCredits). The sandbox stops at 45 minutes, so overtime adds at most 10 credits. The result has sandboxSeconds (what overtime is based on), flows: [{ flow, storageId, marks }], buildLog (secrets and tokens removed) and modeUsed.

If the build, start-up or recording fails on our side (build_failed, start_failed, flow_failed), the credits are refunded. bad_repo (nothing we can build or run, for example not a supported web app) is not refunded. Supported first: Node frontends (Next.js, Vite) with Postgres or SQLite through Prisma or Drizzle, signing in with a seeded user, a saved login, or a signed-in session.

Agents: this page is also available as Markdown; the whole reference is in llms-full.txt.