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

# CLI usage

> Command reference for the caesar-search CLI: search, read, feedback, JSON output, and the exit-code contract.

The standard loop is search, pick a `doc_id`, read it, optionally send feedback:

```bash theme={"system"}
caesar-search search "kubernetes operator patterns" --max-results 5 --format compact --json -o /tmp/search.json
DID=$(jq -r '.results[0].doc_id' /tmp/search.json)
SID=$(jq -r '.search_id' /tmp/search.json)
caesar-search read "$DID" --query "reconciliation loop" --json
caesar-search feedback --event-type result_helpful --search-id "$SID" --doc-id "$DID"
```

Keep returned source URLs and IDs (`doc_id`, `search_id`, `capture_id`, `canonical_url`) when you need to audit or cite a result. See [provenance](/concepts/provenance).

## Commands

| Command                              | Does                                                                                       | Key flags                                                                                            |
| ------------------------------------ | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
| `search <query\|->`                  | Web search                                                                                 | `--max-results`, `--format`                                                                          |
| `read <url\|doc_id\|->`              | Read a page as markdown (aliases: `fetch`, `extract`)                                      | `--query`, `--max-chars`, `--start-char`, `--include`                                                |
| `feedback`                           | Send result feedback                                                                       | `--event-type` (required), `--search-id`, `--doc-id`, `--passage-id`, `--query`, `--rank`, `--notes` |
| `files upload <path...>`             | Upload to your [files knowledge base](/concepts/files) and index                           | `--no-index`, `--content-type`                                                                       |
| `files list\|delete\|index\|status`  | Manage uploads and indexing runs                                                           | `--mode` (index)                                                                                     |
| `usage`                              | Your organization's [API usage](/api-reference): requests, errors, latency, spend          | `--from`, `--to`, `--interval`, `--key-id`                                                           |
| `auth status\|login\|logout`         | Manage the stored API key; `login` opens the browser                                       | `--key`, `--device`, `--no-open`, `--insecure-storage`                                               |
| `config get\|set\|unset\|list\|path` | Manage config keys `api_key`, `base_url`, `oauth_issuer`, `oauth_client_id`, `console_url` | —                                                                                                    |
| `api <method> <path>`                | Raw authenticated API call (escape hatch)                                                  | `--input <file\|->`                                                                                  |
| `update`                             | Channel-aware self-update                                                                  | `--check`                                                                                            |
| `version`                            | Print version, commit, and build date                                                      | —                                                                                                    |
| `completion <shell>`                 | Completion script for `bash`, `zsh`, or `fish`                                             | —                                                                                                    |

## Global flags

Available on every command:

| Flag                  | Meaning                                                       | Default                           |
| --------------------- | ------------------------------------------------------------- | --------------------------------- |
| `--json`              | Machine output: data on stdout, JSON error envelope on stderr | off (human output)                |
| `-o, --output <file>` | Write data output to a file and suppress stdout               | —                                 |
| `--key <key>`         | API key (overrides `CAESAR_API_KEY` and the config file)      | —                                 |
| `--base-url <url>`    | API base URL (overrides `CAESAR_BASE_URL`)                    | `https://alpha.api.trycaesar.com` |
| `--no-retry`          | Disable rate-limit/5xx retries                                | retries on                        |
| `--timeout <seconds>` | Request timeout in seconds                                    | `30`                              |

`--format` is not a global flag — it belongs to `search` only.

## search

| Flag            | Values                                    | Default    |
| --------------- | ----------------------------------------- | ---------- |
| `--max-results` | integer 1–50                              | `10`       |
| `--format`      | `ids_only`, `compact`, `standard`, `full` | `standard` |

`--format` maps to the API's [response shaping](/concepts/response-shaping) verbosity: `compact` is the token-efficient choice for search-then-read loops, `standard` adds quotable passages, `full` adds capture provenance.

## read

The target should be a full URL (`https://…`) or a `doc_id` UUID; a scheme-less target (e.g. `example.com`) is normalized to `https://` by the API.

| Flag           | Values                                                    | Default            |
| -------------- | --------------------------------------------------------- | ------------------ |
| `--query`      | query context for the read                                | —                  |
| `--max-chars`  | optional content character cap, 1–50000                   | —                  |
| `--start-char` | resume a truncated read from this offset                  | `0`                |
| `--include`    | comma list of `metadata,content,passages,capture_history` | `metadata,content` |

A truncated read reports `content.truncated: true` plus `content.char_count` and `content.start_char` (omitted when 0). Continue with `--start-char` set to start plus count — don't retry with a bigger `--max-chars`:

```bash theme={"system"}
caesar-search read https://en.wikipedia.org/wiki/Web_crawler --max-chars 4000 --json
# content.truncated: true, content.char_count: 4000 (content.start_char omitted when 0)
caesar-search read https://en.wikipedia.org/wiki/Web_crawler --start-char 4000 --json
```

## feedback

`--event-type` is required. Values: `result_helpful`, `result_not_helpful`, `passage_used`, `read_abandoned`, `duplicate_result`, `stale_result`, `spam_or_low_quality`, `missing_expected_source`, `unsafe_or_policy_issue`. Pair it with `--search-id` and/or `--doc-id` so the event lands on the right target.

## files

Upload documents into your organization's [files knowledge base](/concepts/files) and search them with the workspace scope:

```bash theme={"system"}
caesar-search files upload ./q3-report.pdf          # presign → upload → auto-index
caesar-search files upload a.md b.csv --no-index    # batch now…
caesar-search files index                           # …index once
caesar-search files status <sync-id>                # poll the run
caesar-search files list
caesar-search files delete "q3-report.pdf"
```

The upload PUTs the bytes straight to storage via a presigned URL — the API key is never sent to storage. `--mode full` on `files index` reprocesses everything instead of just new/changed files.

## usage

See your organization's API usage rendered in the terminal — headline totals, a request sparkline, per-endpoint and per-key tables, and billable spend:

```bash theme={"system"}
caesar-search usage                                  # last 30 days, day buckets
caesar-search usage --from 2026-07-16 --interval hour
caesar-search usage --key-id <api-key-uuid>          # one key only; repeat the flag for several
caesar-search usage --json | jq .headline
```

Notes:

* All numbers are scoped to the organization that owns the API key. The data matches the console's usage dashboard.
* Spend fields are `spend_cents` (exact, possibly fractional cents). The human view formats them as dollars.
* The window is at most 92 days; `--interval hour` needs a range of 8 days or less.
* `--key` sets the API key; the per-key filter is `--key-id`.

## Reading from stdin

`-` reads stdin to EOF for the `search` query, the `read` target, `auth login --key -`, and `api --input -`:

```bash theme={"system"}
echo "model context protocol spec" | caesar-search search - --json | jq -r '.results[0].doc_id'
```

## JSON output

With `--json`, data is a single JSON object on stdout and errors are a JSON envelope on stderr (`hint` only when present):

```json theme={"system"}
{"error": {"code": "rate_limited", "message": "rate limit exceeded", "hint": "Rate limited. Wait and retry, or lower request volume."}}
```

All fields are snake\_case, exactly as the API returns them. Human (non-`--json`) output is not a stable interface — never parse it.

`-o <file>` writes the data payload to the file and suppresses stdout entirely, so output limits can't truncate JSON mid-parse. The agent pattern is write-then-read:

```bash theme={"system"}
caesar-search search "rust async runtimes compared" --format compact --json -o /tmp/out.json
cat /tmp/out.json
```

Errors still go to stderr, and the exit code is unchanged.

## Exit codes

| Code | Meaning                                                          |
| ---- | ---------------------------------------------------------------- |
| 0    | success (includes `--help` and `--version`)                      |
| 2    | bad input (validation errors, unknown flags, usage errors)       |
| 3    | auth error (HTTP 401/403)                                        |
| 4    | API error (other HTTP errors, network failures, update failures) |
| 5    | timeout                                                          |

Branch on these, not on output parsing — see [Scripting and CI](/clients/cli/automation).

## For agents

| Mistake                                             | Correction                                                              |
| --------------------------------------------------- | ----------------------------------------------------------------------- |
| `--results`, `--limit`, `-n`                        | The flag is `--max-results`                                             |
| `--response-format`                                 | The flag is `--format` (values: ids\_only, compact, standard, full)     |
| Passing a bare domain to `read`                     | `read` needs a full URL (`https://…`) or a `doc_id` UUID                |
| Retrying a truncated read with bigger `--max-chars` | Use `--start-char` to continue from where it stopped                    |
| Parsing human output                                | Use `--json`; human output is not a stable interface                    |
| Shell-redirecting and also reading stdout           | Use `-o <file>`; it suppresses stdout so nothing competes with the file |
| `npm update -g` / `brew upgrade` by hand            | `caesar-search update` picks the right channel itself                   |
| Expecting camelCase JSON                            | All fields are snake\_case, exactly as the API returns them             |
| `caesar search`                                     | The binary is `caesar-search`                                           |
