For installation and common tasks, see the README.
In an interactive zsh with command insertion enabled, type openai on a line by itself.
If the reference exceeds the terminal height, it opens at the top.
Scroll with the wheel, arrow keys, or Space. Press q to show the rest, or Escape to leave early.
Each line stays in your terminal history.
When the footer says Start typing your next command, type to continue at your zsh prompt.
Press Enter at that prompt to run the command. An initial q, Q, or Space keeps its pager action.
To enable command insertion for the current zsh session, run:
source <(openai @completion zsh --suggestions --suggestions-only)Command chains such as openai; pwd print help and continue immediately.
Explicit help, pipes, redirects, and shells without this integration also use ordinary output.
| Environment variable | Required | Default value |
|---|---|---|
OPENAI_API_KEY |
no | null |
OPENAI_ADMIN_KEY |
no | null |
OPENAI_ORG_ID |
no | null |
OPENAI_PROJECT_ID |
no | null |
OPENAI_WEBHOOK_SECRET |
no | null |
OPENAI_BASE_URL |
no | https://api.openai.com/v1 |
OPENAI_CLI_NO_UPDATE_CHECK |
no | unset |
OPENAI_CUSTOM_HEADERS |
no | null |
OPENAI_MTLS_CLIENT_CERT_FILE |
no | null |
OPENAI_MTLS_CLIENT_KEY_FILE |
no | null |
OPENAI_UNTRUSTED_STDIN |
no | false |
--api-key(can also be set withOPENAI_API_KEYenv var)--admin-api-key(can also be set withOPENAI_ADMIN_KEYenv var)--organization(can also be set withOPENAI_ORG_IDenv var)--project(can also be set withOPENAI_PROJECT_IDenv var)--webhook-secret(can also be set withOPENAI_WEBHOOK_SECRETenv var)--mtls-client-cert-file(can also be set withOPENAI_MTLS_CLIENT_CERT_FILEenv var)--mtls-client-key-file(can also be set withOPENAI_MTLS_CLIENT_KEY_FILEenv var)--help- Show command line usage--debug- Log redacted HTTP headers and per-attempt timing to stderr. Bodies are omitted by default.--debug-body- Add bounded, redacted JSON request and response previews. Requires--debug.--debug-sse,--debug-event-timing- Add redacted SSE frame previews and observed data-frame timing. Requires--debug.--debug-max-bytes,--debug-max-events- Bound capture diagnostics without limiting API payloads. See HTTP debugging.--version,-v- Show the CLI version--base-url- Use a custom API backend URL. HTTPS is required except forlocalhostor literal loopback IP addresses such as127.0.0.1and::1. This also applies toOPENAI_BASE_URL; remote HTTP backends must enable HTTPS.--header,-H- Add a literal request header asName: Value; repeat for multiple headers--format- Change the output format (auto,text,explore,json,jsonl,pretty,raw,yaml);autoselects readable text unless extracting data--format-error- Change the stderr error format (auto,text,explore,json,jsonl,pretty,raw,yaml);autoselects readable summaries unless extracting error data--transform- Transform the data output using GJSON syntax--transform-error- Transform the error output using GJSON syntax
Use --header or -H before or after a resource command:
openai --header 'X-Trace-ID: example-123' models list \
-H 'X-Client-Label: local,manual'Values are literal: commas and colons are preserved, and @ prefixes do not
read files. Surrounding spaces and tabs are trimmed from values. -H 'X-Example:'
sends an empty value. If a name is repeated, the last value wins regardless of
case, overriding default and endpoint-specific headers. Headers managed by the
HTTP transport, such as Host and Content-Length, retain the transport's
behavior. Supplied header values are hidden in help and redacted in debug logs.
For credential-bearing headers, have a secret manager or trusted launcher set
OPENAI_CUSTOM_HEADERS directly in the CLI's environment. This keeps credentials
out of command arguments and avoids typing literal secrets into shell history.
The variable accepts one Name: Value entry per line. For example, with
non-sensitive values:
export OPENAI_CUSTOM_HEADERS='X-Trace-ID: example-123
X-Client-Label: local,manual'
openai models list--header and endpoint-specific header flags override matching environment
entries. Environment header values are also redacted in debug logs. Use
OPENAI_API_KEY and OPENAI_ADMIN_KEY for standard API and admin authentication.
Mutual TLS is currently in beta. To opt in and activate a CA certificate for your organization or project, follow the OpenAI Mutual TLS Beta Program instructions.
To authenticate API-key requests with a mutual TLS client certificate, provide the client certificate and private key as separate PEM files. If certificate chain support is enabled for your organization, the certificate file must contain the leaf certificate first, followed by any intermediate certificates. Otherwise, use a client certificate signed directly by an activated CA certificate.
export OPENAI_MTLS_CLIENT_CERT_FILE=/run/secrets/openai/client-chain.pem
export OPENAI_MTLS_CLIENT_KEY_FILE=/run/secrets/openai/client.key
export OPENAI_BASE_URL=https://mtls.api.openai.com/v1
openai files listBoth mTLS files must be configured together. Keep the private key in a
permission-restricted file; do not put private-key contents directly in command
arguments or environment variables. The CLI does not automatically select an
mTLS endpoint, so configure OPENAI_BASE_URL or --base-url explicitly. HTTP
and SOCKS proxies remain supported, but HTTPS proxies are rejected to prevent
presenting the client certificate during the proxy's own TLS handshake.
If a flag has a matching -structured flag, its ordinary form sends exactly the text you supply.
For example, responses create --input 'Translate: hello' sends a string.
This also applies to completion prompts and stop sequences, embedding inputs, and vector store search queries.
Run openai help --all responses create to see which flags support both forms.
Other flags keep their existing parsers.
Use that flag to parse JSON or YAML, including explicit nulls:
openai responses create --model MODEL --input 'Translate: hello'
openai responses create --model MODEL --input-structured '[{"role":"user","content":"hello"}]'
openai responses create --model MODEL --input-structured nullDo not combine a flag with its -structured alternative in one command.
The CLI rejects that combination before reading sources, regardless of argument order.
Whole-request JSON/YAML preserves its types and existing trust policy in both input modes.
This default change breaks scripts that relied on implicit JSON/YAML conversion for text-capable operands.
Migrate those operands to -structured, or select legacy parsing for the process.
Pin a CLI version that supports this contract; older binaries can ignore the setting.
OPENAI_CLI_INPUT_MODE accepts literal or legacy.
An unset setting selects literal.
The CLI captures the setting before argument parsing; invalid values fail.
Legacy mode restores the original parser, including parsing ordinary operands before file expansion.
Explicit -structured flags override legacy mode for their operands.
OPENAI_CLI_INPUT_MODE=legacy openai responses create --model MODEL --input '[{"role":"user","content":"hello"}]'
OPENAI_CLI_INPUT_MODE=literal openai responses create --model MODEL --input 'Translate: hello'Only processes that inherit the setting use it.
Configure containers, SSH sessions, and environment-clearing launchers separately.
An explicit literal assignment overrides inherited legacy for that process.
Ordinary text operands retain @myfile.ext, @-, and escaped \@ source syntax.
File and stdin text remains text in literal mode.
The CLI resolves each source once.
Binary upload flags use plain paths. For example, use files upload --file "upload space.txt" --purpose user_data.
Here, --file "@upload space.txt" names an actual file starting with @; it does not expand another file reference.
See working with files.
openai <command> --arg @abe.jpgExplicit structured flags also accept file and stdin sources:
openai responses create --model MODEL --input-structured @input.json
printf '%s' '[{"role":"user","content":"hello"}]' | openai responses create --model MODEL --input-structured @-The CLI resolves the source as text before parsing JSON or YAML.
Strings inside the parsed value remain data, including strings beginning with @ or \@.
For example, --input-structured '"@notes.txt"' sends the string @notes.txt.
Trusted whole-request JSON/YAML retains its existing embedded-reference handling:
openai responses create <<YAML
model: MODEL
input: "@notes.txt"
YAMLWhen piping JSON or YAML from an untrusted source, enable untrusted-stdin mode:
untrusted-producer | OPENAI_UNTRUSTED_STDIN=1 openai <command> --file ./upload.txtIn this mode, values supplied through stdin are treated as literal data: @,
@file://, and @data:// references in request bodies, headers, and query
parameters do not read local files. File-upload parameters must be provided
explicitly as command-line flags. Explicit flags retain their normal file
behavior and take precedence over values supplied through stdin. Leave
OPENAI_UNTRUSTED_STDIN unset when using trusted heredocs or other trusted
piped input that intentionally references local files.
If you need to pass a string literal that begins with an @ sign, you can
escape the @ sign to avoid accidentally passing a file.
openai <command> --username '\@abe'For JSON endpoints, the CLI tool does filetype sniffing to determine whether the
file contents should be sent as a string literal (for plain text files) or as a
base64-encoded string literal (for binary files). If you need to explicitly send
the file as either plain text or base64-encoded data, you can use
@file://myfile.txt (for string encoding) or @data://myfile.dat (for
base64-encoding). Note that absolute paths will begin with @file:// or
@data://, followed by a third / (for example, @file:///tmp/file.txt).
openai <command> --arg @data://file.txtSupported self-managed release installations use automatic updates, including four-hour discovery and exact-version pins. The following notice behavior applies to other installations.
Bare openai checks for newer stable releases when stdin, stdout, and stderr are terminals.
It adds a plain-text notice below help, at most once every seven days.
Explicit help, commands, completion, CI, and redirected streams skip the check entirely.
The notice includes an update command when the CLI can verify its installation method.
Verified Homebrew installations check the official Homebrew cask.
When that cask has a newer version, the notice gives brew update && brew upgrade --cask openai/tools/openai.
Go commands require a verified binary, an available Go command, and an explicit matching GOBIN.
Custom GOOS or GOARCH settings select the installation guide instead.
Go upgrades to major version 2 or later also select the installation guide.
For installations that need the guide, the CLI waits for GitHub to publish a matching archive for the running platform.
Package-manager and Go installations retain their existing installation ownership.
Other installations check public GitHub release metadata. Both checks run without API credentials, at most once daily.
Checks respect HTTPS_PROXY and NO_PROXY, including their lowercase forms.
Update discovery waits at most 200 milliseconds. Failed checks remain silent.
Set OPENAI_CLI_NO_UPDATE_CHECK=1 to disable checks and notices.