CLI
Install and use the inis command-line tool.
The inis CLI is the fastest way to run sandboxes from a terminal or CI pipeline. It wraps the HTTP API — no SDK required.
Status: curl -fsSL https://inis.run/install.sh | bash
Install
curl -fsSL https://inis.run/install.sh | bashThe installer downloads a static binary for your OS/arch and adds it to your PATH. To pin a version:
curl -fsSL https://inis.run/install.sh | bash -s -- --version cli-v0.1.1Configure
inis auth loginOr set INIS_API_KEY manually (CI, scripts). Optional override: INIS_BASE_URL=https://api.inis.run.
Commands
| Command | Description |
|---|---|
inis run | Stateless code execution (--language, --file, -e) |
inis exec | Run a shell command in a new or existing session — streams by default (--no-stream, --cwd, --timeout-ms) |
inis ssh | Interactive shell (--keep, --pick, -c) |
inis sessions create | Create a session (--template, --size, --on-detach, --paused-ttl-ms, …) |
inis sessions get/list | Inspect sessions (--state, --all for history) |
inis sessions pause/resume/destroy | Lifecycle |
inis sessions expose/unexpose | Preview URLs (--port, --auth) |
inis sessions checkpoint/restore | Named checkpoints |
inis sessions egress | Update egress allow/deny |
inis sessions create --connection ... | Bind a Connection at create time (credential brokering) |
inis connections inspect/rotate/revoke | Inspect, rotate, or revoke a session's Connections |
inis fork <id> -n N | Fork into N children |
inis checkpoints … | List/get/delete checkpoints; create session from one |
inis templates ls/save/import/rm | Templates |
inis files read/write/list/mkdir/rm/mv/put/get/… | Files (also write-batch, find, grep) |
inis artifacts … | Captured artifacts |
inis org / registries / connectors / webhooks / domains | Account & platform helpers |
inis update / version | CLI self-update / version |
Run inis --help or inis <command> --help for full flags.
Interactive shell
inis ssh attaches a raw interactive shell to a session — like ssh or docker exec -it. It forwards your keyboard, streams output back, tracks window size, and exits with the remote shell's exit code.
inis ssh # create a fresh session, attach, destroy on exit
inis ssh --keep # ...but keep it alive after you exit
inis ssh 9hmquuxiz7qyqdqiwfvep # attach to an existing session by id
inis ssh -c # reattach to your most recent session
inis ssh --pick # choose from your live and paused sessionsA paused session is resumed automatically before attaching, so a session you left days ago picks up where it was. --template and --size apply only when creating a session.
Detach vs. exit
There are two ways to leave a shell, and they mean different things:
- Exit the shell (
exit, or Ctrl-D at an empty prompt) ends the remote shell. For an ad-hocinis ssh(no--keep) this destroys the session. - Detach with the
~.escape closes the connection but keeps the session running, so you can reattach later withinis ssh -c.
Escape sequences (recognised only at the start of a line):
| Escape | Action |
|---|---|
~. | Detach — keep the session running |
~~ | Send a literal ~ |
~? | List the available escapes |
Examples
# Stateless Python execution
inis run --language python -e 'print(sum(range(10)))'
# Run a script from disk
inis run --language python --file ./analyze.py
# Reuse a session across commands
SID=$(inis sessions create)
inis exec --session "$SID" -- pip install httpx -q
inis exec --session "$SID" -- python -c "import httpx; print(httpx.__version__)"
inis sessions destroy "$SID"
# Pause to free compute, resume later (or just attach — attach auto-resumes)
inis sessions pause "$SID"
inis sessions resume "$SID"Session lifecycle
A session outlives any single connection. Detaching or disconnecting never destroys a session on its own — what happens next is governed by its on-detach policy, set at creation:
inis sessions create --on-detach pause # default
inis sessions create --on-detach keep_live # stay hot for fast reattach
inis sessions create --on-detach destroy # tear down on detach| Policy | On detach |
|---|---|
pause (default) | Pause immediately — near-zero cost, warm resume |
keep_live | Keep the VM running; auto-pause later on idle timeout |
destroy | Tear the session down |
Destroyed sessions leave a lightweight history row (inis sessions list --all / --state ended) with an end_reason. Cap how long a paused session sticks around with --paused-ttl-ms.
States, timers, wake-on-op, and recipes: Session lifecycle.
Connections
A Connection binds a session to one external API origin with a credential the platform injects on the way out — code in the session calls the provider's real hostname and never holds the key. Set one at create time with a compact spec:
inis sessions create --connection \
'name=stripe,origin=https://api.stripe.com,auth=bearer,secret=env:STRIPE_KEY,methods=GET|POST,paths=/v1/*,ttl=1h'--connection is repeatable (up to 16 per session). Fields: name, origin (must be https://), auth (bearer or header:<Header-Name>), secret, methods (|-separated), paths (|-separated prefixes), and an optional ttl (a duration like 1h or a plain number of seconds — defaults to the session's own lifetime, capped at 24h).
For secret, prefer env:VAR_NAME (reads an environment variable) or stdin (reads one line from stdin) over a literal value — a literal works, but shell history keeps plain-text secrets around long after the command exits:
STRIPE_KEY=sk_live_... inis sessions create --connection 'name=stripe,...,secret=env:STRIPE_KEY,...'
echo "$STRIPE_KEY" | inis sessions create --connection 'name=stripe,...,secret=stdin,...'Manage Connections already on a session — the CLI has no dedicated list/add endpoints to call yet, so inspect reads the same redacted data off GET /v1/sessions/{id}:
inis connections inspect "$SID" # every Connection on the session
inis connections inspect "$SID" stripe # just this one
inis connections rotate "$SID" stripe --connection 'origin=...,auth=bearer,secret=env:NEW_KEY,methods=GET|POST,paths=/v1/*'
inis connections revoke "$SID" stripe # fails closed, not openOutput is always redacted — no command ever prints a secret value. The honest limit: the credential is never in your code, image, or the session's environment, and it's scoped and revocable — but if the bound origin reflects request headers back (a debug/echo endpoint, an error body), code in the session can read it out that way. Prefer a scoped, short-lived upstream credential so a leak like that can do no more than methods/paths already permitted. Full detail: Connections.
CI
Use INIS_API_KEY from your CI secret store. The binary is self-contained — no runtime dependencies.
- run: curl -fsSL https://inis.run/install.sh | bash
- run: inis run --language python -e "import sys; sys.exit(0)"
env:
INIS_API_KEY: ${{ secrets.INIS_API_KEY }}