Skip to main content

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 getruncomfy status, runcomfy requests cancelruncomfy 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>]
  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.
FlagDescription
--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

runcomfy 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).
FlagDefaultDescription
--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-waitfalseSubmit and return the request_id immediately; don’t poll
--poll-secs <N>2Polling interval in seconds while waiting
--output-dir <DIR>.Where to download generated files
--no-downloadfalseSkip 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.
statusMeaning
in_queueWaiting for a runner; queue_position shows how many ahead
in_progressRunning on GPU
completed / succeededDone; fetch the output via runcomfy run (same request_id) or curl result_url
failedRun errored; fetch result_url for the failure reason
cancelledCancelled (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).