HWB to CMYK converter
Hue 0 with no whiteness and no blackness is pure red, which prints as cyan 0 %, magenta 100 %, yellow 100 % and black 0 %. Get stable ink percentages for a vendor form or soft-proof estimate. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Hue
- 0
- Whiteness
- 0
- Blackness
- 0
- Red
- 255
- Green
- 0
- Blue
- 0
- Cyan
- 0
Need an HWB swatch turned into CMYK ink percentages for a print preview, packaging note or production ticket? Enter hue in degrees plus whiteness and blackness as percentages from zero to one hundred, and receive cyan, magenta, yellow and key as whole-number percentages, intermediate RGB channels, and ready-to-paste hwb() and cmyk() strings. The path is fully deterministic: CSS-style HWB to RGB, then textbook subtractive RGB to CMYK, with no network call and no random seed.
What HWB and CMYK mean for design and print
HWB stands for hue, whiteness and blackness. It is the model browsers expose as the hwb() CSS function and many design tools use when a designer wants a pure hue mixed with white and black rather than juggling saturation and lightness. Hue is an angle on the color wheel in degrees from zero through three hundred sixty.
Whiteness and blackness are percentages that mix the pure hue toward white paper and black ink respectively; together they must not exceed one hundred percent in this converter so the mixture stays inside the natural HWB domain without silent renormalization surprises. CMYK is the subtractive process-ink model used for commercial print: cyan, magenta and yellow absorb light on paper, and key (black) deepens shadows and type without stacking three colored inks.
Teams often pick or tweak a brand tint as HWB in a UI prototype, then need stable CMYK percentages for a dieline, a vendor form or a quick soft-proof estimate. This capability does only that job: three validated HWB numbers in, print percentages and companion strings out. It is not a full ICC soft-proof pipeline for photography, but it is a reliable analytic baseline for previews, QA scripts and handoff notes that must match every time the same HWB triple is submitted.
How the conversion algorithm works
First the engine checks that hue lies between zero and three hundred sixty inclusive and that whiteness and blackness each lie between zero and one hundred. Valid inputs are normalized to zero-to-one fractions. When whiteness plus blackness reaches one, the result is a pure gray whose level is whiteness divided by the sum, matching the CSS Color Level 4 HWB path.
Otherwise a fully saturated pure-hue RGB triple is built from the hue sector (the same geometry as HSL with full saturation and mid lightness), then each channel is scaled by one minus whiteness minus blackness and offset by whiteness. Those RGB floats are rounded to eight-bit integers from zero to two hundred fifty-five.
CMYK follows the classic subtractive formula: key is one minus the maximum normalized channel; for non-black colors each of cyan, magenta and yellow is one minus the channel minus key, divided by one minus key, then expressed as a whole percentage. Pure black yields zero cyan, magenta and yellow with key one hundred.
What to enter and how to read the result
On success the body includes those inputs, red, green and blue, cyan, magenta, yellow, key, plus cmyk and hwb display strings. Status is beta while the public surface stabilizes, but the arithmetic is fixed textbook math and will not drift for the same inputs. Prefer explicit numeric fields over free-text color strings so OpenAPI, SDKs and form controls stay aligned and you avoid ambiguous parsing of hex, rgb() or hwb() notation on the wire.
Pair this tool with your design-system docs so digital HWB tokens and print CMYK specs share one deterministic conversion path instead of divergent spreadsheets. For pipelines, submit each conversion as its own task and store the four ink percentages next to the original HWB token for audit trails and press-ready exports.
What you can do with it
Print previews from HWB UI tokens
Turn design-system HWB brand tints into CMYK percentages for packaging proofs, stationery and vendor specification sheets.
Design QA before press handoff
Validate that HWB swatches from a prototype map to expected process-ink values before files leave for commercial print.
Automation and catalog pipelines
Batch-convert product or catalog colors stored as HWB into cyan, magenta, yellow and key for CMS jobs and print tickets.
FAQ
What inputs does the HWB to CMYK converter accept?
Three finite numbers: hue (0–360 degrees), whiteness (0–100) and blackness (0–100). Whiteness plus blackness must not exceed 100.
What does the response contain?
The validated hue, whiteness and blackness; intermediate red, green and blue (0–255); cyan, magenta, yellow and key as whole percentages; plus hwb() and cmyk() strings.
What happens if whiteness plus blackness is more than 100?
The conversion stops and tells you the sum is too high, instead of quietly returning an unexpected gray. Lower one of the two values so that together they stay at 100 or below.
How is the black ink percentage worked out?
Black is one minus the strongest of the red, green and blue channels. Pure red has a full red channel, so black is 0 % and the color is carried by magenta and yellow.
Can this replace a professional print proof?
No. It applies the textbook formula from screen color to process inks, which is reliable for previews, checks and handoff notes, but it does not account for a specific press, paper or color profile.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/color/hwb-cmyk \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"hue":0,"whiteness":0,"blackness":0}'const res = await fetch("https://api.kit.forhosting.com/color/hwb-cmyk", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"hue": 0,
"whiteness": 0,
"blackness": 0
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/color/hwb-cmyk",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"hue": 0,
"whiteness": 0,
"blackness": 0
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/color/hwb-cmyk", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"hue":0,"whiteness":0,"blackness":0}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"hue":0,"whiteness":0,"blackness":0}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/color/hwb-cmyk", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"hue": 0,
"whiteness": 0,
"blackness": 0
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "color.hwb_cmyk",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
The converter validates every field and rejects whiteness or blackness outside range or a sum above one hundred with a clear invalid_input message so bad values never reach a press queue. Run it free in your browser or call the same pure logic through the API at $0.002 per successful request.
How the conversion algorithm works
If their sum is greater than one hundred, the request fails with invalid_input naming the sum rule so callers can fix the mixture instead of receiving an unexpected gray. The response echoes the validated HWB fields, the intermediate red, green and blue integers, the four CMYK percentages, and compact hwb() and cmyk() strings for copy-paste into stylesheets or tickets.
API contract, pricing and practical use
POST a JSON object with three required finite numbers: hue, whiteness and blackness. Missing fields, non-finite values, a channel outside its declared range, or whiteness plus blackness above one hundred raise invalid_input and are not billed. Successful API conversions cost a flat $0.002 per request; the free browser path runs the identical pure solve module without an account, which is ideal for a single swatch check or a classroom demo of hue versus process ink.
Technical questions
How much does the HWB to CMYK API cost?
Each successful API call costs $0.002. The same converter runs free in your browser with no account required.
What happens if whiteness plus blackness is greater than 100?
The request fails with invalid_input explaining the sum rule. Invalid client input is not charged.
Is the conversion deterministic?
Yes. It uses the CSS HWB-to-RGB path and the standard subtractive RGB-to-CMYK formula with fixed rounding, so the same HWB triple always produces the same JSON.