> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runcomfy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Commands

The CLI exposes six commands. All accept the global flags `--output {pretty,json}`, `-q/--quiet`, `-v/--verbose`, and all except `login` / `logout` require authentication ([Authentication](/cli/auth)).

Aliases: `runcomfy requests get` ≡ `runcomfy status`, `runcomfy requests cancel` ≡ `runcomfy cancel`.

For exit-code semantics across all commands, see [Troubleshooting → Exit codes](/cli/troubleshooting#exit-codes).

***

## `login`

Authenticate the CLI with RunComfy via the device-code OAuth flow.

```bash theme={null}
runcomfy login [--web-base <URL>]
```

1. Calls `POST {web_base}/api/cli-auth/start`, receives a short user code and a verification URL.

2. Prints the code in the terminal:

   ```
   🔑 Opening the authorization page in your browser
      If your browser doesn't open, visit:  https://www.runcomfy.com/cli-auth

          YOUR CODE:  ABCD-1234

      Type or paste this code into the page, then click Authorize.
   ```

3. Opens the verification URL in your default browser.

4. Polls `POST {web_base}/api/cli-auth/poll` every 2 seconds.

5. On `Authorize`, saves the access token to `~/.config/runcomfy/token.json` (`mode 0600`).

6. `Ctrl-C` aborts the wait cleanly.

| Flag               | Description                                                                                                                             |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `--web-base <URL>` | Override the auth host (default `https://www.runcomfy.com`). Useful for staging / preview environments. Also reads `RUNCOMFY_WEB_BASE`. |

In CI or any non-interactive environment, set `RUNCOMFY_TOKEN=<token>` and skip `runcomfy login` entirely.

***

## `logout`

```bash theme={null}
runcomfy logout
```

Removes the local token file. Does **not** revoke the token server-side — for that, rotate it on your [Profile](https://www.runcomfy.com/profile) page.

***

## `whoami`

Show the currently authenticated user.

```bash theme={null}
runcomfy whoami
# 📛 you@example.com
#    token type: cli
#    user id: 36312e13-1b55-45c5-80f7-5382bd18c98b
```

In `--output json` mode the same data goes to stdout as a single line, useful for scripts:

```bash theme={null}
USER_ID=$(runcomfy --output json whoami | jq -r .id)
```

Backs `GET https://www.runcomfy.com/api/auth/me`.

***

## `run`

Run a [Model API](/model-apis/quickstart) model end-to-end: submit, poll, fetch the result, download generated files.

```bash theme={null}
runcomfy run <model_id> [--input <JSON> | --input-file <PATH>]
                        [--no-wait] [--poll-secs <N>]
                        [--output-dir <DIR>] [--no-download]
```

`<model_id>` is the slash-separated identifier from the [Models catalog](https://www.runcomfy.com/models) (e.g. `blackforestlabs/flux-1-kontext/pro/edit`, `openai/gpt-image-2/text-to-image`).

| Flag                  | Default | Description                                                                        |
| --------------------- | ------- | ---------------------------------------------------------------------------------- |
| `--input '<JSON>'`    | —       | Inline JSON payload matching the model's Input schema                              |
| `--input-file <PATH>` | —       | Read JSON input from a file. Use `-` for stdin. Mutually exclusive with `--input`. |
| `--no-wait`           | false   | Submit and return the request\_id immediately; don't poll                          |
| `--poll-secs <N>`     | 2       | Polling interval in seconds while waiting                                          |
| `--output-dir <DIR>`  | `.`     | Where to download generated files                                                  |
| `--no-download`       | false   | Skip file download; only print the result JSON                                     |

### Examples

```bash theme={null}
# Inline input
runcomfy run blackforestlabs/flux-1-kontext/pro/edit \
  --input '{"prompt": "a small purple cat", "aspect_ratio": "16:9"}'

# Input from a file
runcomfy run openai/gpt-image-2/text-to-image --input-file ./req.json

# Input from stdin
echo '{"prompt": "piped"}' | \
  runcomfy run openai/gpt-image-2/text-to-image --input-file -

# Submit and return immediately
runcomfy run openai/gpt-image-2/text-to-image \
  --input '{"prompt":"..."}' --no-wait
# {"request_id":"8a3f...","wait":false}

# JSON-only output for scripts
runcomfy --output json run openai/gpt-image-2/text-to-image \
  --input '{"prompt":"..."}' --no-wait | jq -r .request_id

# Save outputs to a specific directory
runcomfy run openai/gpt-image-2/text-to-image \
  --input '{"prompt":"..."}' --output-dir ./out

# Print the result URL but don't download
runcomfy run openai/gpt-image-2/text-to-image \
  --input '{"prompt":"..."}' --no-download
```

### End-to-end output

```
⏳ Submitting request to openai/gpt-image-2/text-to-image
   request_id: 8a3f...
⏳ Polling status (every 2s)...
   in_queue
   in_progress
   completed
✅ completed
{
  "images": [
    "https://playgrounds-storage-public.runcomfy.net/.../result.png"
  ]
}
📥 Downloading 1 file(s) to .
   ./result.png
```

Stdout receives the result JSON; stderr receives the progress lines (or `[tag]` text if not a TTY / `NO_COLOR` is set).

### Behavior details

* **Submit**: `POST https://model-api.runcomfy.net/v1/models/<model_id>` with the JSON body **as-is** (Model API expects flat input, not `{"input":{...}}`).
* **Poll**: `GET .../requests/<id>/status` every `--poll-secs` seconds.
* **Fetch**: on terminal status (`completed` / `succeeded` / `failed` / `cancelled`), `GET .../requests/<id>/result`.
* **Download whitelist**: the CLI scans the result JSON recursively and downloads every URL whose host ends with **`.runcomfy.net`** or **`.runcomfy.com`**. URLs outside that whitelist are listed but not fetched — preventing a compromised upstream model from coercing the CLI into pulling arbitrary internet content. Downloads stream to disk and abort with `unlink(2)` if the response exceeds 2 GiB.
* **Ctrl-C**: while polling, sends `POST .../requests/<id>/cancel` to RunComfy before exiting. If the cancel call itself fails, the CLI prints the request\_id and tells you to retry with `runcomfy cancel <id>` — so you don't get billed for GPU you thought was stopped.

***

## `status`

Poll the status of a Model API request submitted via `runcomfy run --no-wait`.

```bash theme={null}
runcomfy status <request_id>
# request_id: 8a3fbf12-...
# status:     in_progress
# status_url: https://model-api.runcomfy.net/v1/requests/.../status
# result_url: https://model-api.runcomfy.net/v1/requests/.../result
```

If still queued, the output also includes `queue: position N`.

| status                    | Meaning                                                                            |
| ------------------------- | ---------------------------------------------------------------------------------- |
| `in_queue`                | Waiting for a runner; `queue_position` shows how many ahead                        |
| `in_progress`             | Running on GPU                                                                     |
| `completed` / `succeeded` | Done; fetch the output via `runcomfy run` (same `request_id`) or curl `result_url` |
| `failed`                  | Run errored; fetch `result_url` for the failure reason                             |
| `cancelled`               | Cancelled (by you or by the platform)                                              |

The CLI doesn't loop — it returns the current snapshot and exits. Wrap in your own `while` loop for repeated checks. Backs `GET .../requests/<id>/status`.

***

## `cancel`

Cancel a queued or running Model API request.

```bash theme={null}
runcomfy cancel <request_id>
# ✅ Cancelled 8a3fbf12-... (final status: cancelled)
```

If already terminal:

```
ℹ 8a3fbf12-... is already terminal (succeeded); cancel is a no-op
```

In `--output json` mode, the response includes an `outcome` field (`cancelled` or `not_cancellable`).

`runcomfy run` (without `--no-wait`) auto-cancels on `Ctrl-C`, so you only need `cancel` directly when you submitted with `--no-wait`, the auto-cancel failed, or you're cancelling someone else's `request_id`. Backs `POST .../requests/<id>/cancel` (returns `202 Accepted`).
