KRA to JPG API
Send a .kra to /v2/convert/kra/to/jpg and get a baseline JPEG of the visible layers. JPEG has no transparency, so empty and soft-edged parts of the canvas are blended onto white, or onto the color you pass in AlphaColor.
- Endpoint
- POST /v2/
convert/ kra/ to/ jpg - Accepts
- kra
- Sample timing
- 25 ms median of 5 runsHow we measure
- Request size
- Up to 10 MB on the Free plan or 100 MB on paid plans, all files together
Request and response
Every sample below ran against the API before this page was published. Set PDFCONVERSIONAPI_KEY to your key and run it as is.
curl -sS -X POST \
https://api.pdfconversionapi.com/v2/convert/kra/to/jpg \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@rocket-sticker.kra \
--form-string 'AlphaColor=#1B1F3B' \
--form-string ImageQuality=90 \
-o response.json
# FileData is base64. Save the first file in converted/,
# or print the JSON error.
if jq -e '.Files' response.json > /dev/null; then
mkdir -p converted
name=$(jq -r '.Files[0].FileName' response.json)
jq -r '.Files[0].FileData' response.json \
| base64 --decode > "converted/$name"
else
cat response.json
fiimport base64
import os
import requests
key = os.environ["PDFCONVERSIONAPI_KEY"]
response = requests.post(
"https://api.pdfconversionapi.com/v2/convert/kra/to/jpg",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("rocket-sticker.kra", "rb"))],
data={
"AlphaColor": "#1B1F3B",
"ImageQuality": "90",
},
timeout=180,
)
result = response.json()
if not response.ok:
raise SystemExit(f"{result['Code']}: {result['Message']}")
os.makedirs("converted", exist_ok=True)
for file in result["Files"]:
path = os.path.join("converted", file["FileName"])
with open(path, "wb") as out:
out.write(base64.b64decode(file["FileData"]))
print(path, file["FileSize"], "bytes")
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
const form = new FormData();
const file = "rocket-sticker.kra";
form.append("File", new Blob([await readFile(file)]), file);
form.append("AlphaColor", "#1B1F3B");
form.append("ImageQuality", "90");
const url = "https://api.pdfconversionapi.com/v2/convert/kra/to/jpg";
const key = process.env.PDFCONVERSIONAPI_KEY;
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${key}` },
body: form,
});
const result = await response.json();
if (!response.ok) {
throw new Error(`${result.Code}: ${result.Message}`);
}
await mkdir("converted", { recursive: true });
for (const file of result.Files) {
const path = join("converted", file.FileName);
await writeFile(path, Buffer.from(file.FileData, "base64"));
console.log(path, file.FileSize, "bytes");
}
{
"ConversionCost": 1,
"ConversionTime": 0.025,
"Files": [
{
"FileName": "rocket-sticker.jpg",
"FileExt": "jpg",
"FileSize": 12831,
"FileData": "/9j/4AAQSkZJRgABAgAAAQAB…"
}
]
}Response from our test run on 2026-11-03. ConversionTime shows the median of 5 runs. FileData is shortened here; the real response carries the whole file as base64.
The sample, converted
The same file the code sends. Download the input and the output and compare them yourself.

- Input
- rocket-sticker.kra (108 KB)
- Output
- rocket-sticker.jpg (13 KB)
- Source
- A cartoon rocket sticker on a transparent canvas that we drew and saved as a six-layer KRA file (one layer hidden, one faded by a transparency mask). (CC0-1.0). How it was made
- Made by
- 2026-11-04, API build
9eeeb0640aba
Parameters
Send these as form fields next to the file. Names are case-insensitive. If you set one of the documented options below that we don't support yet, the request fails with a 400 that names it instead of returning a file made without it.
| Parameter | What it does |
|---|---|
AlphaColorstring, default white | Background the sticker is laid on. The sample sends #1B1F3B, so the 83,159 empty pixels become midnight blue and the soft shadow blends into it instead of into white.Values: A color name (white, black, red, green, blue, gray), #RRGGBB or R,G,B |
BackgroundColorstring, default white | Used when AlphaColor is not sent. BackgroundColor=black gave a black field and an 11,052-byte file.Values: Same as AlphaColor |
ImageQualityinteger, default 85 | JPEG quality. The sample's 90 produced 12,831 bytes; 85 on white gave 10,840 and 50 gave 6,912. ConvertAPI documents 75 for PNG to JPG.Values: 1–100 |
ImageWidthinteger | Output width; the square canvas keeps the height equal. On white at quality 85, 160 gave a 4,580-byte JPEG and 800 an upscaled one of 36,303 bytes.Values: 1–20000 |
ImageHeightinteger | Output height. With ImageWidth it is a bounding box: 200 × 100 returned 100 × 100.Values: 1–20000 |
ScaleProportionsboolean, default true | false stretches to the exact box, so 200 × 100 gives a wide, flattened rocket (3,914 bytes). |
ScaleIfLargerboolean, default false | true skips any enlargement; ImageWidth=800 then leaves the 320 px painting as it is. |
ScaleImageboolean, default true | false trims to ImageWidth × ImageHeight from the top-left corner with no scaling. |
ColorSpaceenum, default default | gray and monochrome write a one-channel JPEG (6,195 and 6,294 bytes for the sticker on white). monochrome is thresholded after the backdrop is applied, so apart from ringing at edges the pixels are black or white.Values: default, rgb, gray, monochrome (also srgb, truecolors, grayscale); cmyk returns 400 |
ImageResolutioninteger | Sets the JFIF density in dots per inch. Without it the JPEG says density 1 × 1 with no unit, even though the KRA was saved at 300 ppi.Values: 10–800 |
FileNamestring | Changes the returned name; by default the JPEG is called rocket-sticker.jpg. |
StoreFileboolean, default false | true stores the JPEG for 3 hours and replies with a download link instead of base64. |
What carries over, and what doesn't
Kept
- Every visible layer, merged as in the file: opacity, the masked flame and the offset window layer all show
- Soft edges, blended into the chosen background rather than cut off: on
#1B1F3Bthe 35% shadow is a faint 34, 34, 62 against the 27, 31, 60 field - Full color resolution: baseline JPEG with 4:4:4 sampling, so color is not subsampled
- The canvas size, 320 × 320, unless you resize
Lost or not yet supported
- Transparency. JPEG can't store it, so the empty canvas takes the
AlphaColor, white when none is sent. - Some detail, since JPEG is lossy: the 90-quality sample is 12,831 bytes, while the lossless PNG of the same merge is 27,925.
- The 300 ppi setting and the embedded color profile; send
ImageResolutionif a print tool needs a DPI value. - Vector, filter, fill and clone layers, which are skipped without a warning in the response.
- 16-bit precision: a 16-bit canvas is reduced to 8 bits per channel.
Limits
- One KRA per request; canvases above 100,000,000 pixels return 413, and a side over 300,000 px returns 422.
- JPEG sides stop at 65,500 px, just under the 65,535 the format allows, a size widely used JPEG readers still open. A 65,501 × 10 canvas returned 413
JPEG images can be at most 65,500 pixels on a side, and this one is 65,501×10, and 65,500 × 10 converted. - Requests up to 10 MB on the Free plan or 100 MB on paid plans, all files and fields together.
- Each conversion has 120 seconds before a 504.
- Tested with KRA files from our own writer, not yet with files saved by Krita.
Where teams use it
Shop and portfolio images
When a print-on-demand listing or a portfolio site takes JPEG, convert the Krita file directly and pick the backdrop with AlphaColor, so a sticker can sit on the store's own brand color.
Sharing work in progress
Clients and editors often only need to look at the art, not open the layers. A JPEG at quality 85 is small enough to attach to a message: the sample sticker is 10,840 bytes on white.
Thumbnails for an art library
Set ImageWidth to get a card-size preview in the same request; at 160 px the sticker came to 4,580 bytes on white at quality 85.
Questions
What color do transparent parts of my KRA become?
White, unless you set AlphaColor (or BackgroundColor). Partly transparent pixels are mixed with that color by their alpha, so a soft shadow fades into it. The sample on this page uses #1B1F3B, and its top-left pixel decodes as 27, 31, 60.
Which quality should I send?
We use 85 when ImageQuality is missing. On the sticker on white, 50 gave 6,912 bytes, 85 gave 10,840 and 90 gave 12,788; the sample's 90 on #1B1F3B is 12,831. At 50 we could see ringing along the edges of the red fins when zoomed in, so check flat areas and sharp edges before going that low.
Why does my blend mode look different from Krita?
Most of Krita's common modes, such as Multiply, Screen, Overlay, Add and Soft Light, matched the blend formulas in our tests. Linear Light, Hard Mix, Erase, Behind and modes we don't know are drawn as Normal, without an error.
Convert your first KRA file in a minute.