# CLI

The `faceless` CLI (npm package `faceless-cli`) wraps the whole API in commands that work for humans and for scripts and agents.

## Install

```bash
npm install -g faceless-cli
faceless --version
```

The command is `faceless` (alias `fcl`). Without installing, use `npx -y faceless-cli <command>`.

## Authenticate

Two options:

- `faceless login`: paste an API key from your team settings at https://faceless.so/team; it is stored in `~/.faceless/config.json` for future commands
- `FACELESS_API_KEY` environment variable: nothing to store; ideal for CI and agents

Verify with `faceless whoami`. Global flags on every command: `--json` (raw API envelope output), `--api-key` (override the key for one call) and `--api-url` (point at another deployment, also via `FACELESS_API_URL`).

## Commands

- `faceless whoami`: introspect the API key (GET /me)
- `faceless credits`: credit balance and ledger (GET /credits)
- `faceless videos create`: create a video from a script (POST /videos)
- `faceless videos captions`: caption an existing video or audio URL (POST /videos/captions)
- `faceless videos list` / `faceless videos get <id>`: browse videos (GET /videos, GET /videos/{id})
- `faceless videos status <id>`: generation progress (GET /videos/{id}/status)
- `faceless videos update <id>`: rename or set per-platform post metadata (PATCH /videos/{id})
- `faceless videos render <id>`: render the MP4 (POST /videos/{id}/render)
- `faceless videos delete <id>`: delete a video (DELETE /videos/{id})
- `faceless renders get <id>`: render progress and final MP4 url (GET /renders/{id})
- `faceless series create` / `list` / `get <id>` / `update <id>` / `delete <id>`: manage series
- `faceless series generate <id>`: force the next episode now (POST /series/{id}/generate)
- `faceless series episodes <id>`: list a series' episodes (GET /series/{id}/episodes)
- `faceless posts publish`: publish a rendered video now (POST /posts)
- `faceless posts schedule`: schedule to one or more platforms (POST /posts/schedule)
- `faceless posts cancel <videoId>`: cancel a scheduled post (DELETE /posts/{id})
- `faceless calendar`: posting calendar (GET /calendar)
- `faceless accounts`: connected social accounts (GET /accounts)
- `faceless voices`: TTS voice catalog (GET /voices)
- `faceless options`: option catalogs, e.g. `faceless options --kind models` (GET /options)
- `faceless assets create`: register a media asset by URL (POST /assets)
- `faceless analytics`: cross-platform performance (GET /analytics)
- `faceless mcp`: run the local stdio MCP server (see [MCP](/developers/docs/mcp))

## Scripting and agents: --json

Always pass `--json` when running from a script or agent, and parse the `success` field. The output is the raw API envelope, so the [API reference](/developers/reference) documents every field.

```bash
faceless videos create --script "Did you know..." --voice-id EXAVITQu4vr4xnSDxMaL \
  --model storyboard --wait --json
faceless posts publish --video-id <videoId> --platform youtube --json
```

The CLI sends an `Idempotency-Key` automatically on every mutating command, so a timed-out command is safe to re-run without double credit charges.

## --wait and --timeout

Asynchronous operations (`videos create`, `videos captions`, `videos render`, `series generate`) accept `--wait`: the CLI polls status at the recommended cadence and exits when the operation reaches a terminal state, printing the final resource. Cap the polling with `--timeout <seconds>`. Without `--wait`, poll yourself with `faceless videos status <id> --json` or `faceless renders get <id> --json`.

```bash
faceless videos create --script "..." --voice-id <voiceId> --wait --timeout 900 --json
faceless videos render <videoId> --wait --json
```

## Exit codes

- `0`: success
- `2`: authentication failed (`unauthorized`); re-run `faceless login` or fix `FACELESS_API_KEY`
- `3`: `insufficient_credits`; top up at https://faceless.so/billing
- `4`: `rate_limited`; wait and retry (respect Retry-After)
- `1`: any other error
