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

# CLI

> Drive every Retab primitive — parse, extract, classify, split, edit, partition — from your terminal or a CI pipeline.

The Retab CLI is a single static binary that wraps the same API as the Python, Node, and Go SDKs. It's the right tool when you want to:

* pipe a PDF through `retab extractions create` from a shell script,
* automate workflow evals in CI,
* explore endpoints quickly without writing client code.

The binary is available for **macOS**, **Linux**, and **Windows** on both **amd64** and **arm64**.

***

## Install

<Steps>
  <Step title="One-liner install" stepNumber={1}>
    Run this in your terminal:

    ```sh theme={null}
    curl -fsSL https://retab.com/install.sh | sh
    ```

    The installer detects your OS and architecture, downloads the matching release from [`github.com/retab-dev/retab/releases`](https://github.com/retab-dev/retab/releases), verifies the SHA-256 checksum, drops the binary at `~/.retab/bin/retab`, appends a `PATH` entry to your shell's rc file (`.zshrc`, `.bashrc`, `.bash_profile`, or `~/.config/fish/config.fish`), and runs `retab setup` to install Retab skills and MCP config.
  </Step>

  <Step title="Reload your shell" stepNumber={2}>
    Open a new terminal, or `source` the rc file the installer modified.

    ```sh theme={null}
    retab version
    ```
  </Step>

  <Step title="Authenticate" stepNumber={3}>
    ```sh theme={null}
    retab auth login
    ```

    Opens your browser for an OAuth login through WorkOS (the same identity provider as the dashboard — SSO, Google, email, all work). The CLI captures the callback on a local loopback port, exchanges it for OAuth tokens, and stores them at `~/.retab/config.json` (mode `0600`). Tokens refresh transparently.

    For headless setups (CI, servers, no browser), use an API key directly — see [Authentication](#authentication) below.
  </Step>
</Steps>

<Tip>
  Prefer not to run a script piped from the internet? Each release also
  publishes raw binaries on the [GitHub releases
  page](https://github.com/retab-dev/retab/releases). Download, `chmod +x`, and
  put it anywhere on your `PATH`.
</Tip>

### Install options

The installer honors a few environment variables:

| Variable               | Default            | Purpose                                     |
| ---------------------- | ------------------ | ------------------------------------------- |
| `RETAB_VERSION`        | latest             | Pin a specific CLI version (e.g. `0.1.0`).  |
| `RETAB_INSTALL_DIR`    | `$HOME/.retab/bin` | Where the binary is dropped.                |
| `RETAB_NO_MODIFY_PATH` | unset              | Set to `1` to skip the rc-file `PATH` edit. |
| `RETAB_SKIP_SETUP`     | unset              | Set to `1` to skip automatic `retab setup`. |

```sh theme={null}
# pin a version, install to a custom dir, leave PATH alone
curl -fsSL https://retab.com/install.sh \
  | RETAB_VERSION=0.1.0 RETAB_INSTALL_DIR=/usr/local/bin RETAB_NO_MODIFY_PATH=1 sh

# install the binary only; run `retab setup` yourself later
curl -fsSL https://retab.com/install.sh | sh -s -- --no-setup
```

### Upgrade

Re-run the installer — it always installs the latest published release:

```sh theme={null}
curl -fsSL https://retab.com/install.sh | sh
```

### Uninstall

```sh theme={null}
retab auth logout            # removes ~/.retab/config.json
rm -rf ~/.retab              # removes the binary and config dir
# then drop the `export PATH=…` line the installer added to your shell rc
```

***

## Authentication

The CLI supports two auth modes. **Pick OAuth on your laptop, API keys in CI.**

<Tip>
  API keys are environment-scoped. Use `rt_test_...` for development and CI,
  `rt_live_...` for production. See [Environments overview](/environments/overview)
  and [CLI environments](/environments/cli) for the full model.
</Tip>

### Browser OAuth (default on workstations)

```sh theme={null}
retab auth login
```

Opens your browser, runs an OAuth Authorization Code + PKCE flow against WorkOS, and writes the resulting access + refresh tokens to `~/.retab/config.json`. Subsequent commands send `Authorization: Bearer <token>` and refresh transparently when the access token nears expiry.

The redirect lands on `http://127.0.0.1:<random-port>/callback` — nothing leaves your machine except the request to your identity provider. The flow times out after 5 minutes if you close the browser without finishing.

### API key (CI, servers, headless boxes)

Any of these three paths works, in order of precedence:

1. **Flag**: `--api-key rt_live_…` on a single command.
2. **Env**: `RETAB_API_KEY=rt_live_…` exported in the shell or CI runner.
3. **Stored**: `retab auth login --api-key rt_live_…` to persist to `~/.retab/config.json`.

In a CI job you typically want option 2:

```sh theme={null}
export RETAB_API_KEY=rt_live_…
retab extractions list
```

Get a key from the [dashboard settings](https://retab.com/dashboard/settings). Use a
`rt_test_...` key for local development and CI, and a `rt_live_...` key for
production. Legacy `sk_retab_...` keys still work and resolve to production.
See [API keys](/environments/api-keys) for the full reference.

### Precedence

The CLI picks credentials in this strict order. **The flag and env paths always win** so an `RETAB_API_KEY` in your environment overrides any logged-in OAuth session — useful when you want to scope a single command to a different identity.

| # | Source                                    | Header sent                                         |
| - | ----------------------------------------- | --------------------------------------------------- |
| 1 | `--api-key` flag                          | `Authorization: Bearer <api-key>`                   |
| 2 | `RETAB_API_KEY` env var                   | `Authorization: Bearer <api-key>`                   |
| 3 | OAuth tokens in `~/.retab/config.json`    | `Authorization: Bearer …` (refreshed automatically) |
| 4 | `api_key` field in `~/.retab/config.json` | `Authorization: Bearer <api-key>`                   |
| 5 | nothing → error                           | —                                                   |

### Inspecting the active credential

```sh theme={null}
retab auth status
```

Prints (as JSON) which source was used, the redacted credential, the API base URL, and whether the credential currently works against the server.

### Switching and clearing

```sh theme={null}
retab auth login                          # OAuth — overwrites any stored API key
retab auth login --api-key rt_live_…      # API key — overwrites any stored OAuth tokens
retab auth login --browser=false          # interactive prompt for an API key, no browser
retab auth logout                         # deletes ~/.retab/config.json entirely
```

***

## Core commands

Every primitive in the [Retab API](../api-reference/introduction) has a matching command group. Output is JSON on stdout so it pipes cleanly into `jq`.

<CodeGroup>
  ```sh Extract structured data theme={null}
  retab extractions create \
    --file Invoice.pdf \
    --json-schema-file invoice.schema.json \
    --model retab-micro \
    | jq '.output'
  ```

  ```sh Generate a schema from samples theme={null}
  retab schemas generate \
    --file Invoice1.pdf --file Invoice2.pdf \
    --model retab-small \
    > invoice.schema.json
  ```

  ```sh Parse to markdown theme={null}
  retab parses create \
    --file Contract.pdf \
    --model retab-small \
    | jq -r '.markdown'
  ```

  ```sh Stream a long extraction theme={null}
  retab extractions stream \
    --file LargeReport.pdf \
    --json-schema-file report.schema.json \
    --model retab-small
  # emits one JSON object per line as tokens stream in
  ```
</CodeGroup>

### Files

```sh theme={null}
retab files upload ./Invoice.pdf          # → returns a file id
retab files list
retab files download <file-id> ./out.pdf  # use `-` for stdout
retab files download-link <file-id>
```

### Workflows

Workflow graph commands operate on flat block, edge, eval, and experiment
resources keyed by workflow id, so the CLI takes `<workflow-id>` as an explicit
argument when creating or updating those resources.

```sh theme={null}
retab workflows list
retab workflows get <workflow-id>
retab workflows runs create <workflow-id> --document start=./invoice.pdf

# Review is configured on a block config, not as a separate block.
printf '%s\n' '{"review":{"predicate":{"kind":"any_required_field_null"}}}' \
  > extract-review.json
retab workflows blocks update <workflow-id> blk_extract_1 \
  --merge-config-file ./extract-review.json

# for_each map-phase review is available for split_by_key partitioning.
printf '%s\n' '{"review":{"predicate":{"kind":"boundary_confidence_lt","threshold":0.8}}}' \
  > for-each-review.json
retab workflows blocks update <workflow-id> blk_for_each_1 \
  --merge-config-file ./for-each-review.json

# Runs paused by review use awaiting_review.
retab workflows runs list --status awaiting_review
retab workflows reviews list
retab workflows reviews get <review-id>
retab workflows reviews approve <review-id> --version-id <version-id>

# Create a corrected output version, then approve its returned version id.
retab workflows reviews versions list <review-id>
retab workflows reviews versions create <review-id> \
  --parent-id <version-id> \
  --snapshot-file ./corrected-output.json
retab workflows reviews approve <review-id> --version-id <new-version-id>

# Workflow evals are run-id-first: create a run, poll it, then inspect results.
retab workflows evals runs create <workflow-id> --eval-id <eval-id>
retab workflows evals runs get <run-id>
retab workflows evals results list <run-id>

# Experiments follow the same run shape; metrics live under the experiment run.
retab workflows experiments runs create <experiment-id>
retab workflows experiments runs get <run-id>
retab workflows experiments results list <run-id>
retab workflows experiments metrics get <run-id> --view summary
```

The full surface — `files`, `parses`, `extractions`, `classifications`, `splits`, `partitions`, `edits`, `schemas`, and the workflow sub-trees (`blocks`, `edges`, `runs`, `artifacts`, `evals`, `experiments`) — follows the same `retab <noun> <verb>` shape. Run `retab <noun> --help` to enumerate verbs, then `retab <noun> <verb> --help` for the flags.

For review corrections, `--parent-id` is required. It must name the existing
review version that the corrected snapshot derives from.

Workflow evals and experiments do not use public `job_id` or `batch_id`
handles. Store the returned run `id`, poll the corresponding `runs get`
command, and read experiment child records from the `experiments results`
or `experiments metrics` subcommands.

***

## Discoverability

The CLI is a tree of commands. Two shortcuts you'll want:

* **`--help` everywhere.** `retab --help` lists nouns; `retab extractions --help` lists verbs; `retab extractions create --help` lists flags.
* **Shell completion.** Generate a completion script once and source it from your shell rc:

  <CodeGroup>
    ```sh zsh theme={null}
    retab completion zsh > "${fpath[1]}/_retab"
    ```

    ```sh bash theme={null}
    retab completion bash > /usr/local/etc/bash_completion.d/retab
    ```

    ```sh fish theme={null}
    retab completion fish > ~/.config/fish/completions/retab.fish
    ```

    ```powershell PowerShell theme={null}
    retab completion powershell | Out-String | Invoke-Expression
    ```
  </CodeGroup>

***

## Configuration reference

<CardGroup cols={2}>
  <Card title="Config file" icon="file-lines">
    `~/.retab/config.json` — written by `retab auth login`, mode `0600`. Holds either an `oauth` block (tokens, expiry, WorkOS domain) or an `api_key`, plus optional `base_url`.
  </Card>

  <Card title="Environment" icon="terminal">
    `RETAB_API_KEY`, `RETAB_BASE_URL` — override anything stored on disk. The
    right choice in CI.
  </Card>

  <Card title="Flags" icon="flag">
    `--api-key`, `--base-url`, `--debug` — persistent flags on every command.
    Override env vars.
  </Card>

  <Card title="Binary" icon="microchip">
    Installed at `~/.retab/bin/retab` by default. Single static binary, no runtime dependencies.
  </Card>
</CardGroup>

The `--debug` flag turns on verbose output (request URLs, response codes, raw bodies). Use it when filing an issue against the CLI.

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="`retab: command not found` after install">
    The installer added `~/.retab/bin` to your shell rc, but the current shell hasn't reloaded it. Either open a new terminal or run `source ~/.zshrc` (or your shell's rc file). On `fish`, run `source ~/.config/fish/config.fish`.
  </Accordion>

  <Accordion title="`401 Unauthorized`">
    Run `retab auth status` — it shows which credential source the CLI is reading
    from and pings the API to verify. If the source is `~/.retab/config.json
          (oauth)` and the access token has expired, the CLI will refresh on its own; if
    the refresh token itself has expired, you'll see `invalid_grant` — run `retab
          auth login` to re-authenticate. If the source is an API key but still 401s,
    double-check the key in the [dashboard
    settings](https://retab.com/dashboard/settings).
  </Accordion>

  <Accordion title="Browser didn't open during `retab auth login`">
    The CLI uses `open` (macOS), `xdg-open` (Linux), or `rundll32 url.dll` (Windows). If none of those are wired up — typical on minimal Docker images or remote SSH — the CLI prints the authorize URL to stderr instead. Copy it into a browser on a machine that can talk to your identity provider; the callback still lands on `127.0.0.1:<port>` of the box where the CLI is running, so port-forward or use `RETAB_API_KEY` instead.
  </Accordion>

  <Accordion title="`unsupported architecture` during install">
    The installer supports `x86_64` and `arm64` only. On other architectures,
    build from source: `git clone https://github.com/retab-dev/retab && cd
          retab/cli && go build -o retab .`
  </Accordion>

  <Accordion title="Checksum mismatch during install">
    A checksum mismatch means the downloaded archive doesn't match the SHA-256 published in `checksums.txt`. Don't bypass the check — re-run the installer (it's idempotent). If it persists, file an issue at [github.com/retab-dev/retab](https://github.com/retab-dev/retab/issues).
  </Accordion>
</AccordionGroup>

***

## Get started

<CardGroup cols={2}>
  <Card title={<div className="card-title">Try it</div>} icon="play" href="../api-reference/introduction">
    <div className="text-lg">
      Walk through an end-to-end extraction with the CLI.
    </div>
  </Card>

  <Card title={<div className="card-title">GitHub</div>} icon="github" href="https://github.com/retab-dev/retab">
    <div className="text-lg">
      Source code, releases, and issues live here.
    </div>
  </Card>
</CardGroup>
