Prompt Chain Ideogram Caption
Turn a normal prompt into the JSON Ideogram 4 actually wants
- text
Ideogram 4 doesn't take prompts the way most open models do. It was trained exclusively on structured JSON captions - hex colors, typed text elements, bounding boxes - and a plain English prompt genuinely underperforms on it, not just stylistically but in a way that also happens to trip the model's trained-in safety filter. This node handles both problems at once: hand it your normal Prompt Chain prompt and it comes back wrapped in the full JSON caption schema Ideogram 4 was actually trained to read.
How it works
The mode: caption setting doesn't just reformat your text - the tooltip states its purpose plainly: it "avoids the model's false safety blocks." That's not marketing language, it's a documented community finding about how Ideogram 4's filter behaves: the model's refusal image gets triggered less by content than by prompt format, and prompting through the JSON schema the vendor itself documented clears it even on requests that get blocked in plain prose. Wrapping the prompt properly is the actual fix, not a workaround bolted on top of one.
The inputs and outputs that matter
text is required - wire Prompt Chain's positive output straight in. mode is a combo, defaulting to caption; set it to off if you want straight passthrough, for instance if you've already hand-written your own JSON caption and don't want this node reinterpreting it, or if you're A/B testing prose against JSON on the same prompt.
Two optional inputs unlock Ideogram 4's actual regional-prompting feature - bounding boxes as a native part of its caption format, rather than the bolted-on extension regional control usually is on other models. regions takes Prompt Chain's regions output (its 4th), so each $name{} block in your prompt becomes its own typed element in the JSON. pose takes a Region Box's POSE_JSON, which is what actually carries each region's bounding-box (bbox) coordinates so the caption knows where to place each block - without it, the regions have names and text but no position to anchor to.
Single text (STRING) output - the compiled JSON caption, ready to feed into whatever conditioning path your Ideogram 4 sampling setup expects.
How to install it
Manager: search ComfyUI-PromptChain. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/mobcat40/ComfyUI-PromptChain.git
This node only matters if Ideogram 4 is actually somewhere in your graph - it's not useful bolted onto an SDXL or Flux workflow. Note that Ideogram 4's own weights ship under a non-commercial license (fine-tunes and personal/research use permitted, revenue-generating use requires a separate paid tier) - that's a fact about the model you're generating on, not about this node, but worth knowing before you build a pipeline around it.
Common issues & troubleshooting
Generations still come back as the grey blocked frame. Confirm mode is actually set to caption, not off - plain-prose prompting is exactly what triggers the filter most often. If you're already on caption mode and still seeing occasional refusals, that's a separate, known Ideogram 4 quirk rather than something this node controls; pair it with PromptChain_IdeogramSampler, which auto-detects and re-rolls a blocked frame rather than handing you one.
Regions aren't landing where you placed them. regions alone only carries names and text - without pose wired from a Region Box, there's no bounding-box data for the caption to place blocks at, and they'll fall back to wherever the model decides on its own.
A hand-written JSON caption gets mangled. Set mode: off for passthrough - caption mode assumes it's compiling from a Prompt Chain-style prompt, not re-parsing an already-structured caption.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | Wire to Prompt Chain's 'positive' output. | |
| mode | COMBO | caption | caption = wrap the prompt in a complete Ideogram JSON caption (avoids the model's false safety blocks); off = passthrough. |
| regionsopt | STRING | Optional: wire Prompt Chain's 'regions' output (4th) to place each $name{} block at its Region Box. | |
| poseopt | STRING | Optional: wire a Region Box POSE_JSON — carries each region's box (bbox) so the caption places it. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |