# Recording product UI # 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](https://playwright.dev/docs/selectors): 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. ```json { "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 - Public `http(s)` URLs only; private and internal network addresses are refused. - Up to 60 steps and 300 seconds of recording. - Pages that need a login, or that sit on `localhost`, are not reachable yet. Record those yourself and upload the file as a clip. - Only record sites you own or have permission to film.