Skip to main content
Every recipe below is a 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 with connect 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 (scope sessions:terminal):
Use 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 stdout compares cleanly against expected text.
  • The process still exits with the remote exit code, so under set -e a failing command aborts the script before you can read the JSON. Capture it with || true as above, then read exit_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 in agent_status: awaiting_approval is not broken; it is waiting for a person. List the gates, then resolve:
Who may resolve is enforced server-side: admins and owners always, otherwise the approval’s 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:
The response separates 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:
Text operations:
Files need 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”, use session previews. It is scoped to the API key’s own user and returns just id, name, state, preview_url.
Do not reach for 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.
If 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

Lifecycle policy (--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:
Stop polling when 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:
Read until an event of type done or error. Filter with jq:
The WebSocket equivalent, with the full event vocabulary, is in Stream prompts over WebSockets.

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

Env-var endpoints use the 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 exec output. Without --json the stream mixes stderr, stdout and shell banners. Always pass --json when a script reads the result.
  • set -e swallows the JSON. exec exits with the remote exit code, so capture with || true and branch on .exit_code.
  • session list --team-mode for “my preview URLs”. It returns every teammate’s sessions. Use session previews.
  • Sharing vs visibility. visibility team opens the whole session to the org; share create shows one port to one outside person.
  • Env scopes. env set needs secrets:write; a key with only sessions:write gets a 403.
  • --skip-agent implies --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).