Nodes/TankNodes/API Chat (Environment Key) · Tank
ComfyUI Node

API Chat (Environment Key) · Tank

Same node, key stays on the server

By xzbdqian10nian·Created 2 months ago·Updated a day ago· 1
API Chat (Environment Key) · Tank
  • image
  • video_frames
  • video
  • response
  • usage
  • stats
  • reasoning
  • raw_response
◄base_urlhttps://api.openai.com/v1►
◄model►
◄api_key_envOPENAI_API_KEY►
◄system_prompt►
◄prompt►
◄max_tokens0►
◄temperature0.00►
◄seed1►
◄thinking_modeauto►
◄max_video_frames8►
◄video_transportframes►

API Chat (Environment Key) · Tank is the same node as API Chat (Direct Key) with one input swapped and one security rule bolted on. Instead of pasting a key into a node field, you name an environment variable that the ComfyUI server process reads at request time. The workflow then contains OPENAI_API_KEY - a string of letters, not a secret. Share it, screenshot it, upload the JSON anywhere.

The rule that comes with it is the interesting part, and it's the reason this node is worth choosing even when pasting a key would be easier. Environment-key mode only talks to a host on an administrator-controlled allow-list:

  • The default list is api.openai.com plus loopback (localhost, 127.0.0.1, ::1).
  • HTTPS is required everywhere except loopback; the node refuses to send a key to a plain-HTTP address that isn't local.
  • URLs carrying credentials, a query string or a fragment are rejected outright.

Read that as what it is: an anti-exfiltration design. A shared workflow can't quietly reroute your server's API key to somebody else's endpoint, because the workflow isn't allowed to change the process's allow-list. That's a genuinely thoughtful move in a category where the KB's standing warning is that an API node is a credential plus arbitrary Python, and the ecosystem has already shipped a vision node that stole credentials.

Set it up

Export the variable before ComfyUI starts, in the same environment that launches it:

export OPENAI_API_KEY='sk-...'
# then start ComfyUI from this same shell
python main.py

In the node, put OPENAI_API_KEY in api_key_env - the variable's name, not its value. That's the single most common mistake with this node, and it fails as an authentication error rather than a configuration complaint.

To reach a provider that isn't OpenAI, allow the exact host on the server side and restart:

export COMFYUI_API_ALLOWED_HOSTS='api.openai.com,api.deepseek.com,api.example.com'

Because loopback is allowed by default, this node is also the nicer way to talk to a local server - LM Studio at http://127.0.0.1:1234/v1, or a llama.cpp --server instance - without hardcoding anything into the workflow.

Everything else is shared with its sibling. base_url (no /chat/completions), the exact provider model ID, system_prompt, prompt, max_tokens and temperature where 0 means "omit this parameter," seed, and the seven-value thinking_mode where auto leaves the provider untouched. The optional media inputs are the same too: image (every frame in a batch goes in one request), video_frames sampled by max_video_frames, video plus video_transport (frames is the broadly supported choice, video_url only if the provider takes native video). Outputs are response, usage, stats, reasoning and raw_response; the node is a terminal, it returns text directly, and it never connects to the local loader.

Install

ComfyUI Manager → search Tank (registry package ID qwen38-vl), or clone and restart:

cd ComfyUI/custom_nodes
git clone https://github.com/xzbdqian10nian/ComfyUI-TankNodes.git

Unlike the two local nodes in this pack, nothing here needs llama-cpp-python, a CUDA build or a GGUF file - the API nodes run standalone, and the pack's dependency list is deliberately tiny (the OpenAI SDK if you already have it, otherwise ComfyUI's own aiohttp). You can install this node, set your key, and never touch the local half of the pack at all.

Where people get burned

Environment-key mode rejected the unallowlisted API host - you're pointing at a provider the server doesn't trust yet. Add the exact hostname to COMFYUI_API_ALLOWED_HOSTS and restart ComfyUI; changing the variable while it's running does nothing, because this setting is deliberately read as a process property.

Environment-key mode will not send a key to a non-loopback HTTP address - you typed http:// for a remote host. Use HTTPS.

Key not found, or the same 401 you'd get with no key at all - the variable exists in your terminal but not in the process that's running ComfyUI (common with systemd units, Docker containers, LaunchAgents, or a desktop launcher that never saw your shell profile). Put it in the service definition or the container's environment, not just your .bashrc.

It worked yesterday. Loopback aside, this node will not fall back to a direct key if the environment variable is missing - that's the point. Nothing about the failure is silent about which mode you're in.

For anything else - wrong model IDs, /v1 mistakes, surprise token bills from image batches, interrupt behaviour - the Direct Key article covers it, since the two nodes share one implementation and differ only in where the key comes from.

CategoryTankNodes/API

Inputs (14)

NameTypeDefaultDescription
base_urlSTRINGhttps://api.openai.com/v1OpenAI-compatible API base URL; do not include /chat/completions. The environment-key node only permits the administrator's host allow-list.
modelSTRINGExact model ID exposed by the API provider.
api_key_envSTRINGOPENAI_API_KEYEnvironment variable name containing the API key. Its request host must be administrator-allow-listed.
system_promptSTRINGOptional persona and system-level instruction; leave blank for the provider default.
promptSTRINGUser instruction sent to the API, together with any attached image or video input.
max_tokensINT00–32768Maximum output token count. 0 omits this parameter and uses the provider default.
temperatureFLOAT0.000–2Sampling temperature. 0 means do not send this parameter; use the provider default.
seedINT10–4294967295Seed sent for sampling when the provider supports it; providers may ignore it.
thinking_modeCOMBOautoReasoning control: auto leaves the provider unchanged, off disables reasoning when supported, and low/medium/high/xhigh/max are the five unified effort tiers. Unsupported tiers may be rejected or mapped by the provider.
max_video_framesoptINT81–64Sample at most this many frames from video or video frames. Every image in the image input is still sent.
video_transportoptCOMBOframesChoose sampled image frames, native video_url, or automatic native-video fallback. The provider must support the selected format.
imageoptIMAGEOne still image or an IMAGE batch; every item is sent in the same API request.
video_framesoptIMAGEDecoded video as an IMAGE batch; frames are sampled according to max_video_frames.
videooptVIDEOComfyUI VIDEO input; use frames for broad support or video_url only when the provider supports native video.

Outputs (5)

NameTypeDescription
responseSTRINGFinal API response text.
usageSTRINGUsage JSON returned by the provider, when available.
statsSTRINGRequest timing and backend information.
reasoningSTRINGReasoning text when the provider returns it; otherwise empty.
raw_responseSTRINGOriginal assistant content or complete tool-call message.