> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sumvin.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The --json contract

> How every sumvin command speaks to a script or an agent.

<Warning>
  **The CLI is for developers.** It's mainly for people building and experimenting on Sumvin. The recommended way to use Sumvin is the [MCP connector](/get-started/connect), or the API if you're building (docs coming).

  An agent running in your terminal can approve Stamped Mandates that the CLI signs for you. Never give an unattended agent `--yes`.
</Warning>

Every `sumvin` command accepts `--json`. Instead of formatted text, it prints exactly one JSON document to standard output and nothing else — no progress messages, no partial output, nothing on standard error to interleave with it.

## The envelope

**Success:**

```json theme={null}
{
  "ok": true,
  "exit_code": 0,
  "command": "pint get",
  "data": { "…": "…" },
  "_links": { "…": "…" },
  "next": [ { "command": "…", "reason": "…" } ]
}
```

**Error:**

```json theme={null}
{
  "ok": false,
  "exit_code": 1,
  "command": "pint get",
  "error": {
    "code": "PINT-404-001",
    "title": "Mandate not found. Check the ID and try again.",
    "detail": "No mandate with that id.",
    "status": 404,
    "trace_id": "abc-123"
  },
  "next": [ { "command": "sumvin pint list", "reason": "See your mandates." } ]
}
```

`data` is present only when `ok` is `true`; `error` is present only when `ok` is `false`. `error`'s fields are always present — `null` rather than omitted — so a script never has to check for a missing key before reading one.

## `ok` is not the verdict

`ok` means the command completed — it reached your account, got an answer, and didn't crash. It does **not** mean "the answer is yes."

The clearest example: verifying a Stamped Mandate that turns out to be invalid is a completely successful run whose answer is no.

```json theme={null}
{
  "ok": true,
  "exit_code": 2,
  "command": "pint verify",
  "data": { "valid": false }
}
```

**Always read `exit_code` (or the command's own verdict field, such as `data.valid`) for check-style commands. Never branch on `ok` alone.**

## Exit codes

| Code | Meaning                                                                                                                   |
| ---- | ------------------------------------------------------------------------------------------------------------------------- |
| `0`  | Success.                                                                                                                  |
| `1`  | The run itself failed and decided nothing.                                                                                |
| `2`  | The run succeeded, and the answer is no. Only two commands use this: `sumvin pint verify` and `sumvin kyc status --wait`. |

Every other command uses only `0` and `1`. A bare `sumvin kyc status` or `sumvin sigil show` reports state rather than judging it, so even an unwelcome result — a rejected verification, a failed Sigil — is still a successful read and exits `0`.

## `_links` vs `next`

* **`_links`** — what can be done to this result, translated into a runnable `sumvin` command. Reflects what's actually available right now: it only lists actions your account can currently take.
* **`next`** — what the CLI suggests you do now. Appears on errors (pointing at how to fix the problem) and on results with an obvious follow-up.

A `command` in either field is always a complete, runnable command with real arguments filled in — never a placeholder.

## Discovery

Running `sumvin --json` with no command returns the entire command surface as one catalog: every command, its flags, its arguments, and what each exit code means. An agent can learn the whole CLI from a single call, without reading text written for humans.

```bash theme={null}
sumvin --json | jq '.data.commands'
```

Running `sumvin <command> --help --json` returns just that command's descriptor the same way.

## The stdout/stderr guarantee

Under `--json`, nothing the CLI writes for a human — error lines, progress narration, `--debug` diagnostics — reaches standard error. Everything is either a field of the envelope or suppressed entirely. `sumvin <command> --json 2>&1` is always safe to parse.

Long-running commands (`sumvin kyc status --wait`, `sumvin keys add-to-safe`) print nothing at all until they finish. Silence under `--json` is expected, not a hang.

## An env var, if you'd rather not repeat the flag

```bash theme={null}
SUMVIN_CLI_OUTPUT_JSON=1 sumvin login
```

An explicit `--json` on a single call always wins over the environment variable.

## Credential safety

`--json` never emits a signing key or an access token. `sumvin login --json` returns the token's id and expiry, never the token; `sumvin whoami --json` returns token metadata, never the token; `sumvin keys add-to-safe --json` returns the registered address, never the key.

<Tip>**Try asking your agent:** "Run `sumvin --json` and tell me what commands are available."</Tip>
