Resterm
A terminal API client for REST, GraphQL, gRPC, WebSocket and SSE.

Resterm is a keyboard-driven API client that lives in your terminal and keeps everything local. It stores requests as plain files and supports SSH tunnels, Kubernetes port-forwarding, OAuth 2.0, and command-backed auth, with a fast feedback loop built around history, diffs, tracing, and profiling.
Quick links: Screenshots, Installation, Quick Start, Documentation.
See the UI in action (click to expand)
Workflows

Trace and Timeline

Profiler

Explain

RestermScript

Light Theme

OAuth browser demo (old UI design)

.http / .rest files.@when, @skip-if, @if/@elif/@else, @switch/@case, and @for-each.@workflow / @step.@capture, @var, @assert).resterm run for requests, workflows, JSON/JUnit output, and reusable run artifacts.Resterm also ships with a built-in CLI: resterm run.
Use resterm run when you want to execute .http / .rest files directly from the terminal without opening the TUI.
Example:
mkdir my-api && cd my-api
resterm init
resterm run --request Echo requests.http
resterm init creates requests.http with sample requests and resterm.env.json with a dev environment that points at httpbin.org. The command above runs the Echo request which POSTs a JSON body and prints the response.
[!NOTE] This is different from the
headlesspackage. Theheadlesspackage is the embeddable Go API for building your own runner or CI integration, whileresterm runis the built-in CLI on top of the same execution engine.
See the full CLI documentation for usage, selectors, output formats, and examples.
Resterm ships with the engine API, so you can build your own headless runner for Resterm and embed request execution in your own Go tooling/code, CI or internal automation.
The public Go API lives in the headless package and can run requests, workflows, assertions, compare runs and profiles without the TUI.
[!NOTE] If you don't want to build your own runner, check out resterm-runner.
```bash # Linux/macOS (Homebrew) brew install resterm
# Linux (install script) curl -fsSL https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.sh | bash ```
powershell
# Windows (PowerShell)
iwr -useb https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.ps1 | iex
bash
mkdir my-api && cd my-api
resterm init
bash
resterm
Press Ctrl+Enter in the editor to send the highlighted request.
If you do not want files yet, just run resterm, type a URL in the editor, and press Ctrl+Enter.
If you already have a curl command, paste it into the editor and press Ctrl+Enter to import it.
A few keys that make Resterm feel “native” quickly:
Tab / Shift+Tab - move focus between sidebar, editor, and response.g+r - jump to Requests (sidebar).g+i - jump to Editor.g+p - jump to Response.g+h / g+l - adjust layout:g+j / g+k - adjust layout:g+v / g+s - toggle response pane between inline and stacked layout.g+1, g+2, g+3 + minimize/restore sidebar, editor, response.g+z / g+Z - zoom the focused pane / clear zoom.
Environments & globals
Ctrl+E - switch environments.Ctrl+G - inspect captured globals.
Working with responses
Ctrl+V / Ctrl+U - split the response pane for side-by-side comparison.Ctrl+Shift+C or g y - copy the entire Pretty/Raw/Headers tab
to the clipboard (no mouse selection needed).g x - build an Explain preview for the active request without sending it.g e - open the current or selected supported file in your external editor.[!TIP] If you only remember three shortcuts… -
Ctrl+Enter- send request -Tab/Shift+Tab- switch panes -g+p- jump to response
Linux / macOS (Homebrew)
brew install resterm
[!NOTE] Homebrew installs should be updated with Homebrew (
brew upgrade resterm). The built-inresterm --updatecommand is for binaries installed from GitHub releases or install scripts.
Linux / macOS (Shell script)
[!IMPORTANT] Pre-built Linux binaries depend on glibc 2.32 or newer. If you run an older distro, build from source on a machine with a newer glibc toolchain or upgrade glibc before using the release archives.
curl -fsSL https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.sh | bash
or with wget:
wget -qO- https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.sh | bash
Windows (PowerShell)
iwr -useb https://raw.githubusercontent.com/unkn0wn-root/resterm/main/install.ps1 | iex
These scripts detect your architecture, download the latest release, and install the binary.
[!NOTE] The manual install helper uses
curlandjq. Installjqwith your package manager (brew install jq,sudo apt install jq, etc.).
Linux / macOS
# Detect latest tag
LATEST_TAG=$(curl -fsSL https://api.github.com/repos/unkn0wn-root/resterm/releases/latest | jq -r .tag_name)
# Download the matching binary (Darwin/Linux + amd64/arm64)
curl -fL -o resterm "https://github.com/unkn0wn-root/resterm/releases/download/${LATEST_TAG}/resterm_$(uname -s)_$(uname -m)"
# Make it executable and move it onto your PATH
chmod +x resterm
sudo install -m 0755 resterm /usr/local/bin/resterm
Windows (PowerShell)
$latest = Invoke-RestMethod https://api.github.com/repos/unkn0wn-root/resterm/releases/latest
$asset = $latest.assets | Where-Object { $_.name -like 'resterm_Windows_*' } | Select-Object -First 1
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile resterm.exe
# Optionally relocate to a directory on PATH, e.g.:
Move-Item resterm.exe "$env:USERPROFILE\bin\resterm.exe"
go install github.com/unkn0wn-root/resterm/cmd/resterm@latest
resterm --check-update
resterm --update
The first command reports whether a newer release is available. The second downloads and installs it (Windows users receive a staged binary to swap on restart).
resterm.env.json) discovered in the request directory, workspace root, or CWD. Dotenv files (.env, .env.*) are opt-in via --env-file and are single-workspace. Prefer JSON when you need multiple environments in one file.--workspace, --file, --env, --env-file, --timeout, --insecure, --follow, --proxy, --recursive, --from-curl, --from-openapi, and --http-out.$HOME/Library/Application Support/resterm, %APPDATA%\resterm, or $HOME/.config/resterm and can be overridden with RESTERM_CONFIG_DIR.You can export a workspace into a Git-friendly Resterm bundle. The exported bundle always includes a manifest.json with checksums, so imports can verify file integrity before writing anything.
When Resterm sees resterm.env.example.json in your workspace, it includes that file as-is. If only resterm.env.json exists, Resterm generates resterm.env.example.json automatically and replaces values with REPLACE_ME placeholders so secrets are not exported.
resterm collection export \
--workspace ./my-api \
--out ./shared/my-api-bundle \
--recursive \
--name "my-api-v1"
resterm collection import \
--in ./shared/my-api-bundle \
--workspace ./my-local-api
If you want to preview actions first, you can run:
resterm collection import \
--in ./shared/my-api-bundle \
--workspace ./my-local-api \
--dry-run
If files already exist and should be replaced intentionally, add --force.
Paste a curl command into the editor and press Ctrl+Enter to convert it into a structured request. Resterm understands common flags, merges repeated data segments, and keeps multipart uploads intact.
curl \
--compressed \
--url "https://httpbin.org/post?source=resterm&case=multipart" \
--request POST \
-H "Accept: application/json" \
-H "X-Client: resterm-dev" \
--user resterm:test123 \
-F file=@README.md \
--form-string memo='Testing resterm inline curl
with multiline value' \
--form-string meta='{"env":"test","attempt":1}'
If you copied the command from a shell, prefixes like sudo or $ are ignored automatically.
RestermScript (RTS) is a small expression language built specifically for Resterm. Because it targets Resterm features directly, it can evolve alongside Resterm and stay symbiotic with the request format, workflows, and directives. JavaScript hooks are still available when you want them, but RTS is the default because it is readable, predictable, and focused on Resterm’s domain.
Quick example (RTS module + request):
// rts/helpers.rts
module helpers
export fn authHeader(token) {
return token ? "Bearer " + token : ""
}
# @use ./rts/helpers.rts
# @when env.has("feature")
# @assert response.statusCode == 200
GET https://api.example.com/users/{{= vars.get("user") }}
Authorization: {{= helpers.authHeader(vars.get("auth.token")) }}
Full reference: docs/restermscript.md.
Resterm supports client credentials, password grant, and authorization code + PKCE. For auth code flows, it opens your system browser, spins up a local callback server on 127.0.0.1, captures the redirect, and exchanges the code automatically. Tokens are cached per environment and refreshed when they expire. Docs: docs/resterm.md#oauth-20-directive and _examples/oauth2.http.
Chain requests with @workflow and @step, pass data between steps, and add lightweight JS hooks where needed. Docs + sample: docs/resterm.md#workflows-multi-step-workflows and _examples/workflows.http.
Run the same request across environments with @compare or --compare, then diff responses side by side with g+c. Docs: docs/resterm.md#compare-runs.
Add @trace with budgets to capture DNS, connect, TLS, TTFB, and transfer timings. Resterm visualizes overruns and can export spans to OpenTelemetry. Docs: docs/resterm.md#timeline--tracing.
Use @websocket with @ws steps or @sse to script and record streams. The Stream tab keeps transcripts and includes an interactive console. Docs: docs/resterm.md#streaming-sse--websocket.
Resterm supports unary and strea
$ claude mcp add resterm \
-- python -m otcore.mcp_server <graph>