Session Recording
Capture a terminal session as a timestamped stream of events, replay it inside TermFlow, or export it to JSON, plain text, HTML, or an asciinema cast for sharing and archiving.
Session recording is driven by TermFlow's local Recordings API and paired with an in-app playback viewer. A recording captures the terminal's output (and, optionally, your keystrokes and resize events) as events tagged with a millisecond offset from when recording started, so playback reproduces the session at its original pace — or faster, or slower.
An honest note: Session recording is part of TermFlow 0.1.0's early-access release. The Recordings API, all four export formats, and the playback viewer described on this page are implemented and working today; expect the capture and export pipeline to keep evolving as TermFlow moves past pre-release.
How it works
Each recording is a self-contained document: an ordered list of events, plus metadata (title, detected shell, and the terminal's initial size in columns and rows). Recordings persist as JSON files on disk — one file per recording — inside TermFlow's application data folder, so they survive restarts and are listed back to you the next time you open the app.
Like every TermFlow endpoint, the recordings API is unauthenticated on localhost because it is bound to 127.0.0.1. If you turn on "Expose on local network," the routes require the bearer token from Settings → Connections. See Local API and auth.
Recording a terminal
Start a recording against a terminal id. The terminal must already exist; TermFlow reads its current size to seed the recording's metadata.
POST /api/recordings/start
Content-Type: application/json
{
"terminal_id": "term-1a2b",
"options": {
"include_output": true,
"include_input": true,
"include_resize": true,
"compression": "gzip",
"auto_stop": false
}
}
A successful start returns 201 Created:
{ "recordingId": "b3f1…", "terminalId": "term-1a2b", "status": "recording" }
The options object is optional — omit it to accept the defaults below.
| Option | Type | Default | Effect |
|---|---|---|---|
include_output | bool | true | Capture terminal output |
include_input | bool | true | Capture your keystrokes |
include_resize | bool | true | Capture resize events |
compression | string | "gzip" | "none" or "gzip"; recorded in the file's metadata |
auto_stop | bool | false | Auto-stop flag (leave off) |
Stop the recording by its recording id (not the terminal id). TermFlow stamps the end time, writes the file to disk, and reports the final size and event count:
POST /api/recordings/stop/b3f1…
{ "recordingId": "b3f1…", "status": "stopped", "size": 20480, "eventCount": 512 }
A terminal has at most one active recording at a time. Use GET /api/recordings/status/:terminalId to check whether a terminal is currently recording, and GET /api/recordings/active to list every recording in progress.
Exporting a recording
Export converts a saved recording into a portable file. Send the desired format to the export endpoint; TermFlow responds with the file as a download (Content-Disposition: attachment).
POST /api/recordings/b3f1…/export
Content-Type: application/json
{ "format": "asciinema" }
# Export a recording to an asciinema cast file
curl -X POST http://127.0.0.1:42031/api/recordings/b3f1…/export \
-H "Content-Type: application/json" \
-d '{"format":"asciinema"}' \
-o session.cast
format | Content type | What you get |
|---|---|---|
json | application/json | The complete recording — every event (output, input, resize), all timestamps, and metadata. Lossless; ideal for re-importing or programmatic analysis. |
text | text/plain | A plain-text dump of the output events, preceded by a short header comment (id, terminal, start/end, event count). Raw bytes, so ANSI escape sequences are preserved as-is. |
html | text/html | A standalone, dark-themed HTML page containing the captured output — open it in any browser, no server required. |
asciinema | application/json | An asciinema v2 cast (a header line plus one JSON line per output event), downloaded as a .cast file. Play it with the asciinema player or upload it to asciinema.org. |
The in-app recordings list offers one-click Export as JSON / Text / HTML; the asciinema format is available through the API. An unrecognized format value returns 400 Bad Request.
Playing back a recording
Open a saved recording in the playback viewer to replay it in a read-only terminal. The viewer renders the recorded output at its original timing (input is disabled during playback), with transport controls and a scrubber.
┌─ Recording: my-session ───────────────────────── [✕] ┐
│ Terminal: term-1a2b Duration: 84s Events: 512 │
├───────────────────────────────────────────────────────┤
│ │
│ (the recorded session replays here, read-only) │
│ │
├───────────────────────────────────────────────────────┤
│ ⏮ ▶ / ⏸ ⏹ ⏭ 0:12 ── ──●────────── 1:24 │
│ Speed [ 1.0x ▾ ] ☐ Loop │
├───────────────────────────────────────────────────────┤
│ Space Play/Pause Esc Stop Shift+←/→ Step Home/End│
└───────────────────────────────────────────────────────┘
Playback speed is adjustable from 0.25× to 4× (0.25, 0.5, 1, 1.5, 2, 3, 4), and a Loop toggle restarts the recording when it reaches the end. Click or drag the progress bar to seek to any point.
Keyboard shortcuts
| Key | Action |
|---|---|
Space | Play / pause |
Esc | Stop (reset to the start) |
Shift+← | Step to the previous recorded event |
Shift+→ | Step to the next recorded event |
Home | Jump to the start |
End | Jump to the end |
Automate with the Recordings API
Everything above — start, stop, list, inspect, export, delete — is exposed as plain HTTP, so you can script recording around builds, test runs, or agent sessions.
| Method & path | Purpose |
|---|---|
POST /api/recordings/start | Begin recording a terminal |
POST /api/recordings/stop/:id | Stop and save a recording |
GET /api/recordings | List saved recordings |
GET /api/recordings/:id | Fetch a full recording (JSON) |
GET /api/recordings/:id/info | Fetch metadata only (duration, counts) |
DELETE /api/recordings/:id | Delete a recording |
POST /api/recordings/:id/export | Export as json / text / html / asciinema |
GET /api/recordings/status/:terminalId | Whether a terminal is recording |
GET /api/recordings/active | List active recording ids |
Full request and response schemas live in the Recordings API reference.
Next steps
- Recordings API reference — every field, status code, and response shape.
- Tutorial: Record and export a session — a start-to-finish walkthrough.