Export an API-format workflow
For the tested SDXL environment graph, start from the bundled versioned recipe instead of copying node IDs by hand:
pixelkiln recipe install comfyui/pixel-art-xl-environment@1.0.0
pixelkiln recipe verify \
pixelkiln-recipes/comfyui/pixel-art-xl-environment/1.0.0 \
--model-root /path/to/ComfyUI/models
Installation prints the manifest style entry. The recipe pins the workflow and model hashes, records their licenses and source links, and labels the output as composition source. It does not download models or turn the result into finished pixel art. See Versioned recipes for its update and verification contract.
Build and test the workflow in ComfyUI first. Enable developer mode in ComfyUI settings, then use Save (API Format). Commit the exported JSON beside the manifest or in a project workflow directory. PixelKiln reads the file during planning and hashes its parsed JSON, so a node or model change marks dependent assets stale even if the filename stays the same.
The output node must expose an images array in ComfyUI history. A standard
SaveImage node does this. Record these node IDs and input names from the
exported JSON:
- the positive text encoder's prompt input;
- the latent image width, height, and batch-size inputs;
- the sampler seed input, when the PixelKiln style declares a seed;
- the source
LoadImageinput for a revision; - the mask
LoadImageinput for inpainting; - the sampler denoise/strength input when the asset declares strength;
- any project-named inputs that should vary by asset, such as a pose image, ControlNet strength, reference image, or LoRA weight;
- the final
SaveImagenode.
Node IDs are workflow-specific. Do not copy IDs from an example without checking the exported file.
Bind per-asset workflow inputs
Use one project-defined binding name in the style and the same key under each
asset's providerInputs. This keeps a pose, composition guide, reference image,
or strength with the asset instead of cloning nearly identical workflow files:
{
"styles": {
"character": {
"generator": "map",
"outDir": "assets/generated/characters",
"providerOptions": {
"comfyui": {
"workflowFile": "workflows/pose-api.json",
"outputNodeId": "9",
"bindings": {
"prompt": { "nodeId": "6", "input": "text" },
"width": { "nodeId": "5", "input": "width" },
"height": { "nodeId": "5", "input": "height" },
"pose": { "nodeId": "19", "input": "image" },
"poseStrength": { "nodeId": "20", "input": "strength" }
}
}
}
}
},
"assets": {
"showcase-performer": {
"prompt": "a stage performer mid-spin",
"width": 832,
"height": 1216,
"providerInputs": {
"pose": "controls/pole-spin.png",
"poseStrength": 0.75
}
}
}
}
PixelKiln recognizes a custom binding as an image input when it targets the
image input of a core LoadImage or LoadImageMask node. Its value must be a
manifest-relative PNG or JPEG. Planning reads and hashes the file without
contacting ComfyUI. Submission checks the bytes again, uploads them under a
content-addressed pixelkiln/ name, and refuses the job if the file changed in
between. The lock records the hash and format, never the workstation path.
Other custom bindings accept strings, finite numbers, or booleans. Their type
must match the primitive placeholder already stored at the target input in the
committed workflow. PixelKiln rejects missing targets, duplicate targets,
reserved built-in names, missing files, and unsupported image formats during
offline resolution. ComfyUI performs the final graph and custom-node validation
when /prompt is submitted. Keep providerInputs names stable: values are part
of the asset spec hash, so changing one correctly makes that asset stale.