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.
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).
Aliases: runcomfy requests get ≡ runcomfy status, runcomfy requests cancel ≡ runcomfy cancel.
For exit-code semantics across all commands, see Troubleshooting → Exit codes.
login
Authenticate the CLI with RunComfy via the device-code OAuth flow.
runcomfy login [--web-base <URL>]
-
Calls
POST {web_base}/api/cli-auth/start, receives a short user code and a verification URL.
-
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.
-
Opens the verification URL in your default browser.
-
Polls
POST {web_base}/api/cli-auth/poll every 2 seconds.
-
On
Authorize, saves the access token to ~/.config/runcomfy/token.json (mode 0600).
-
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
Removes the local token file. Does not revoke the token server-side — for that, rotate it on your Profile page.
whoami
Show the currently authenticated user.
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:
USER_ID=$(runcomfy --output json whoami | jq -r .id)
Backs GET https://www.runcomfy.com/api/auth/me.
run
Run a Model API model end-to-end: submit, poll, fetch the result, download generated files.
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 (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
# 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.
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.
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).