Skip to main content
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 tests in CI,
  • explore endpoints quickly without writing client code.
The binary is available for macOS, Linux, and Windows on both amd64 and arm64.

Install

1

One-liner install

Run this in your terminal:
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, 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.
2

Reload your shell

Open a new terminal, or source the rc file the installer modified.
retab version
3

Authenticate

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 below.
Prefer not to run a script piped from the internet? Each release also publishes raw binaries on the GitHub releases page. Download, chmod +x, and put it anywhere on your PATH.

Install options

The installer honors a few environment variables:
VariableDefaultPurpose
RETAB_VERSIONlatestPin a specific CLI version (e.g. 0.1.0).
RETAB_INSTALL_DIR$HOME/.retab/binWhere the binary is dropped.
RETAB_NO_MODIFY_PATHunsetSet to 1 to skip the rc-file PATH edit.
RETAB_SKIP_SETUPunsetSet to 1 to skip automatic retab setup.
# 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:
curl -fsSL https://retab.com/install.sh | sh

Uninstall

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.
API keys are environment-scoped. Use rt_test_... for development and CI, rt_live_... for production. See Environments overview and CLI environments for the full model.

Browser OAuth (default on workstations)

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:
export RETAB_API_KEY=rt_live_
retab extractions list
Get a key from the 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 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.
#SourceHeader sent
1--api-key flagApi-Key
2RETAB_API_KEY env varApi-Key
3OAuth tokens in ~/.retab/config.jsonAuthorization: Bearer … (refreshed automatically)
4api_key field in ~/.retab/config.jsonApi-Key
5nothing → error

Inspecting the active credential

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

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 has a matching command group. Output is JSON on stdout so it pipes cleanly into jq.
retab extractions create \
  --file Invoice.pdf \
  --json-schema-file invoice.schema.json \
  --model retab-micro \
  | jq '.output'

Files

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, test, and experiment resources keyed by workflow id, so the CLI takes <workflow-id> as an explicit argument when creating or updating those resources.
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 tests are run-id-first: create a run, poll it, then inspect results.
retab workflows tests runs create <workflow-id> --test-id <test-id>
retab workflows tests runs get <run-id>
retab workflows tests runs results list <run-id>

# Experiments follow the same run shape; metrics live under the experiment run.
retab workflows experiments runs create <workflow-id> <experiment-id>
retab workflows experiments runs get <run-id>
retab workflows experiments runs results list <run-id>
retab workflows experiments runs 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, tests, 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 tests 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 child records from the runs results or runs 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:
    retab completion zsh > "${fpath[1]}/_retab"
    

Configuration reference

Config file

~/.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.

Environment

RETAB_API_KEY, RETAB_BASE_URL — override anything stored on disk. The right choice in CI.

Flags

--api-key, --base-url, --debug — persistent flags on every command. Override env vars.

Binary

Installed at ~/.retab/bin/retab by default. Single static binary, no runtime dependencies.
The --debug flag turns on verbose output (request URLs, response codes, raw bodies). Use it when filing an issue against the CLI.

Troubleshooting

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.
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.
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.
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 .
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.

Get started

Try it

Walk through an end-to-end extraction with the CLI.

GitHub

Source code, releases, and issues live here.