Features
The CLI generator is in early access. Reach out 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) 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.
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.
Retries with backoff
Failed requests are retried automatically with exponential backoff on status codes 408, 429, and 5xx, honoring Retry-After headers.
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, 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.
Pagination
For endpoints annotated with x-fern-pagination, the CLI auto-paginates when the --page-all flag is set.
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.
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.
Headers declared API-wide, through the headers: block of a Fern definition or x-fern-global-headers in OpenAPI, are sent on every request, preserving each header’s env fallback, client-default, and optionality. An x-fern-global-parameters entry targeting the same header takes precedence.
Run contoso <command> --help to list a command’s flags, or --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: <name>), 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.
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, return binary bodies, or stream also report paginable, binaryResponse, or streaming.
Server URL variables
For APIs with templated server URLs (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.
File uploads and downloads
For endpoints with format: binary request bodies, pass a file path as the --file argument. For binary responses, use --output <PATH> to save the response body to a file.
Exit codes
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 — <NAME> is the CLI’s binary name uppercased with hyphens mapped to underscores (for example, CONTOSO).
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):
Corporate network with a custom root CA:
User-Agent
Each generated CLI sends a User-Agent header identifying it by binary name and version, <binaryName>-cli/<version> (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 <NAME>_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.
Structured logging
Logging is off by default. Set <NAME>_LOG to a tracing filter to emit structured logs to stderr. Set <NAME>_LOG_FILE to a directory path to write daily rotated JSON log files.