runtm-api session subcommand. The endpoint behind each one is documented under Sessions; this page is about the order to run them in and the flags that matter. Sessions, templates and the file and env commands all need an org-scoped API key when the resources belong to an org; --org cannot substitute for one.
When to use which command
Recipe: boot a session from a template, then run commands
The most common path: create a template once, spin up sessions from it, drive them withconnect or exec.
Recipe: run commands in a session (connect vs exec)
Two ways to get a shell against a session’s sandbox, both over the same terminal WebSocket the dashboard uses (scopesessions:terminal):
exec for automation and scripted checks. Use connect only when a human is at a real terminal.
--json: use it whenever you will parse the output
The default output is the raw PTY stream: stderr is merged into stdout and the sandbox’s shell startup noise (mise, nvm and similar banners) rides along, which is why hand-rolled pipelines end up with a grep -v filter. --json avoids all of that:
- The two streams are captured separately (stderr goes to a temp file in the sandbox and is replayed after a sentinel), so neither can interleave into the other.
- PTY carriage returns are stripped, so
stdoutcompares cleanly against expected text. - The process still exits with the remote exit code, so under
set -ea failing command aborts the script before you can read the JSON. Capture it with|| trueas above, then readexit_code.
! is safe
Bash history expansion is disabled for the command in both modes. A literal ! in a heredoc, a commit message or a regex reaches the sandbox intact instead of being rewritten against shell history.
Paused sandboxes resume automatically
Sessions auto-pause after about 20 minutes idle.exec, connect and the file commands resume a paused sandbox in place rather than failing, so a scripted run against a session you left alone yesterday just works. The first command after a resume takes a few extra seconds. Use session pause when you deliberately want to stop the clock.
Recipe: unblock a stalled autopilot run (approvals)
A run inagent_status: awaiting_approval is not broken; it is waiting for a person. List the gates, then resolve:
required_role or required_team_id must match. The session flips back to working and the agent continues from the verdict. How an agent requests one from inside the run is in Request an approval from inside a run.
Recipe: hot-load capabilities into a running session
Attaching a skill at template build time takes a rebuild. Loading it into the running sandbox takes seconds:loaded from needs_auth (credentials missing) and skipped (wrong id or slug). Loading requires the sandbox to be running; a paused one auto-resumes. Hot-loaded capabilities last for that session only; to make them permanent, attach to the template and rebuild (Give it tools).
Recipe: move binary artifacts in and out
file write and file read handle text. For CSVs, archives and anything binary:
sessions:read (list, read, search) or sessions:write (write, upload, mkdir, rename, delete). The HTTP shape of each call is in Work with session files.
Recipe: find the session again later
session list only pages. search filters by agent, model, template, source, creator and time windows, and matches name and prompt text with -q.
Recipe: find my own preview URLs
When the user asks “what are my preview URLs” or “give me the link to my prototype”, usesession previews. It is scoped to the API key’s own user and returns just id, name, state, preview_url.
session list --team-mode here. In a busy org that returns every teammate’s sessions, so the user gets a wall of URLs that are mostly not theirs. session previews defaults to scope: "mine" and says so in its output.
A paused session still lists its URL. Opening a shared preview wakes the sandbox automatically, so a paused state is not a reason to withhold the link.
Recipe: share a live preview with someone outside the org
Two different things, often confused:
A preview share grants exactly one
(session, port) pair. The invitee gets the app and nothing else: no workspace, no terminal, no prompting, and they are not added to the organization. They need a Runtm account to open it, but not before being invited; the grant binds to their account the first time they sign in.
emailed is false, delivery is not configured; send preview_url to the invitee yourself. Re-inviting an address that already has the port is a no-op and sends no second email.
A shared link keeps working through auto-pause: opening it wakes the sandbox and lands the visitor on the preview after a few seconds. Do not pre-emptively session resume just to keep a share alive. Revocation applies once the holder’s current preview cookie expires (a few minutes), not instantly; to cut access immediately, also pause or destroy the session.
Recipe: ship a deployment and track it afterwards
session deploy ships from the sandbox; deployments is how you see the result later without switching tools.
Recipe: launch an agent from scratch
--on-complete): pause (default, sandbox pauses and is resumable), destroy (torn down immediately, for one-shot tasks), keep_alive (stays running until the TTL, for iteration). --ttl-minutes is the hard upper bound, maximum 1440. The HTTP side is in Manage sessions at scale.
Recipe: interactive iteration
Recipe: pre-seed files and env, then prompt
Recipe: pause and resume
Reading session status and session prompt output
session status returns an envelope tuned for polling:
last_prompt.status is completed, error or timed_out. The summary field holds the agent’s final response, truncated to 500 characters. For high-volume workflows prefer outbound webhooks over polling.
session prompt streams JSON lines, one event per line:
done or error. Filter with jq:
Git operations
session git <id> <operation>:
The working directory defaults to
/home/user. Set --working-dir if the repo is elsewhere, for example in a monorepo with several workdirs.
Env vars
secrets:read and secrets:write scopes, not sessions:write. Confirm the API key has them with runtm-api auth status before suggesting env changes.
Gotchas
- Parsing default
execoutput. Without--jsonthe stream mixes stderr, stdout and shell banners. Always pass--jsonwhen a script reads the result. set -eswallows the JSON.execexits with the remote exit code, so capture with|| trueand branch on.exit_code.session list --team-modefor “my preview URLs”. It returns every teammate’s sessions. Usesession previews.- Sharing vs visibility.
visibility teamopens the whole session to the org;share createshows one port to one outside person. - Env scopes.
env setneedssecrets:write; a key with onlysessions:writegets a 403. --skip-agentimplies--build. A template created that way starts building immediately with whatever is attached at that moment; attach skills first or rebuild afterwards (Launch and iterate).