selo runs a Selo release test from a terminal or a CI job and turns the verdict into an exit code a pipeline can trust. It authorizes your endpoint, runs the free preflight, pays Selo once from a dedicated, capped wallet, and blocks the release unless every release check passed with evidence. It also verifies Selo’s signed attestations offline.
Install and run
The CLI lives in the Selo repository as the private workspace package@selo/cli. It is not published to a package registry: you run it from a checkout.
Requirements: Node 24 or later and pnpm 10. The repository pins pnpm 10.33.0 through its packageManager field.
Terminal
package.json defines the script that pnpm selo runs:
package.json
packages/cli/bin/selo.js registers tsx and loads src/main.ts, so the CLI runs its TypeScript source directly. There is no build step.
pnpm selo …works from anywhere inside the checkout.- Relative paths you pass (
--body,--contract,--summary,--attestation, and the filesselo verifyreads) resolve against the directory you ran the command in. The run state directory.selo/runs/is created there too. - Under pnpm, that directory comes from
INIT_CWD, which pnpm sets for you. When you callnode packages/cli/bin/selo.jsdirectly, as the GitHub Action does, it is the current directory.
Commands
selo auth
Prove you control the endpoint before Selo will touch it.
selo preflight
Free eligibility check with the target fee, Selo’s cap and Selo’s price.
selo test
The paid release gate: one payment, five checks, one exit code.
selo verify
Check a signed verdict offline for an exact release, URL and method.
Output files
The run state, the
selo.gate.v1 summary, the attestation and the job summary.GitHub Action
The composite action that runs the CLI in a workflow.
Global behaviour
Syntax
- Flags take a value as
--flag valueor--flag=value. Boolean flags (--approve-mainnet,--resume) take none. - Values are trimmed. An empty value counts as missing.
- Unknown flags and positional arguments are usage errors.
- A leading
--is ignored, sopnpm selo -- test …behaves likepnpm selo test ….
Help
selo, selo help, selo --help and selo -h print the full usage and exit 0. So does any command that has help, --help or -h among its arguments. There is no per-command help: one usage text covers every command.
selo --help (excerpt)
Usage errors exit 3
Invalid input is caught before any network request. The CLI prints the problem on stderr, followed by(run selo --help), and exits 3:
Terminal
Unexpected errors exit 2
Any other error stops the CLI with exit2 and this line on stderr:
0.
Output streams
Results go to stdout. Usage errors, refusals, preflight failures, recovery instructions andselo verify failures go to stderr.
Shared validation
These rules apply to every command that takes the flag.Environment variables
Exit codes
Every command uses the same four codes.selo test is the release gate: only 0 allows a release.
What each code means per command:
The CLI does not trust a verdict label on its own.
selo test recomputes the verdict from the report’s own checks with the same reducer Selo uses, and blocks with exit 2 on any disagreement or gap. See How the gate decides and Verdicts and the gate.
Payment approval rules
Onlyselo test pays, and it pays Selo once per run. It never retries a payment on its own.
1
Before any request
--network mainnet needs both --approve-mainnet and --pay-to <Selo's payTo>, or the CLI exits 3 with --network mainnet needs --approve-mainnet and --pay-to <Selo's payTo address>. A missing or invalid SELO_PAYER_MNEMONIC also exits 3.2
Before signing
The CLI reads Selo’s 402 and shows the price, network, payee, payer and tag. It refuses to sign, and exits
3 (2 while resuming), when:- the 402 does not offer exactly one
exactAlgorand USDC requirement (ASA31566704on Mainnet,10458941on Testnet); - the 402 asks for payment on a network other than
--network; --pay-tois set and the 402 names another payee;- the payer is the payee (self-payment);
- the price is zero or above
5.00USDC; - the price is above
--max-usdc.
3
After sending
If the outcome cannot be confirmed (a timeout, a lost connection, a redirect, a held settlement), the CLI records the attempt in
.selo/runs/<release>.json and exits 2. Further runs for that release refuse to pay until you rerun the same command with --resume. See Recover an interrupted run.Network access
The CLI makes requests to these hosts:
Each request to Selo, and the key download in
selo verify, times out after 300 seconds. A release test is one long request: Selo waits for its own settlement and the call to your endpoint before it answers. A timeout on the paid request counts as an unconfirmed outcome, never as a failure that is safe to retry.
Scope
quick profile only, GET and POST targets, Algorand USDC on Mainnet or Testnet. Any other method or network exits 3. The public API at https://api.useselo.xyz runs on Algorand Mainnet; --network testnet is for a Selo deployment that runs on Testnet.
Related
- Quickstart walks through the four commands end to end.
- Run a release test and Gate deploys in GitHub Actions are the task guides.
- Output files documents every file the CLI reads and writes.