# Cheqi CLI

The Cheqi CLI (`@cheqi/cli`) is a command-line tool for the encrypted receipt flow. It wraps the [JavaScript SDK](/sdk/javascript) so that matching, receipt building, encryption, and submission can be driven from a shell — or, more importantly, from an autonomous agent.

Every command reads structured input and writes a single, machine-readable JSON envelope to standard output. There is no human-only prose to parse, no interactive prompts, and no ambiguity about success or failure. This makes the CLI a natural tool surface for LLM agents that already know how to run shell commands.

The CLI performs all cryptography locally (in-process, through the SDK) and talks to the Cheqi REST API directly. It never asks Cheqi to join plaintext match results with template data or to encrypt receipts, so it preserves the same [zero-knowledge boundary](/mcp/overview#zero-knowledge-boundary) as the SDK and the MCP flow.

## Installation

The CLI requires Node.js 20 or newer.

```bash
npm install -g @cheqi/cli
```

Then invoke it as `cheqi`:

```bash
cheqi version
```

You can also run it without installing globally:

```bash
npx @cheqi/cli version
```

## Why it is built for agents

The CLI is deliberately designed so an agent can use it reliably without guesswork:

- **Uniform JSON envelope.** Every command returns the same top-level shape, so an agent parses one structure regardless of the command.
- **Explicit success/failure.** The `ok` field is authoritative, and the process exit code matches it (`0` on success, `1` on failure).
- **Retryable errors.** Every error carries a `retryable` flag, so an agent can distinguish transient failures (back off and retry) from input errors (re-plan).
- **Stable error codes.** Errors use a fixed set of machine-dispatchable codes instead of free-text messages.
- **Self-describing schema.** The `schema` command emits a machine-readable description of every command, its flags, and its response shape — agents can discover capabilities at runtime instead of relying on documentation.
- **Guided next steps.** Most responses include a `nextStep` object that names the next valid command, so an agent can chain a multi-step flow without hard-coding the sequence.
- **Pure stdout.** Standard output contains only the JSON envelope. Diagnostic logging (enabled with `--verbose`) is written to standard error, so it never corrupts the parsed output.


## Response envelope

A successful command:

```json
{
  "ok": true,
  "data": { },
  "meta": { "durationMs": 0, "version": "0.2.0" }
}
```

A failed command:

```json
{
  "ok": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable message",
    "retryable": false,
    "details": { }
  },
  "meta": { "durationMs": 0, "version": "0.2.0" }
}
```

| Field | Meaning |
|  --- | --- |
| `ok` | `true` on success, `false` on failure. Matches the process exit code. |
| `data` | Command-specific result object (only on success). |
| `error.code` | Stable, machine-readable error code (see [Error codes](/cli/commands#error-codes)). |
| `error.message` | Human-readable explanation. |
| `error.retryable` | `true` if retrying the same command may succeed. |
| `error.details` | Optional structured context (e.g. the offending session id). |
| `meta.version` | CLI version that produced the response. |
| `meta.durationMs` | Wall-clock duration of the command. |


## Two ways to use it

The CLI supports both a stateful and a stateless workflow:

- **Sessions** (`session …`, `receipt …`) build a receipt incrementally on local disk. Each step is a separate command, so an agent can create a draft, add products, match the customer, and finalize across multiple tool calls. Sessions are stored as JSON files under `.cheqi/sessions/<id>.json` in the current working directory, and `--session <id>` isolates concurrent workflows.
- **Direct submission** (`receipts submit`) sends a complete receipt JSON document (from a file or stdin) in a single command, without creating a session.


See [Agent Workflows](/cli/agent-workflows) for end-to-end examples of both.

## Configuration

Network commands need an API endpoint and a credential. Both can be supplied as flags or environment variables; flags take precedence.

| Setting | Flag | Environment variable | Default |
|  --- | --- | --- | --- |
| Environment | `--env <sandbox|test|production>` | `CHEQI_ENV` | `sandbox` |
| Custom endpoint | `--endpoint <url>` | `CHEQI_API_ENDPOINT` | — |
| API key | `--api-key <key>` | `CHEQI_API_KEY` | — |
| OAuth access token | `--access-token <token>` | `CHEQI_ACCESS_TOKEN` | — |
| Request timeout (seconds) | `--timeout <n>` | `CHEQI_TIMEOUT_SECONDS` | `30` |


The named environments map to:

| `--env` | Endpoint |
|  --- | --- |
| `sandbox` | `https://sandbox.api.cheqi.io` |
| `test` | `https://test.api.cheqi.io` |
| `production` | `https://api.cheqi.io` |


### Authentication

Network commands (`session match`, `receipt finalize`, `receipts submit`) require **exactly one** credential — either an API key or an OAuth access token:

- Providing neither returns `AUTH_REQUIRED`.
- Providing both returns `AUTH_CONFLICT`.


Local-only commands (`session create`, `session status`, `session reset`, `receipt set`, `receipt add-product`, `receipt preview`, `receipt validate`) do not require authentication because they never touch the network.

## Output and exit codes

- **stdout** always contains exactly one JSON envelope — safe to pipe straight into a parser.
- **stderr** carries SDK diagnostics, and only when `--verbose` is set. Without `--verbose`, the CLI is silent on stderr.
- **Exit code** is `0` when `ok` is `true` and `1` when `ok` is `false`.


This separation means an agent can capture stdout for the result and ignore (or surface) stderr for debugging, without ever risking a parse failure.

## Next steps

- [Command Reference](/cli/commands) — every command, its flags, and its response.
- [Agent Workflows](/cli/agent-workflows) — end-to-end examples and agent integration tips.