Metadata-Version: 2.4
Name: nace-cli
Version: 0.1.0
Summary: Nace CLI: calibrated decisions and document jobs from the shell
Keywords: drex,nace,cli,document-intelligence
Author: Nace AI
Author-email: Nace AI <engineering@nace.ai>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Dist: nace-sdk>=0.1,<1
Requires-Dist: truststore>=0.10.4,<1
Requires-Python: >=3.11
Project-URL: Homepage, https://console.nace.ai
Project-URL: Documentation, https://console.nace.ai/docs/developer-tools/cli
Description-Content-Type: text/markdown

# nace-cli

`nace` — the [Drex API](https://console.nace.ai/docs) from the shell: calibrated decisions and document jobs.

```bash
pipx install nace-cli    # or: uv tool install nace-cli
nace login               # paste a key from https://console.nace.ai/dashboard/api-keys
```

`nace login` checks the key against Drex before saving it to `~/.nace/config.toml` (mode 0600). `$NACE_API_KEY` and `$NACE_BASE_URL` override the file; `--api-key -` reads the key from stdin for scripts. `nace --version` (or `nace version`) prints the CLI and SDK versions, and `NACE_LOG_LEVEL=debug` logs each request to stderr.

## Decisions

```bash
nace decide --state "I was charged twice for my March invoice." \
  --noul "wants_refund=Is the customer asking for a refund?" \
  --choice "topic=billing,shipping,other: Which topic is it?" \
  --score "urgency=low,medium,high: How urgent is it?"
```

```
wants_refund  noul    0.930
topic         choice  billing (confidence 0.880)
urgency       score   1.400 on low < medium < high (confidence 0.500)
```

`--state` takes text, `@file` or `-` (stdin); a JSON object or array is sent as JSON. Richer questions go in `--questions questions.json`, or a whole request in `--body`. `nace models` lists the models; `-m` picks one. `--json` prints the response body, `request_id` included.

## Documents

```bash
nace parse https://example.com/invoice.pdf > invoice.md
nace parse ./invoice.pdf --format markdown,text -p 1-3 --mode high
nace parse ./locked.pdf --password -          # reads the PDF password from stdin, hidden at a terminal
nace extract ./invoice.pdf --schema invoice.schema.json
nace extract job:<parse job id> --schema-id sch_... --schema-version 2
nace classify ./scan.pdf --class invoice:Invoice --class receipt:Receipt --granularity page
nace split ./batch.pdf --classes classes.json
nace ground ./invoice.pdf --target "total=Total due" --target "Net 30"
```

A `SOURCE` is one of:

- an `https://` URL. The document service picks the parser from the file name's extension, taken from the URL's last path segment; when the link doesn't end in one, name it with `--file-name invoice.pdf`;
- a local file, uploaded into your workspace first at its file name (`--upload-path` picks another path). The same bytes again reuse the file there; an edited file fails with `path_conflict`: pass another `--upload-path`, or `--on-conflict new_version` to add a version (jobs on that file not yet started then read the new version);
- `ws:<workspace_id>/<file_id>`, what `nace upload` prints;
- `job:<parse job id>` to reuse a finished parse (not for `classify`, `-p`, `--mode medium|high` or `--password`).

`-p/--pages` and `--mode` apply to parse, split, classify and extract. `--semantic` (deprecated) asks Ground to match each target by meaning; on PDF, Word and PowerPoint those targets fail with `semantic_mode_deprecated`. Any other request field goes in `--option key=value` (dotted keys nest, JSON values parse) or `--options request.json`; flags win over both, and the source always comes from `SOURCE`.

Each command waits for the job and prints Markdown for a parse, the result JSON otherwise. For a document too large to return inline, `nace parse` fetches the full Markdown instead of the preview; when it can't, it prints the preview, names the `nace file` command that fetches the rest, and exits `1`. `-o json` prints the whole job, `-o result` only the result, `-o id` the job id; `--save PATH` writes it to a file. `--async` prints the job id and returns at once; `--watch` streams progress to stderr; `--wait-seconds N` asks Drex to hold the create up to 60 s; `--wait-timeout` bounds the client-side wait (default 600 s).

## Uploads

```bash
nace upload ./invoice.pdf --path invoices/2026/invoice.pdf --on-conflict new_version
nace upload-grant --path inbox/scan.pdf --max-bytes 10000000   # a one-use upload token for another client
nace upload-session --path big.csv --total-size-bytes 734003200
```

`upload-grant` and `upload-session` print JSON for another client to upload with: the CLI doesn't send parts or complete a session itself, and `nace upload` (or a local-file `SOURCE`) does every step for you.

## Jobs and their files

```bash
nace jobs --operation parse --status succeeded --limit 50 --cursor <next_cursor>
nace job <id> --wait                      # --watch implies --wait
nace events <id>                          # progress, one JSON object per line
nace job-request <id>                     # the request the job ran under
nace file <id> <document.content_url>     # full Markdown, saved as <id>.md
nace file <id> parse-images/<ref> --save figure-1.png
nace rows <id> <rows_url> --all > sheet.tsv
nace cancel <id>
```

`nace file` saves any file a job produced, waiting for Markdown still being prepared. Without `--save` it goes in the current directory as `<id>.md` for a document's Markdown, else `<id>-<kind>-<digest>` with the file's extension. `--link` prints a stored file's five-minute signed link instead.

## Saved extraction schemas

```bash
nace schema-create Invoice --schema invoice.schema.json
nace schema-version-add sch_... --schema invoice-v2.schema.json
nace schemas --all
nace schema-versions sch_...              # oldest first
nace schema sch_... > invoice.schema.json # the JSON Schema itself; --json for the whole record
nace schema-version sch_... 1
```

## Output and exit codes

Stdout carries the payload and stderr the status, so `nace parse doc.pdf > doc.md` captures only the document. Exit `0` on success, `1` on an API or job failure (the message names the error type, code, request id and up to five fields that failed validation), `2` on a usage or configuration error.

Requests are retried up to twice on a `408`, `429`, `5xx`, dropped connection or timeout, but only while the retry can start within 30 s of the first attempt, so a request that fails after 30 s, such as one that hit `--timeout` (120 s) or a slow `529`, is not retried. `schema-create` and `schema-version-add` are never retried.

Full guide: https://console.nace.ai/docs/developer-tools/cli (install, sign-in, `decide`, documents, uploads, jobs, schemas, exit codes).

## License

MIT
