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

# Command reference

> Every Airscale CLI 0.2.1 command and flag for setup, authentication, completion, search, file enrichment, credits, and runs.

This reference covers `@airscale/cli` **0.2.1**. Start with [Airscale CLI](/cli/overview) for the free first-run workflow.

## Global flags and help

| Flag               | Description                                                                                   |
| ------------------ | --------------------------------------------------------------------------------------------- |
| `--json`           | Write JSON to stdout. For `enrich file`, this applies to the summary, not the completed file. |
| `--base-url <url>` | Override `AIRSCALE_API_BASE_URL`. Default: `https://api.airscale.io/v1`.                      |
| `--quiet`          | Hide progress and informational messages. Errors and result output remain visible.            |
| `-V, --version`    | Show the CLI version.                                                                         |
| `-h, --help`       | Show help for the current command.                                                            |

Use `airscale help [command]` for a top-level group or append `--help` to any nested command.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale --version
airscale help auth
airscale setup --help
airscale people search --help
airscale enrich file --help
```

### Output flags

These flags are available on `credits`, `people search`, `companies search`, `runs status`, and `runs wait`.

| Flag                | Description                                                                                                                          |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `--output <path>`   | Write to a file. `--output -` writes the selected result format to stdout.                                                           |
| `--format <format>` | One of `json`, `jsonl`, `csv`, or `table`. Defaults to a table in an interactive terminal and JSON otherwise or when writing a file. |
| `--jsonl`           | Emit one JSON object per line. Search output contains result records.                                                                |

All result formats go to stdout when no file path is selected, including tables. Progress and errors go to stderr. The global `--json` flag wins over `--jsonl`, which wins over `--format`.

JSON search output preserves the response envelope and continuation cursor. CSV and JSONL contain result records. Select the format explicitly when writing a `.csv` or `.jsonl` search file; the filename does not select its format.

### Credit flags

These flags are available on both search commands and `enrich file`.

| Flag                      | Description                                                                                                                                                                                                                     |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--confirm-credit-spend`  | Confirm the maximum credit exposure. Required to start fresh paid work in non-interactive mode; otherwise the CLI asks in the terminal.                                                                                         |
| `--max-credits <credits>` | Plain positive decimal that caps maximum exposure, such as `0.5` or `4`, up to `9,007,199,254,740,991`. Scientific notation, `Infinity`, hexadecimal, and signed values are rejected. This does not replace spend confirmation. |

Credit checks are free. Search costs 0.1 credit per returned result. File enrichment previews a maximum of 2 credits per row. Row counts, page sizes, and limits remain positive integers.

## Authentication

### `airscale auth login`

Store a workspace API key through a hidden terminal prompt. It takes no arguments or command-specific flags and requires an interactive terminal.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale auth login
```

After saving the key, the CLI shows `airscale auth status` as the next step. The optional system keychain is used when available; otherwise the CLI writes a restricted local credential file. `AIRSCALE_API_KEY` overrides the saved key. There is no API-key command-line flag.

`airscale auth set-key` remains an alias for compatibility:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale auth set-key
```

### `airscale auth status`

Check configured authentication and API connectivity with a free `/credits` request. It takes no arguments or command-specific flags; use global `--json` for machine-readable status.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale auth status --json
```

A successful status includes `configured`, `connected`, `source`, `fingerprint`, and `base_url`. Missing credentials produce `configured: false`, `connected: false`, and `source: "none"`, then exit `3`. Invalid credentials also exit `3`. The full API key is never displayed.

### `airscale auth logout`

Remove locally saved credentials. It takes no arguments or command-specific flags.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale auth logout
```

This does not revoke the API key. If `AIRSCALE_API_KEY` is set, it remains active until removed from the environment.

## Guided setup

### `airscale setup`

Guide an interactive user through authentication and a free connectivity check.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale setup
```

The command points to the [Airscale dashboard](https://app.airscale.io/dashboard) and tells the user to choose **Settings → API key**, then checks whether a credential is already configured. If one exists, it skips the key prompt. If none exists, it accepts the key through a hidden prompt. It finishes by checking `/credits`, which does not spend credits.

In a non-interactive environment, `setup` fails before it reads any credential or makes an HTTP request. For CI, set `AIRSCALE_API_KEY` through a secret manager and run `airscale auth status --json` when a free connectivity check is needed.

## Shell completion

### `airscale completion <shell>`

Print a completion script for `bash` or `zsh`.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale completion bash
airscale completion zsh
```

The command writes the shell script only to stdout. It does not edit a shell profile, create files, or enable completion automatically. Review the output, then explicitly source it or save it in the completion directory used by your shell. See [Troubleshooting](/cli/troubleshooting#enable-shell-completion) for opt-in examples.

## Credits

### `airscale credits`

Show the authenticated workspace's remaining credits. This request is free and supports all [output flags](#output-flags).

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale credits --json
airscale credits --format csv --output credits.csv
```

## Search

### Shared search flags

Both searches support the [output flags](#output-flags), [credit flags](#credit-flags), and these request and pagination flags:

| Flag                | Description                                                                                                                           |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `--request <path>`  | Read an advanced public API request from a JSON file. Cannot be combined with convenience filters.                                    |
| `--size <size>`     | Integer page size from `1` to `100`. Defaults to `100` for people and `50` for companies; a company cursor carries its own page size. |
| `--cursor <cursor>` | Continue a previous search. Overrides the request file's cursor.                                                                      |
| `--all`             | Follow continuation cursors until exhausted or the row limit is reached.                                                              |
| `--limit <rows>`    | Integer maximum from `1` to `10000`. With `--all`, defaults to `10000`. Without `--all`, limits one page.                             |

`--size` also overrides a request file's size. Without `--all`, maximum exposure is the smaller of the page size and `--limit`. With `--all`, it is `--limit` (or 10,000) multiplied by 0.1 credits.

People page sizes shrink to the remaining row budget. Company cursors require a full page: the CLI stops before another page would exceed `--limit` and preserves its continuation cursor. Keep the filters unchanged when continuing with `next_cursor`.

Paid search requests are not automatically retried. If a response is lost or ambiguous, inspect API request logs before repeating the search.

### `airscale people search`

Search for people with convenience filters or an advanced [Find People request](/api-reference/find-people).

| Flag                        | Description                                         |
| --------------------------- | --------------------------------------------------- |
| `--title <value>`           | Job title. Repeat to include multiple titles.       |
| `--company-domain <domain>` | Company domain. Repeat to include multiple domains. |
| `--location <value>`        | Location. Repeat to include multiple locations.     |

Also supports every [shared search flag](#shared-search-flags).

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale people search \
  --title CTO --company-domain northstar.example \
  --size 5 --max-credits 0.5 \
  --confirm-credit-spend --json
```

For advanced filters, save a JSON object with the public request schema:

```json people-query.json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "query": {
    "JobTitle": { "include": ["CTO"], "exclude": ["Assistant"] },
    "currentCompany.headcount": { ">=": 20, "<=": 200 }
  },
  "size": 25
}
```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale people search --request people-query.json \
  --max-credits 2.5 --confirm-credit-spend \
  --jsonl --output people.jsonl
```

Unknown top-level request keys and filter names are rejected before the search.

### `airscale companies search`

Search for companies with convenience filters or an advanced [Find Companies request](/api-reference/find-companies). At least one real filter is required.

| Flag                 | Description                                      |
| -------------------- | ------------------------------------------------ |
| `--country <value>`  | Country. Repeat to include multiple countries.   |
| `--industry <value>` | Industry. Repeat to include multiple industries. |

Also supports every [shared search flag](#shared-search-flags).

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale companies search \
  --country France --country Germany --industry Software \
  --size 50 --all --limit 200 \
  --max-credits 20 --confirm-credit-spend \
  --format csv --output companies.csv
```

Advanced requests use the public `filters` object. See [company filter values](/api-reference/find-companies/filter-values) for supported values.

```json company-query.json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "filters": {
    "country": ["France"],
    "industry": ["Software"]
  },
  "size": 20
}
```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale companies search --request company-query.json \
  --max-credits 2 --confirm-credit-spend --json
```

## File enrichment

### `airscale enrich file <input>`

Validate a CSV or JSONL file locally, or enrich it with professional work emails through one durable run.

| Argument or flag      | Description                                                                                                                                 |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `<input>`             | A `.csv` or `.jsonl` path, or `-` to read stdin and detect the format. Maximum 10,000 records.                                              |
| `--output <path>`     | Required for paid execution and optional with `--dry-run`. Must differ from the input and cannot be `-`. A dry run never writes the output. |
| `--field <field>`     | Defaults to `work_email`, the only supported field.                                                                                         |
| `--format <format>`   | Completed-file format: `csv` or `jsonl`. Inferred from an explicit `.jsonl` output path; otherwise defaults to CSV.                         |
| `--dry-run`           | Validate every row and preview maximum exposure locally, without credentials, HTTP requests, or credit spend.                               |
| `--resume`            | Continue the saved run with the same input, output, field, format, and API URL. With no saved state, prepares fresh paid work.              |
| `--state-file <path>` | Override the default `<output>.airscale-state.json`. Must differ from the input and output paths.                                           |

Also supports the [credit flags](#credit-flags). Global `--json` formats the summary; it does not change the completed-file format. `--jsonl` is not an enrichment flag.

#### Input columns

Each row needs either:

* `linkedin_profile_url`; or
* `first_name` and `last_name`, with `domain` or `company_name`.

```csv contacts.csv theme={"theme":{"light":"github-light","dark":"github-dark"}}
first_name,last_name,domain
Avery,Stone,northstar.example
Morgan,Lee,solstice.example
```

CSV headers are trimmed, lowercased, and normalized so spaces or hyphens become underscores for identity matching. Original columns and values remain in the output. CSV quoting, embedded newlines, UTF-8 BOMs, and Unicode are supported. JSONL records must be objects.

Invalid identities, duplicate normalized headers, invalid CSV, malformed JSONL, and duplicate `custom_id` values stop the command before HTTP. Row-level identity and JSONL validation errors are reported together. Missing IDs become `airscale-row-1`, `airscale-row-2`, and so on.

#### Preview

No output path is needed for a local preview:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale enrich file contacts.csv --dry-run --json --quiet
```

The summary reports `output: null` and defaults `format` to `csv` when `--output` and `--format` are absent. An explicit output remains allowed during a dry run and can infer the format:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale enrich file contacts.csv \
  --output preview-shape.jsonl --dry-run --json
```

The output path is included in the summary, but no completed file or state file is written.

#### Start or resume paid work

Fresh paid execution requires an explicit output path, credit confirmation, and a budget in these examples:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale enrich file contacts.csv \
  --output contacts-enriched.csv --max-credits 4 \
  --confirm-credit-spend --resume --json
```

For stdin and JSONL output:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
cat contacts.csv | airscale enrich file - \
  --output contacts-enriched.jsonl --format jsonl \
  --max-credits 4 --confirm-credit-spend --resume --json
```

To resume stdin, supply the exact same input bytes again.

#### Output and recovery

Results add `custom_id`, `work_email`, `email_status`, and `status` when returned. Existing input fields are preserved; collisions receive an `airscale_` prefix and then a numeric suffix when needed.

The CLI verifies completed metadata, format, row count, and custom-ID order before committing the output atomically. An existing output with different content is preserved.

Keep the state file until the run is fully reconciled. It records the input hash, output path, field, format, API URL, batch ID, run ID, and idempotency key without API credentials. `--resume` refuses mismatched inputs and continues the same batch and run after a lost upload or start response. It never creates a replacement batch automatically.

Ctrl-C aborts local requests and polling, removes temporary downloads, retains state, and exits `130`. It does not cancel server work. Resume with the original command to retrieve the result. An unknown start handoff is reported for inspection and is not replayed automatically.

Locks protect both output and state paths. If a crash leaves a reported `.airscale-lock` file, inspect its PID and remove the lock only after that process has stopped, then resume.

## Runs

Run IDs start with `exp_`. Both commands perform free reads and support all [output flags](#output-flags).

### `airscale runs status <id>`

Fetch the current status of a durable enrichment run once.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale runs status exp_example --json
```

A failed run is returned as status data. Use `runs wait` when a failed run should produce a failing exit code.

### `airscale runs wait <id>`

Poll until a run completes or fails. A failed run exits `5`.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
airscale runs wait exp_example --json
airscale runs wait exp_example --quiet --output run.json
```

Polling follows the server's `poll_after_seconds` hint, waits at least one second, caps the delay at 30 seconds, and adds jitter. Transient `429` and `5xx` responses retry with bounded backoff. Other `4xx` responses fail immediately.

## 0.2.0 to 0.2.1 compatibility

Version 0.2.1 keeps the same commands, flags, credentials, and saved enrichment state as 0.2.0.

* Before authentication or API requests, `credits`, `people search`, `companies search`, `runs status`, and `runs wait` check any `--output` file destination. A directory or an unwritable destination exits `2` without starting paid work. Existing files are not truncated by this check. Local `--dry-run` still makes no HTTP requests and writes no output file.
* API errors retain sanitized request IDs when the server supplies them, including interrupted-response errors and ambiguous paid-search failures. Include the `request_id` in a support report when present. Exit codes and the rule against automatically retrying paid searches are unchanged.

See [upgrade instructions](/cli/troubleshooting#upgrade-the-cli) before using a saved global installation.

## 0.1.0 to 0.2.0 compatibility

* `airscale auth login` is the canonical key-storage command. Existing `airscale auth set-key` calls continue to work as an alias.
* Version 0.1.0 wrote an interactive table result to stderr. Version 0.2.0 writes every result format, including tables and `--output -`, to stdout. Progress and errors remain on stderr.
* `enrich file --dry-run` no longer needs `--output`. Supplying one remains valid. Fresh paid execution still requires a real output path.
* `--max-credits` now accepts a plain positive decimal budget, including values such as `0.5`, up to `9,007,199,254,740,991`. Scientific notation and `Infinity` are rejected. Count flags such as `--size` and `--limit` still require integers.
* `setup` and `completion` are opt-in commands. They do not change existing scripts unless invoked.

## Environment and exit codes

| Setting                 | Precedence or default                                                                         |
| ----------------------- | --------------------------------------------------------------------------------------------- |
| `AIRSCALE_API_KEY`      | Overrides a saved credential. Use a CI secret manager.                                        |
| `AIRSCALE_API_BASE_URL` | Overridden by `--base-url`; otherwise defaults to `https://api.airscale.io/v1`.               |
| `XDG_CONFIG_HOME`       | Stores local configuration under `$XDG_CONFIG_HOME/airscale`; otherwise `~/.config/airscale`. |

API URLs must use HTTPS, except HTTP loopback URLs. URLs containing credentials, query parameters, or fragments are rejected.

| Exit code | Meaning                                                                   |
| --------- | ------------------------------------------------------------------------- |
| `0`       | Success.                                                                  |
| `2`       | Invalid command, option, input, state, or file access.                    |
| `3`       | Missing or invalid authentication or configuration.                       |
| `4`       | Credit ceiling, insufficient credits, confirmation, or admission failure. |
| `5`       | API or durable-run failure.                                               |
| `130`     | Interrupted with Ctrl-C; enrichment state is retained.                    |
