Skip to content

Image conversion ​

convertImage is a utility step for format conversion, resizing, and blurring. It applies zero or more transforms in order, then encodes the result to the requested format. Cost is a flat 1 Buzz (Cost).

The request shape ​

json
{
  "$type": "convertImage",
  "input": {
    "image":      "https://...",        // source — URL, data URL, or Base64
    "transforms": [ /* optional */ ],   // resize / blur — applied in order
    "output":     { "format": "jpeg" }, // required — format + per-format settings
    "public":     false                 // optional — restricted, see "Public output"
  }
}

transforms is optional (omit to change format or settings only). output is required. public is optional and restricted — see Public output.

Examples ​

Format conversion ​

Convert any image to JPEG:

http
POST https://orchestration.civitai.com/v2/consumer/workflows?wait=60
Authorization: Bearer <your-token>
Content-Type: application/json

{
  "steps": [{
    "$type": "convertImage",
    "input": {
      "image": "https://image.civitai.com/.../source.png",
      "output": { "format": "jpeg", "quality": 85 }
    }
  }]
}
POST/v2/consumer/workflows
Set your Civitai API token via the Token button in the navbar to enable Try It.
Request body — edit to customize (e.g. swap the image URL or prompt)
Valid JSON

Resize then convert ​

Resize to a target width (aspect ratio preserved) and encode to WebP:

json
{
  "$type": "convertImage",
  "input": {
    "image": "https://...",
    "transforms": [{ "type": "resize", "targetWidth": 512 }],
    "output": { "format": "webp", "quality": 85 }
  }
}
POST/v2/consumer/workflows
Set your Civitai API token via the Token button in the navbar to enable Try It.
Request body — edit to customize (e.g. swap the image URL or prompt)
Valid JSON

Region blur ​

Blur one or more rectangular areas — useful for privacy masking:

json
{
  "$type": "convertImage",
  "input": {
    "image": "https://...",
    "transforms": [{
      "type": "blur",
      "blur": 60,
      "mode": "include",
      "regions": [
        { "x1": 50, "y1": 50, "x2": 400, "y2": 400 }
      ]
    }],
    "output": { "format": "jpeg", "quality": 85 }
  }
}

mode: "include" blurs only inside the regions; the rest stays sharp. mode: "exclude" blurs everything except the regions — use it to protect a subject while blurring the background.

POST/v2/consumer/workflows
Set your Civitai API token via the Token button in the navbar to enable Try It.
Request body — edit to customize (e.g. swap the image URL or prompt)
Valid JSON

Full-image blur ​

mode: "exclude" with an empty regions array blurs the entire image (nothing is excluded):

json
{
  "type": "blur",
  "blur": 40,
  "mode": "exclude",
  "regions": []
}
POST/v2/consumer/workflows
Set your Civitai API token via the Token button in the navbar to enable Try It.
Request body — edit to customize (e.g. swap the image URL or prompt)
Valid JSON

PNG with metadata stripped ​

json
{
  "$type": "convertImage",
  "input": {
    "image": "https://...",
    "output": { "format": "png", "hideMetadata": true }
  }
}
POST/v2/consumer/workflows
Set your Civitai API token via the Token button in the navbar to enable Try It.
Request body — edit to customize (e.g. swap the image URL or prompt)
Valid JSON

Transforms reference ​

Transforms run in array order. You can chain multiple transforms — for example, resize first and then blur.

resize ​

FieldDefaultNotes
type— ✅Must be "resize".
targetWidth(none)Target width in pixels, 1–4096. Height is calculated to preserve aspect ratio.

blur ​

FieldDefaultNotes
type— ✅Must be "blur".
blur— ✅Gaussian blur intensity, 1–100.
mode— ✅"include" — blur only inside regions. "exclude" — blur everywhere except regions.
regions[]Pixel-coordinate rectangles { x1, y1, x2, y2 }. With mode: "exclude" and no regions, the entire image is blurred. With mode: "include" and no regions, nothing is blurred.

Output formats reference ​

jpeg ​

FieldDefaultNotes
format— ✅"jpeg"
quality851–100. Higher = better quality, larger file.
hideMetadatafalseStrip EXIF and other metadata.

png ​

FieldDefaultNotes
format— ✅"png"
hideMetadatafalseStrip metadata.

PNG is lossless — no quality setting.

webp ​

FieldDefaultNotes
format— ✅"webp"
quality851–100. Applies only when lossless: false.
losslessfalseEnable lossless WebP compression.
maxFramesnullCap frame count for animated sources. Set to 1 to extract only the first frame.
hideMetadatafalseStrip metadata.

gif ​

FieldDefaultNotes
format— ✅"gif"
maxFramesnullCap frame count. Set to 1 to extract the first frame.
hideMetadatafalseStrip metadata.

JPEG and PNG with animated sources

JPEG and PNG are inherently single-frame. Animated source images (GIF, animated WebP) are automatically reduced to the first frame when encoding to these formats — there is no maxFrames field to set. Use WebP or GIF output to preserve animation.

Reading the result ​

json
{
  "status": "succeeded",
  "steps": [{
    "name": "0",
    "$type": "convertImage",
    "status": "succeeded",
    "output": {
      "blob": {
        "id": "blob_...",
        "url": "https://.../signed.jpg",
        "width": 512,
        "height": 342
      }
    }
  }]
}

Blob URLs expire — see Reading results.

Public output ​

"public": true stores the result in a bucket that serves it directly. The returned url is then unsigned and permanent for the blob's lifetime, and urlExpiresAt, if set, is when the object is scheduled for deletion:

json
{
  "blob": {
    "id": "blob_...",
    "url": "https://.../blob_....jpg",
    "urlExpiresAt": null
  }
}

The point of this is caching. A signed URL carries a fresh signature every time it is issued, so the same image is a different URL — and a different CDN cache key — on every request. An unsigned URL is stable, so a CDN can serve it, and reads never reach the orchestrator at all.

Restricted, and genuinely public

This field requires an elevated token; ordinary consumer tokens get 403. Anyone holding the URL can read the object, with no NSFW level, blocked reason, or mature-content restriction applied — and because the URL is served straight from storage, a block decided after the fact does not take it back. Only deleting the blob does.

A public result does not reuse a cached private one, or vice versa. The two are separate objects, so asking for "public": true re-runs the conversion even when the same conversion already exists privately.

Result caching

convertImage is deterministic: the same source image, transforms, and output settings always produce the same blob. The orchestrator caches the result, so repeated identical calls skip re-processing and return the cached blob immediately.

Cost ​

Flat 1 Buzz per step — regardless of source image size, number of transforms, or output format.

Chaining with other steps ​

convertImage is most useful as a post-processing step. Chain it after imageGen using $ref to reference the previous step's output:

json
{
  "steps": [
    {
      "name": "gen",
      "$type": "imageGen",
      "input": {
        "engine": "flux2",
        "model": "klein",
        "operation": "createImage",
        "modelVersion": "4b",
        "prompt": "A photorealistic cat sitting in a sunny garden"
      }
    },
    {
      "name": "convert",
      "$type": "convertImage",
      "input": {
        "image": { "$ref": "gen", "path": "output.images[0].url" },
        "transforms": [{ "type": "resize", "targetWidth": 1024 }],
        "output": { "format": "webp", "quality": 90 }
      }
    }
  ]
}

Troubleshooting ​

SymptomLikely causeFix
400 with "output is required"Missing output fieldoutput is always required — include at minimum { "format": "jpeg" }.
400 with "targetWidth out of range"Value outside 1–4096Clamp to 1–4096.
400 with "blur out of range"Value outside 1–100Clamp to 1–100.
400 with "mode is required"Blur transform sent without modemode is required on blur — set "include" or "exclude".
403 with "Publicly readable blob output is restricted to privileged callers""public": true on an ordinary tokenDrop public (or omit it) — the default signed URL works for every caller.
Output height different from expectedresize maintains aspect ratioOnly targetWidth is specified; height is derived from the original aspect ratio.
Animated source collapsed to one frameJPEG or PNG output requestedThese formats are single-frame; use WebP or GIF output to preserve animation.

Civitai Developer Documentation