> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. # Features > Explore the capabilities of Fern's generated CLIs, including output formatting, retries, pagination, dry-run mode, and TLS configuration. #### Early access The CLI generator is in early access. [Reach out](https://buildwithfern.com/book-demo?type=cli) to get started. Generated CLIs ship with a common set of runtime flags and environment variables: output formatting, retries with exponential backoff, pagination, dry-run previewing, TLS and proxy configuration, exit codes, and structured logging. APIs with templated server URLs also expose per-variable flags and environment variables. The binary name (set via [`binaryName`](/learn/cli-generator/get-started/configuration#config-options)) determines the environment-variable prefix used by TLS, proxy, and logging settings below. ## Output formatting Use the `--format` flag to control how responses are displayed. | Format | Flag | Description | | ------ | ---------------- | ---------------------------------------------------------------------- | | JSON | `--format json` | Default. Pretty-printed JSON. | | Table | `--format table` | Columnar table. Nested objects flatten to `parent.child` column names. | | YAML | `--format yaml` | YAML representation of the response. | | CSV | `--format csv` | Comma-separated values, suitable for piping into spreadsheet tools. | ```bash # Display plants in a table contoso plants list --format table # Export orders as CSV contoso orders list --format csv > orders.csv ``` ## Dry-run mode Pass `--dry-run` to validate arguments and preview the HTTP request without sending it. The CLI prints the method, URL, headers, and body it would send, then exits. ```bash contoso plants get --params '{"plantId": "abc"}' --dry-run ``` ## Retries with backoff Failed requests are retried automatically with exponential backoff on status codes `408`, `429`, and `5xx`, honoring `Retry-After` headers. | Setting | Default | | -------------- | ----------------------- | | Total attempts | 4 (initial + 3 retries) | | Base delay | 500 ms | | Backoff factor | 2x | | Jitter | 10% | GET, HEAD, OPTIONS, DELETE, and PUT retry by default. POST and PATCH retry only when the operation declares server-side idempotency support with [`x-fern-idempotent: true`](/learn/api-definitions/openapi/extensions/idempotency), which also exposes an `--idempotency-key` flag on that command, or when the caller passes `--idempotency-key` explicitly. Pass `--no-retry` to disable retries for a single invocation. An `Idempotency-Key` header is generated automatically for POST, PUT, and PATCH requests unless the invocation carries its own `--idempotency-key` or the operation opts out with `x-fern-cli-idempotency: false`. The same generated key is sent on every attempt of a request, but the key alone doesn't make a request retry-eligible. ```bash # Disable retries for a single request contoso plants create --json '{"name": "Monstera"}' --no-retry ``` ## Pagination For endpoints annotated with [`x-fern-pagination`](/learn/api-definitions/openapi/extensions/pagination), the CLI auto-paginates when the `--page-all` flag is set. | Flag | Description | Default | | ------------------- | ------------------------------------------------------------------------ | ------- | | `--page-all` | Fetch every page and emit one JSON line per page (NDJSON). | Off | | `--page-limit ` | Maximum number of pages to fetch. | 10 | | `--page-delay ` | Delay in milliseconds between page requests. | 100 | | `--no-pager` | Skip the pager when `--page-all` output goes to an interactive terminal. | Off | These flags are registered only on operations whose spec declares pagination. On a spec with no pagination metadata they don't exist, and passing one is an argument error. ```bash # Fetch all plants, one JSON line per page contoso plants list --page-all # Limit to 5 pages with a 200 ms delay contoso plants list --page-all --page-limit 5 --page-delay 200 ``` Paginated output works with all output formats. For table and CSV formats, headers are only emitted on the first page so the output concatenates cleanly. ## Passing parameters Path and query parameters can be passed two ways: as individual flags, or as a single JSON object. Request bodies use `--json`. | Flag | Purpose | | ----------------- | ---------------------------------------------------------------------------------- | | `--` | An individual path or query parameter, kebab-cased from its name in the spec. | | `--params ` | All path and query parameters as a single JSON object. Overrides individual flags. | | `--json ` | Request body for POST, PUT, and PATCH methods. | ```bash # Individual flags contoso plants get --plant-id abc # The equivalent --params JSON object contoso plants get --params '{"plantId": "abc"}' # Request body contoso plants create \ --json '{"name": "Monstera", "species": "Monstera deliciosa", "sunlight": "indirect"}' ``` Headers declared API-wide, through the `headers:` block of a Fern definition or [`x-fern-global-headers`](/learn/api-definitions/openapi/extensions/global-headers) in OpenAPI, are sent on every request, preserving each header's `env` fallback, `client-default`, and optionality. An [`x-fern-global-parameters`](/learn/cli-generator/get-started/openapi-extensions#global-parameters) entry targeting the same header takes precedence. Run `contoso --help` to list a command's flags, or [`--schema`](#machine-readable-schema) for the same surface as a machine-readable JSON contract. When a flag name differs from the spec, `--help` shows the original name as `(api: )`, which is the key to use in `--params`. ## Machine-readable schema Every generated CLI exposes a global `--schema` flag that prints its command surface as JSON. It's the agent-facing counterpart to `--help`: the output is deterministic, derived from your spec and the CLI's own flag surface, and is handled before arguments are parsed, so an operation's schema prints even when its required flags are missing. | Command | Output | | ------------------------------ | ---------------------------------------------------------- | | `contoso --schema` | `globalFlags` plus every operation's name and description. | | `contoso plants --schema` | The operations in one command group. | | `contoso plants list --schema` | The full input and output contract for one operation. | ```bash contoso plants list --schema ``` ```json { "operation": "plants.list", "description": "List all plants", "input": { "type": "object", "properties": { "limit": { "type": "integer", "description": "Maximum number of plants to return.", "location": "query", "maximum": 100, "flag": "--limit" } }, "required": [] }, "output": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["id", "name"] } } } ``` `input.properties` is keyed by the spec's parameter names, and each property's `flag` gives the exact flag to pass. Properties without a `flag` are passed through `--params` or `--json`. Operations that support [`--page-all`](#pagination), return binary bodies, or stream also report `paginable`, `binaryResponse`, or `streaming`. ## Server URL variables For APIs with [templated server URLs](/learn/api-definitions/openapi/extensions/server-names-and-url-templating) (such as `https://api.example.com/stores/{store_hash}/v3`), the CLI automatically exposes each template variable as a CLI flag and environment variable, carrying the variable's `default`, `description`, and `enum` from the spec. When an invocation pins no variable, the server's `x-fern-default-url` is used as the base URL. Servers declared on an individual operation resolve the same way as the root `servers` block. ```bash # Pass the variable as a flag bigcommerce --store-hash abc123 v3 customers list # Or set it via an environment variable export BIGCOMMERCE_STORE_HASH=abc123 bigcommerce v3 customers list ``` ## File uploads and downloads For endpoints with `format: binary` request bodies, pass a file path as the `--file` argument. For binary responses, use `--output ` to save the response body to a file. ## Exit codes | Code | Meaning | Example cause | | ---- | ---------------- | ---------------------------------------------------------------------------------- | | `0` | Success | Command completed normally. | | `1` | API error | Server returned a 4xx/5xx response. | | `2` | Auth error | [Credentials](/learn/cli-generator/get-started/authentication) missing or invalid. | | `3` | Validation error | Bad arguments, unknown command, or invalid JSON. | | `4` | Discovery error | Couldn't load API schema. | | `5` | Internal error | Unexpected failure. | All errors are emitted as structured JSON on stderr, making them easy to parse in scripts and CI pipelines. ## TLS, proxies, and CA bundles Every generated CLI honors environment variables for TLS and proxy configuration at runtime. Variables are scoped by binary name — `` is the CLI's binary name uppercased with hyphens mapped to underscores (for example, `CONTOSO`). | Variable | Effect | | ----------------------------- | ----------------------------------------------------------------- | | `_CA_BUNDLE` | Path to a PEM file appended to the default trust roots. | | `_INSECURE=1` | Disable TLS verification. Logs a warning. Not for production use. | | `_PROXY` | HTTP/HTTPS proxy URL, overriding `HTTPS_PROXY` / `HTTP_PROXY`. | | `_NO_PROXY` | Comma-separated proxy bypass list scoped to this CLI. | | `_TIMEOUT_SECS` | Total request timeout. None by default. | | `_CONNECT_TIMEOUT_SECS` | Connection-establishment timeout. | Standard environment variables (`HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY`, `SSL_CERT_FILE`) are honored when the scoped overrides are absent. #### Common scenarios **Behind a MITM proxy (Proxyman, Charles, mitmproxy):** ```bash export SSL_CERT_FILE=~/path/to/proxyman-ca.pem export HTTPS_PROXY=http://127.0.0.1:9090 contoso plants list ``` **Corporate network with a custom root CA:** ```bash export CONTOSO_CA_BUNDLE=/etc/ssl/corp-roots.pem contoso plants list ``` ## User-Agent Each generated CLI sends a `User-Agent` header identifying it by binary name and version, `-cli/` (for example, `contoso-cli/1.4.0`), so its traffic is distinguishable on the API backend. The `-cli` suffix is added automatically. A tool built on top of the CLI can append its own product token without replacing the CLI's identity, producing `contoso-cli/1.4.0 partner-app/3.1`. Supply the token at runtime with either the `--user-agent-suffix` flag or the `_USER_AGENT_SUFFIX` environment variable; the flag takes precedence when both are set. Rename the flag and its environment variable at generation time with [`userAgentSuffixFlag`](/learn/cli-generator/get-started/configuration#config-options). ```bash # Append a product token via flag contoso plants list --user-agent-suffix "partner-app/3.1" # Or via environment variable export CONTOSO_USER_AGENT_SUFFIX="partner-app/3.1" contoso plants list ``` ## Structured logging Logging is off by default. Set `_LOG` to a [tracing filter](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html) to emit structured logs to stderr. Set `_LOG_FILE` to a directory path to write daily rotated JSON log files. ```bash CONTOSO_LOG=debug contoso plants list ``` > Explore the capabilities of Fern's generated CLIs, including output formatting, retries, pagination, dry-run mode, and TLS configuration.