Docs

Agent runs.

A run gives an agent a task inside one of your workspaces and lets it work on its own. You write what you want done, pick the agent (Pi, Pi + Gentle Shell or Hermes, among the ones installed in that workspace) and the folder, and the run takes it from there. It keeps going if you close the page or the terminal.

While it works you follow its log live. When it ends you get its result and, if the folder is a git repository, a branch with its changes, ready for you to review.

You can start a run in three ways, and all three see the same runs:

  • From the Runs tab of your workspace in the portal.
  • From your terminal, with nan run.
  • From your own scripts, with the API.

To run the same task again and again, from a webhook, on a schedule or with actions that wait for your approval, save it as an automation.

Before you start

  • A workspace that is running, with at least one agent installed: Pi, Pi + Gentle Shell or Hermes. You install them from the Software panel of the workspace. See Pick the agent.
  • A plan with inference, or your own provider key. With NaN inference (the default), a run uses your workspace’s own inference key, and what the agent spends counts against your plan’s usage like any other request. With your own provider key, your provider bills it and a plan with inference is not needed: an active workspace of your own is enough.

Pick the agent

A run can use one of three agents. Each one needs its programs installed in the workspace:

AgentValue for --agent and agentWhat the workspace needs
PipiPi.
Pi + Gentle Shellpi_gentlePi and gentle-shell. The run starts Pi through gentle-shell, so the agent works with gentle-shell’s subagents, guardrails and memory.
HermeshermesHermes, picked when you created the workspace or installed from the Software panel.

Runs and automations only accept an agent the workspace has installed:

  • In the portal, the Agent list of a new run or an automation shows only the agents of that workspace. If it has none, the portal says so and links to its Software panel: install one there first.
  • From the CLI or the API, asking for an agent the workspace does not have is refused before the run is created, with 409 agent_not_installed (the error names the agent field). nan run exits with code 4. Install the agent from the Software panel, or pick another one, and try again.
  • An automation keeps its agent if you remove that agent from the workspace later (the editor marks it (not installed)), but its runs are refused until you install it again or pick another agent. If you change an automation’s workspace and the new one lacks its agent, the editor switches to one it has and tells you.

To know from a script which agents a workspace can run, read its run_agents field: see API reference → Workspaces.

Start a run from the portal

Open the Runs tab

Go to cloud.nan.builders/workspaces and open a workspace. Next to Overview, Console, SSH keys, Events and Backups there is a Runs tab. Its Agent runs card lists the runs of that workspace, newest first, each with its state, the agent, the task, when it started, how long it took and the tokens it used.

Runs tab of a workspace: the Agent runs card with the New run button and a list of runs, each with its state, agent, task, date, duration and tokens
The Runs tab, with the history and New run.

Fill in the form

Press New run and fill in the form:

FieldWhat it is
AgentPi, Pi + Gentle Shell or Hermes. The list shows only the agents installed in the workspace. See Pick the agent.
TaskWhat you want done, in your own words, as you would write it to the agent in a chat. Up to 32 KiB (the counter under the box shows the bytes used).
FolderWhere the agent works. It defaults to /home/nan and must be inside it.
Separate branchAuto (the default), On or Off. In a git repository, the agent works on its own branch and your checkout stays as it is. See Where the agent works.
Time limit30 min by default, the same as the CLI and the API. The options are 15 min, 30 min, 1 hour and 2 hours. The run is stopped when it reaches it.
InferenceNaN (included in your plan), the default (shown as NaN (not in your plan) when your plan has no inference), or My own key: a Provider key of yours and the Model to use. See Use your own provider key.

Press Start run, or Ctrl+Enter (⌘+Enter on a Mac) from the task box.

New run form with the Agent selector, the Task box and its byte counter, the Folder field, the Separate branch switch set to Auto, the Time limit selector and the Start run button
The New run form.

Follow it live

Click a run in the list to open its page. At the top you see its state, the workspace, the agent, the folder, how long it has been running, the tokens it has used, its time limit and the task. Below, under Output, the log fills in live as the agent works: what it says, the tools it calls and what they answer. Click a Tool call or Tool result line to unfold it. When the run ends, the page shows how it ended, the agent’s summary and, if there is one, the branch with its changes.

You can close the page at any moment. The run goes on, and its page is there when you come back.

Page of a running run: the Running state, the Cancel run button, the workspace, agent, folder, duration, tokens, time limit and task, and the live Output with a bash tool call and its result
A run in progress, with its live output.

Cancel it, if you need to

Cancel run stops the run within a few seconds. The portal asks you to confirm first.

Where the agent works

What happens to your files depends on the Folder you choose and on the Separate branch setting.

The folder is…Auto (default)OnOff
inside a git repositorySeparate branchSeparate branchDirectly in the folder
not a git repositoryDirectly in the folderThe run fails with a configuration errorDirectly in the folder

With a separate branch, the agent does not touch your checkout. It works in a separate copy of the repository (a git worktree), on a new branch called nan-run/ followed by the first 8 characters of the run id, for example nan-run/6f1c2a9b. When the agent ends, whatever it changed is committed on that branch. The run never pushes: the branch stays in the repository inside your workspace, and you decide what to do with it. If the agent changed nothing, the branch is deleted.

To review the changes and bring them in, open a terminal in your workspace (over SSH or the Console tab) and, from the repository:

git log -p HEAD..nan-run/6f1c2a9b
git merge nan-run/6f1c2a9b

Without a separate branch, the agent works directly in the folder and there is no branch. Use it for folders that are not repositories, or when you want the changes right there.

The folder must be inside /home/nan, your home in the workspace.

Run states

StateWhat it means
queuedWaiting for a free place. See How many runs at once.
startingBeing set up in the workspace.
runningThe agent is working.
succeededThe agent finished its task.
failedThe agent stopped with an error, or the run could not start (for example, Separate branch set to On in a folder that is not a repository).
cancelledYou cancelled it.
timed_outIt reached its time limit and was stopped.
awaiting_approvalOnly for automation runs: the agent finished and proposed actions that wait for your approval.

The portal shows the same states with a capital letter, for example Running, Succeeded or Cancelled.

Through the CLI and the API the time limit goes from 60 seconds to 2 hours. The portal offers 15 min, 30 min, 1 hour and 2 hours, with 30 min by default.

How many runs at once

How many runs work at the same time depends on the size of the workspace:

SizeRuns at once
Micro (also the free Premium workspace)1
Nano2
Basic3
Medium5
Large8

On top of that, runs on NaN inference share your inference concurrency, so you can have at most 5 of them working at once across all your workspaces (8 on Premium). Runs on your own provider key have their own limit: up to 8 at once across all your workspaces.

Runs beyond those limits are not refused: they wait in a queue and start in order, first in, first out. The queue holds up to 20 runs per workspace and 50 in total, and you can create up to 60 runs per hour.

Each run works in its own process inside the workspace, with its own share of CPU and memory. If one gets out of hand, it is stopped alone: your SSH sessions and your always-on agents keep working.

Inference and secrets

Runs on NaN inference use the inference key of the workspace, the same one its agents use when you work with them by hand. Their requests count against your plan’s usage like any other. Runs on your own provider key use your key instead, and never get the workspace’s.

Secrets in your workspace’s environment file, such as that inference key or a Telegram bot token, are shown as [masked] in run logs and results, so a log does not leak them. See Masking in logs and events.

The secrets you keep in your settings are not given to these runs: they go only to the runs of the automations you assign them to. See Secrets.

Use your own provider key (BYOK)

A run can use your own key with an AI provider instead of NaN inference: bring your own key (BYOK). The agent works exactly the same way, but its model calls go from your workspace straight to your provider, with your key, and your provider bills them.

You choose it per run, and per automation: NaN stays the default.

Providers

ProviderproviderModel id, for example
Anthropicanthropicclaude-sonnet-4-5
OpenAIopenaigpt-5
Google Geminigeminigemini-2.5-pro
OpenAI-compatibleopenai_compatibleWhatever the endpoint serves, for example meta-llama/Llama-3.3-70B-Instruct

OpenAI-compatible is any endpoint that speaks the OpenAI API at a base URL you give: a hosted provider such as Together, Groq or OpenRouter, or your own server, as long as it is reachable on the internet over https.

Type the model id exactly as your provider names it. NaN does not check it against your provider: a wrong id, or a wrong key, shows up as a failed run with your provider’s error in its log (with the key masked).

Save your key as a provider key

Open your settings on the portal, Secrets, and press Add secret. Fill in:

  • Name: how runs and automations refer to it, for example ANTHROPIC_KEY. Capitals, digits and _, starting with a letter.
  • Kind: Provider key.
  • Provider: Anthropic, OpenAI, Google Gemini or OpenAI-compatible. It cannot be changed later: to switch providers, add another key.
  • Base URL, only for OpenAI-compatible: the root of the endpoint, usually ending in /v1, for example https://api.together.xyz/v1. See the base URL rules.
  • Value: the key, one line without spaces, 8 to 4096 characters.
  • Description (optional).

Like every secret, a provider key is write-only: nobody can read it back, not even you. The list shows it as Provider key · Anthropic (or its provider) usually with its last 4 characters, and, for an OpenAI-compatible key, its base URL, which you can change with Base URL. Replace value changes the key for every run that starts from then on. nan secrets ls shows it with KIND provider_key, its PROVIDER and its BASE URL.

Where your account has the write API, you can also save it from the CLI, reading the key from a file or a pipe: nan secrets set ANTHROPIC_KEY --value-file key.txt --kind provider_key --provider anthropic. See Manage secrets from the CLI.

Base URL rules. NaN checks the base URL when you save it, and never connects to it: only the agent in your workspace does. It must be a public https address, not one of NaN’s own hosts, with no user:password@, query string or fragment: the full list is in Base URL rules. Never put a token in the base URL: it is not a secret, and the portal, nan secrets ls and the API show it in clear.

Choose it for a run

In the portal, in the New run form, set Inference to My own key, pick the Provider key and type the Model.

From the terminal (CLI 0.1.32 or newer):

nan run --byok-secret ANTHROPIC_KEY --model claude-sonnet-4-5 "fix the flaky test in the date parser"

--byok-secret takes the name of the secret, never the key itself, and needs --model. nan runs show <id> shows the choice on its inference line, and nan runs ls in its INFERENCE column.

From the API, with a signed-in session (see Who can use it), add an inference object and leave the top-level model out:

{
  "workspace": "develop",
  "agent": "pi",
  "prompt": "fix the flaky test in the date parser",
  "inference": { "source": "byok", "secret": "ANTHROPIC_KEY", "model": "claude-sonnet-4-5" }
}

The run you get back says the same in its inference ("source": "byok", the provider, the secret and the model), and its usage.source is byok. Without inference, or with {"source": "nan"}, the run uses NaN inference as always.

Who can use it

  • Without a NaN inference plan, runs and automations on your own key work if you have a workspace of your own that is active. With a NaN inference plan, you can choose either for each run.
  • A run you start yourself on your key needs a signed-in session: the portal, or the CLI after nan auth login. An API key (sk-...) or a platform token (nan_pat_...) gets 403 session_required, and nan run refuses NAN_TOKEN and --token-file for it. The reason: the prompt of a run can make the agent print the key it holds, and those credentials cannot read your secrets, so they must not be able to make an agent reveal one. They can still start an automation that uses your key: its instructions are the ones you saved.
  • If My own key is disabled with “isn’t available for your account yet”, it is being opened gradually and your account does not have it yet: use NaN inference meanwhile, or ask in #support on Discord.

Billing and usage

Your provider bills every token of these runs, under your account with them. NaN does not meter them: nothing counts against your NaN plan or its usage. The tokens a run shows are the ones the agent reported (Pi and Pi + Gentle Shell report them, Hermes does not); your provider’s bill is the reference.

Limits

  • Up to 8 runs on your own keys working at once across all your workspaces. They do not take places from your NaN inference limit (5, or 8 on Premium).
  • The size of each workspace still limits all its runs together, NaN or not: see How many runs at once. So do the queue (20 per workspace, 50 in total) and the 60 runs per hour.

Security

  • Your key is stored like any secret: encrypted, write-only and masked in logs, results and proposals.
  • It reaches only the agent of the run, inside your own workspace, as an environment variable: never on the command line, in a file or in NaN’s logs. The run does not get your workspace’s NaN inference key.
  • NaN never calls your base URL or your provider. The agent in your workspace does, over your workspace’s network.
  • The run reads your agent’s settings to keep your skills and preferences, but it uses its own copy of the configuration, with only your key’s provider in it: your own configuration files are not changed.
  • The agent holds the key. A prompt, or data it reads, that convinces it to print or send the key can leak it. Use a key limited to what the run needs, with a spending limit at your provider, and replace it if it leaks.
  • An automation started by a webhook gives the agent text that someone else wrote, while it holds your key. Keep that in mind before you connect a public webhook to an automation on your key.

If something goes wrong

What you seeWhy, and what to do
404 not_found, param: inference.secretYou have no secret with that name. Check the names with nan secrets ls.
400 invalid_request, param: inference.secretThat secret is a generic secret, not a Provider key. Add your key as a provider key.
400 invalid_request, param: inference.modelThe model is missing, or it is not a model id (letters, digits and . _ : / -, up to 128, not starting with -).
400 invalid_request, param: modelA top-level model sent with "source": "byok". Move it into inference.model.
400 invalid_request, param: inferenceYour own key is not available for your account yet, or the inference object is malformed.
403 session_requiredA run on your key with an API key or a token. Start it signed in, or run an automation instead.
403 tier_restrictedNo NaN inference plan and no active workspace of your own.
The run fails with secret_missingThe provider key was deleted after the run was queued.
The run fails with config_errorThe agent could not be set up for your key, for example Hermes with an Anthropic key (below).
The run fails with your provider’s error in the logA wrong key, a wrong model id, no credit at your provider, or a base URL that does not answer.

Known limitation: Hermes with an Anthropic key

Hermes cannot use an Anthropic key in workspaces yet: its runs fail with config_error until the workspace image includes Anthropic support. Use Pi or Pi + Gentle Shell with an Anthropic key, or point Hermes at an OpenAI-compatible endpoint.

From the terminal: nan run

The NaN CLI starts and follows runs from your own terminal. You need version 0.1.25 or newer, and 0.1.29 or newer for --agent pi_gentle: nan --version prints nan <version>.

Install or update the CLI

curl -fsSL https://nan.builders/install | bash

Sign in

nan auth login --email you@yours

It emails you a sign-in link. Copy it from the email and paste it back into the command without opening it in the browser first: it works once. The NaN CLI guide has the details. For scripts, CI or a server, use a token instead: see Authentication.

Start a run

nan run "add tests for the date parser and make them pass"

The CLI streams the log to your terminal until the run ends.

A few more ways to start one:

# A specific workspace, agent and folder
nan run --ws develop --agent hermes --cwd /home/nan/projects/api "review the open TODOs"

# Pi + Gentle Shell (the workspace needs Pi and gentle-shell)
nan run --ws develop --agent pi_gentle "refactor the config loader and keep the tests green"

# The task from a file, or from stdin
nan run -f task.md
git diff | nan run -

# Start it and get the id back without waiting
nan run --detach "upgrade the dependencies"
FlagDefaultWhat it does
--ws NAMEyour only workspaceThe workspace to run in. If you have more than one and leave it out, the CLI lists them and exits with code 64.
--agent pi|pi_gentle|hermespiThe agent: pi (Pi), pi_gentle (Pi + Gentle Shell) or hermes (Hermes). It must be installed in the workspace. See Pick the agent.
--model Mthe agent’s ownThe model the agent uses. Required with --byok-secret.
--byok-secret NAMENaN inferenceRun on your own provider key: the name of a provider key secret. Needs --model and your nan auth login session. See Use your own provider key.
--cwd PATH/home/nanThe folder in the workspace.
--worktree / --no-worktreeautoForce a separate branch on or off. See Where the agent works.
--timeout D30mThe time limit, from 1m to 2h.
--detachStart the run, print its id and return.
--idempotency-key KIf a retry sends the same key and request, you get the run already created instead of a second one.
--jsonPrint events as JSON lines, then the finished run.
-f FILERead the task from a file, or from stdin with -.
--token-file PATHAuthenticate with the token on the first line of a file. See Authentication.

The flags match the portal form: Agent is --agent, Folder is --cwd, Separate branch is --worktree / --no-worktree and Time limit is --timeout. The task is the text in quotes.

While it streams, Ctrl-C once stops following the log: the run keeps going and the CLI tells you how to pick it up again. Ctrl-C twice within 2 seconds cancels it.

Manage your runs

nan runs ls                # your runs, newest first
nan runs show <id>         # state, result and prompt
nan runs logs <id> -f      # follow the log until it ends
nan runs cancel <id>

nan runs logs <id> --json prints one JSON event per line, handy for scripts. Each event has a type; these are the main ones:

TypeWhat it is
startedThe run started: agent, model, folder and, if there is one, the branch.
messageText from the agent.
tool_call / tool_resultA tool the agent called, and what it answered.
logA line of output that is not a message.
usageTokens used so far.
errorSomething went wrong, with a code.
finishedThe run ended: its state and the agent’s summary.
approval_requiredAn automation run proposed actions that wait for your approval.
actionOne step of applying an automation’s actions.

Exit codes

nan run and nan runs logs -f exit with the outcome of the run, so a script can act on it without reading the text:

CodeMeaning
0succeeded
1failed
2timed out
3cancelled
4the workspace is not ready for it: agent not installed, no inference key or a bad configuration
10the run is waiting for your approval (only automation runs)
64usage error, including more than one workspace and no --ws
65not signed in, session expired or not allowed (also a token or an API key for a run on your own key)
69nan.builders unavailable, or the stream was lost (the run goes on, and the id is printed)
75the run was accepted and is still going (--detach, or Ctrl-C once)

Under set -e, allow for the 75 of --detach:

id=$(nan run --detach "upgrade the dependencies") || [ $? -eq 75 ]

Authentication

nan run and nan runs use the first of these they find:

  1. NAN_TOKEN: an environment variable holding a platform token (nan_pat_...) or an API key (sk-...). It is read on every command and never written to disk.
  2. --token-file PATH: the token on the first line of a file. The file must be private (chmod 600): on macOS and Linux, one that other users can read or write is refused.
  3. A saved token, from nan auth login --api-token.
  4. Your session, from nan auth login (the emailed sign-in link).
  5. A saved API key, from the Setup tab (or an sk-... key saved with nan auth login --api-token).

nan auth login --api-token reads the token from stdin only, hidden while you paste it, checks it against nan.builders and saves it with mode 0600. It keeps it apart from the API key, so the Setup tab never copies a platform token into your tools’ configuration:

nan auth login --api-token              # paste it when asked
nan auth login --api-token < token.txt  # or pipe it in

Never put a token on the command line itself: it would end up in your shell history and in ps.

A run on your own provider key (--byok-secret) uses only your session from nan auth login: the CLI refuses NAN_TOKEN and --token-file for it, and skips a saved token or API key.

In the CLI, a platform token only works for nan run, nan runs, nan automations and nan approvals (see API keys and tokens). nan me, nan metrics usage and the dashboard still need a session from nan auth login.

Use the CLI in CI or on a server

Create a token, store it in your CI’s secret store and expose it as NAN_TOKEN. For example, in GitHub Actions:

- name: Review the PR with an agent
  env:
    NAN_TOKEN: ${{ secrets.NAN_TOKEN }}
  run: |
    curl -fsSL https://nan.builders/install | bash
    nan run --ws ci --timeout 20m -f .github/review-task.md

That step waits for the run and fails if the run fails. To start the run and move on without waiting, use --detach and allow for its exit code 75:

nan run --ws ci --detach "upgrade the dependencies" || [ $? -eq 75 ]

Keep the token secret

Store the token only as a secret (secrets.NAN_TOKEN in GitHub Actions), never in the repository or in the workflow file. It can start runs that spend your plan.

On a server you set up once, save it with nan auth login --api-token instead.

From the API

The same runs are available over HTTP, at https://api.nan.builders/v1/runs, for your own scripts and integrations.

API keys and tokens

Two kinds of credentials work with the runs API. Both are in your settings on the portal:

API KeysTokens
Looks likesk-...nan_pat_...
Inference (models)YesNo, never
Platform API (runs, automations, approvals, your workspaces)YesYes
Who can create themPlans with inferenceAny member with an active subscription

A token is the one to give a script that only manages runs. It cannot call the models directly, but it can start runs that spend your plan, so keep it as private as an API key and revoke it if it leaks. Create it under Settings → Tokens:

  • It is shown once, when you create it. Copy it then.
  • You can have up to 10 active tokens.
  • Each one expires after 30, 90 or 365 days, or never.
  • You can revoke any of them at any time.
  • It carries scopes, what it may do: runs and workspaces:read by default. To list or run automations, add automations:read or automations:run. See Tokens for automations.

Creating runs on NaN inference still needs a plan with inference, whatever credential you use. Runs on your own provider key need a signed-in session instead of a key or a token. The API reference lists which credential each endpoint accepts.

An agent cannot launch runs by itself

The key inside a workspace, the one its agents use for inference, cannot manage runs: the API answers it with 403. An agent working in your workspace cannot start new runs on its own, unless you give it one of your own API keys or tokens.

Create a run and follow it

An end-to-end example: create a run, keep its id (with jq) and follow its log live until it ends. If the run cannot be created, it prints the error instead of following the log.

export NAN_TOKEN="nan_pat_..."

RESP=$(curl -s https://api.nan.builders/v1/runs \
  -H "Authorization: Bearer $NAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "workspace": "develop",
    "agent": "pi",
    "prompt": "add tests for the date parser and make them pass",
    "cwd": "/home/nan/projects/api"
  }')
RUN_ID=$(echo "$RESP" | jq -r '.id // empty')
if [ -z "$RUN_ID" ]; then
  echo "$RESP"
else
  curl -N "https://api.nan.builders/v1/runs/$RUN_ID/events" \
    -H "Authorization: Bearer $NAN_TOKEN" \
    -H "Accept: text/event-stream"
fi

The fields match the portal form: Agent is agent, Task is prompt, Folder is cwd, and the optional Separate branch and Time limit are git_isolation and timeout_seconds.

agent is pi, pi_gentle or hermes, as in Pick the agent. If the workspace does not have that agent installed, no run is created and the example prints the error instead:

{
  "error": {
    "message": "Pi + Gentle Shell is not installed in this workspace",
    "type": "invalid_request_error",
    "param": "agent",
    "code": "agent_not_installed"
  }
}

The stream sends one run_event frame per event of the log, a state frame when the run changes state, and an end frame with the finished run, after which it closes.

Full reference: API reference → Runs. It has every endpoint (list, retrieve, cancel), the request and response fields, the event types, how to resume a stream, idempotent retries and every error code. To find a workspace’s name or id from a script, see API reference → Workspaces.

FAQ

Does a run push my code anywhere?

No. With a separate branch, the changes stay on a nan-run/... branch in the repository inside your workspace. Pushing, merging or throwing them away is up to you.

What happens if I close the browser or the terminal?

Nothing: the run keeps going in the workspace. Open its page in the Runs tab, or run nan runs logs <id> -f, to pick it up again.

Can I use runs without inference in my plan?

Yes, with your own provider key and an active workspace of your own: your provider bills the tokens. Runs on NaN inference need a plan with inference.

Does a run touch my SSH sessions or my always-on agents?

No. Each run has its own share of the workspace’s CPU and memory. If one gets out of hand, only that run is stopped.

Where do I get help?

Write in #support on Discord.

nan.builders © 2026
Copied to clipboard