CLI reference

Every bithuman command, flag, environment variable, exit code and --json shape.

Covers the CLI at the version on Downloads & versions. The binary describes itself too: bithuman <command> --help, and bithuman __schema prints the full command, flag and exit-code tree as JSON. The quickstart is on CLI.

Commands

CommandPurpose
bithuman run [avatar]Live avatar in your browser. No argument runs wise-pup
bithuman render <avatar> <audio>Audio in, MP4 out
bithuman pull <avatar>Download a sample avatar, or your own agent’s model, ahead of time
bithuman list [--mine]List the sample avatars, or yours
bithuman open <avatar>Check that an avatar opens here, and list its contents
bithuman login / logoutSign in and store a per-device API secret / revoke it
bithuman accountYour account, plan, credit balance and recent usage
bithuman engine list | install [mac|linux]Inspect or fetch the Expression 2 render engine
bithuman pack redeem [purchase | file] / pack statusInstall a prepaid offline pack on this machine / show the render-seconds left
bithuman doctorCheck the install, credential, brain and cache
bithuman versionCLI, engine and build versions
bithuman mcpMCP server over stdio; bithuman mcp tools lists its tools
bithuman completion <shell>Completions for bash, zsh, fish, elvish, powershell

A command outside this list exits 2 with unrecognized subcommand. Everywhere, <avatar> is an agent code (A24EKJ8433), a sample avatar’s name (wise-pup), or a file (wise-pup.imx); run, render and open download a code or name on first use. --json, -h and -V (root only) work on every command.

Sign in

bithuman login                 # browser sign-in; stores a per-device API secret
bithuman login --device        # over SSH: prints a code to enter elsewhere
printf %s "$BITHUMAN_API_SECRET" | bithuman login --with-token   # CI: checks the secret, then stores it
bithuman logout                # revokes the secret login stored on this device

The secret is stored in ~/.bithuman/config (mode 0600) and named cli@<hostname> under API Secrets, so each device can be revoked alone. --with-token exits 77 (TOKEN_REJECTED) for a secret the service refuses and 69 (TOKEN_UNVERIFIED) when the service cannot be reached; neither stores anything.

Credential resolution order

  1. BITHUMAN_API_SECRET in the environment
  2. BITHUMAN_API_KEY in the environment (a deprecated alias; read until CLI 3.0, no earlier than 2026-12-26)
  3. A .env file in the working directory: its BITHUMAN_API_SECRET line, else its BITHUMAN_API_KEY line (the deprecated alias). No other line of the file is read. Deprecated: the CLI prints a notice when it uses this file, and CLI 2.9 (no earlier than 2026-12-26) stops reading it; export BITHUMAN_API_SECRET or run bithuman login once.
  4. ~/.bithuman/config, written by bithuman login

bithuman account --json reports which of these supplied the secret.

bithuman logout revokes only the secret in ~/.bithuman/config, then deletes it. A secret from the environment or a .env file is never revoked; logout names where it comes from instead.

bithuman run

FlagDefaultPurpose
--host127.0.0.1Bind address. 0.0.0.0 also needs BITHUMAN_ALLOW_PUBLIC_BIND=1
--port8088HTTP port

run starts everything a session needs: a local livekit-server (it must be on PATH) and the conversation brain. A file runs locally: Expression 2 (.avatar or .imx), Essence 2 and Essence 1 (.imx). An Essence 2 or Expression 2 agent code opens a cloud session. Expression 1 is cloud-only.

The conversation brain: signed in, run uses the managed brain and installs it into ~/.cache/bithuman/brain-venv on first use (about 350 MB on disk). OPENAI_API_KEY selects OpenAI Realtime instead, and BITHUMAN_LOCAL=1 runs it on your hardware (local conversation brain).

bithuman render

FlagDefaultPurpose
<audio>requiredThe second argument: any format ffmpeg reads
-o, --output <PATH><avatar>.mp4Output file
--limit <N>noneStop after N frames
ModelOutput
Expression 2MP4 at 20 fps: ceil(seconds × 20) frames
Essence 2MP4 at 25 fps: ceil(seconds × 25) frames
Essence 1refused (exit 70); use the video API

render needs ffmpeg on PATH (or BITHUMAN_FFMPEG). A refused render writes no file.

bithuman pull

bithuman pull wise-pup                          # a sample avatar: no account → ~/.cache/bithuman/showcase/
bithuman pull "$AGENT_CODE"                     # your agent: needs sign-in → ~/.cache/bithuman/agents/<code>/
bithuman pull "$AGENT_CODE" --model essence-2   # when the agent has more than one model

pull prints only the cached path on stdout, so MODEL=$(bithuman pull wise-pup) captures it. A second pull downloads again when the published file changed; --force always does. An agent with several models returns the one it was created with unless you pass --model; --json lists the others in other_models. A slug not in bithuman list exits 66 (SLUG_NOT_FOUND). --model essence-1 | essence-2 | expression-2 picks which of the agent’s models to download.

bithuman open

Succeeds, or refuses with one of four kinds: InvalidAvatar, NotSupported, NotAuthorised, Failed. On success it prints the engine, the model and every member with its size. The engine value is a legacy identifier (the engine value), not a model value.

bithuman engine

The Expression 2 engine ships with the CLI. bithuman engine install fetches it again (idempotent); bithuman engine install linux fetches the other platform’s for a cross-build. The argument is mac or linux.

bithuman pack

Offline packs (Business and Enterprise) let a machine render with no network. Buy the pack online, then run this on the machine that will render:

bithuman pack redeem            # the account's unredeemed pack
bithuman pack redeem ent_...    # a named purchase
bithuman pack redeem ./PACK.bhl # a saved pack, with no network
bithuman pack status            # render-seconds left

redeem binds the pack to this machine and installs it. The signed pack is kept at ~/.bithuman/packs/<pack_id>.bhl (mode 0600) first, so a failed install is retried by passing that file. Afterwards bithuman render of an avatar the pack covers needs no network and no API secret until the pack is spent. A refusal names what to do (the plan, the platform, a pack already installed) and nothing is spent. Where the CLI’s offline support has not opened yet, it says to use python -m bithuman pack redeem on the same machine. Plans and rates: offline licensing.

bithuman doctor

Checks versions, host, memory, credential, brain and cache sizes. Exits 0 only when a credential, a brain, the agent worker, the audio encoder and ffmpeg are all available. The first bithuman run sets up the worker, so a fresh install reports not ready until then.

Environment variables

VariableEffect
BITHUMAN_API_SECRETYour API secret (BITHUMAN_API_KEY is a deprecated alias)
BITHUMAN_CACHE_DIRCache root (default ~/.cache/bithuman)
BITHUMAN_ALLOW_PUBLIC_BIND1 lets run --host 0.0.0.0 listen on every interface
OPENAI_API_KEYUse OpenAI Realtime as the conversation brain
BITHUMAN_LOCAL1 runs the brain on this machine (local conversation brain)
BITHUMAN_LOCAL_*, BITHUMAN_INSTRUCTIONSLocal conversation brain settings (tuning)
BITHUMAN_FFMPEGPath to ffmpeg
BITHUMAN_VERSIONRelease tag for the installer, set on the sh side of the pipe: curl -fsSL https://install.bithuman.ai | BITHUMAN_VERSION=cli-v2.7.8 sh
BITHUMAN_INSTALL_DIRWhere the installer puts the binary (default ~/.local/bin)
NO_COLORTurn colour off
BITHUMAN_LICENSE_FILEPath to a signed offline license (Business and Enterprise, offline licensing)
BITHUMAN_THREADSRender threads (default: one per CPU the process may use, up to 16)
BITHUMAN_INSTALL_IDThis install’s id in usage reports (default: a random id kept in ~/.bithuman/install_id)

Cache

PathContents
~/.cache/bithuman/showcaseSample avatars
~/.cache/bithuman/agents/<code>Your agents’ models
~/.cache/bithuman/runSession state and logs
~/.cache/bithuman/brain-venvThe conversation brain
~/.cache/bithuman/bundlesUnpacked avatars (about the size of each avatar again)
~/.bithuman/enginesRender engines, including the Essence 2 audio encoder (about 66 MB)
~/.cache/huggingface, ~/.cache/supertonicLocal conversation brain weights

bithuman doctor prints each size. Deleting ~/.cache/bithuman is safe.

Platforms

Binaries: aarch64-apple-darwin, x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu. On any other platform the installer names the platform, says what is supported, and exits 1 without downloading. There is no Intel Mac or native Windows binary; use WSL2, a Linux container, or the cloud API.

JSON output

With --json, a command prints exactly one JSON object on stdout and nothing else. Success objects carry "schema_version": 1. A failure prints one object to stderr, with a hint when there is a next step:

{"error": {"code": "USAGE", "kind": "Failed", "command": "renders", "message": "unrecognized subcommand 'renders'", "hint": "run `bithuman --help`"}}

Colour appears only on an interactive terminal.

Shapes

bithuman version --json:

{"abi":7,"cli":"2.8.3","libessence":"2.11.16","build":{"target":"x86_64-unknown-linux-gnu","profile":"release"},"engine":{"platform":"linux","runtime":"litert","version":"1.0.2"},"schema_version":1}

bithuman account --json (exit 77 with no credential; --limit <N>, default 10, sets how many recent charges to show):

{"logged_in": true, "source": "env BITHUMAN_API_SECRET", "email": "you@example.com", "plan": "creator", "credit_balance": 1000, "account_status": "active", "out_of_credits": false, "usage": {"data": [], "pagination": {"total": 0}}}

bithuman list --json:

{"schema_version": 1, "version": 2, "models": [{"slug": "wise-pup", "agent_code": "A23WJF0199", "name": "Wise Pup", "model": "expression-2", "size": 198632867}]}

bithuman pull <slug or code> --json:

{"schema_version": 1, "code": "A23WJF0199", "path": "/home/you/.cache/bithuman/showcase/wise-pup.imx", "cached": false, "family": "expression-2", "model": "expression-2", "other_models": [], "runnable_locally": true}

bithuman render … --json also carries render_seconds and render_fps, how long the engine took and how fast it produced frames (fps is the file’s playback rate). frames / fps is the clip length; seconds is the wall time of the whole command:

{"schema_version": 1, "output": "out.mp4", "bytes": 1234567, "seconds": 21.4, "width": 416, "height": 720, "frames": 300, "fps": 20, "render_seconds": 6.2, "render_fps": 48.4}

bithuman login --json (both routes; the code box goes to stderr):

{"schema_version": 1, "logged_in": true, "email": "you@example.com", "alias": "cli@your-host", "stored": "~/.bithuman/config"}

alias is null with --with-token.

bithuman run … --json prints one event when the session is live:

{"schema_version": 1, "event": "session_started", "url": "http://127.0.0.1:8088/WISEPUP", "code": "WISEPUP", "host": "127.0.0.1", "port": 8088, "cost_per_min": 10, "credit_balance": 99}

bithuman doctor --json exits 0 when "ready": true. The values above are examples; the shapes are stable, and schema_version changes when they are not.

Exit codes

CodeNameMeaning
0success
1GENERICruntime error; doctor not ready; a browser or device sign-in that failed or timed out
2USAGEbad arguments; --host 0.0.0.0 without BITHUMAN_ALLOW_PUBLIC_BIND=1
66NOINPUTfile, slug or model not found; not an avatar file
69UNAVAILABLEnetwork, engine or service unavailable; incomplete model file; ffmpeg missing
70SOFTWAREinternal error (Essence 1 render)
77NOPERMnot signed in, a rejected or revoked secret (including login --with-token), out of credits, or forbidden
130—interrupted with Ctrl-C (a live Expression 2 session exits 0 after draining)

Introspection

bithuman __schema    # command, flag and exit-code tree as JSON
bithuman __agents    # this contract, offline
bithuman token       # the resolved secret on stdout (exit 77 if none)

MCP server

{"mcpServers": {"bithuman": {"command": "bithuman", "args": ["mcp"]}}}

bithuman mcp speaks the Model Context Protocol over stdio. bithuman mcp tools --json lists the tools: local ones (version, doctor, inspect_model, list_showcase, pull, render, pack_redeem) and ones that call the bitHuman API. Tools that create agents, speech or gestures spend credits. The full list is on MCP server.

Recipes

# First render on a new machine: check the credential first, then render.
set -e
bithuman account --json >/dev/null          # exit 77: run `bithuman login`
curl -fsSLo speech.wav https://docs.bithuman.ai/samples/speech.wav
bithuman render wise-pup speech.wav -o out.mp4 --json | jq -r .output

# Is this install ready to serve? (exit 0 = yes)
bithuman doctor --json | jq -e .ready >/dev/null

Renamed in 2.7.3

The old spellings still work for now. Each prints one line on stderr naming what to use instead, and --json output is unchanged.

WasNow
render X -a in.wavrender X in.wav
render writing output.mp4render writes <avatar>.mp4 unless you pass -o
render --quality, --target-sizeone preset, each avatar’s default size
run --allow-public-bindBITHUMAN_ALLOW_PUBLIC_BIND=1
run --cloud, --offscreen, --frames, --embedded-livekit, --livekit-*not needed: run <avatar> picks and starts what it needs; frames without a window come from render --limit N
chat, info, avatars, list --agentsrun, open, list, list --mine
list --limit/--offset/--status, account --start/--end/--agentthe full list; filter the --json output
--api-basenot needed: the CLI talks to https://api.bithuman.ai
--destBITHUMAN_CACHE_DIR
--quiet, --no-color, BITHUMAN_JSON/QUIET/NO_COLOR--json, NO_COLOR=1