Colour API: hex to RGB, HSL and OKLCH, plus WCAG contrast check
Give a hex colour and get it back in the formats designers and CSS use, plus its relative luminance. Add a second colour and you also get the WCAG 2 contrast ratio and whether it passes AA and AAA for normal and large text.
/v1/color?hex=1f6f5c&against=ffffff returns JSON. No key, CORS on, 60 requests a minute./v1/color
Colour formats (hex, RGB, HSL, OKLCH) and WCAG contrast. Change the values and press Send request to call the live API.
Parameters
| Name | Type | What it does | Default |
|---|---|---|---|
hex required | string | Colour like 1f6f5c or #fff (encode # as %23) | — |
against | string | Second colour for a contrast check | — |
Example
Request:
GET https://api.oddlathe.com/v1/color?hex=1f6f5c&against=ffffff
Response (generated by the real code when these docs were last built):
{
"hex": "#1f6f5c",
"rgb": {
"r": 31,
"g": 111,
"b": 92,
"css": "rgb(31 111 92)"
},
"hsl": {
"h": 166,
"s": 56,
"l": 28,
"css": "hsl(166 56% 28%)"
},
"oklch": {
"l": 0.4888,
"c": 0.0819,
"h": 173.5,
"css": "oklch(48.9% 0.082 173.5)"
},
"relative_luminance": 0.1243,
"best_text": "#ffffff",
"contrast": {
"against": "#ffffff",
"ratio": 6.02,
"aa_normal": true,
"aa_large": true,
"aaa_normal": false,
"aaa_large": true
}
}
Code examples
curl 'https://api.oddlathe.com/v1/color?hex=1f6f5c&against=ffffff'const params = new URLSearchParams({
hex: "1f6f5c",
against: "ffffff"
});
const res = await fetch(`https://api.oddlathe.com/v1/color?${params}`);
if (!res.ok) throw new Error((await res.json()).error.message);
const data = await res.json();
console.log(data);import json, urllib.parse, urllib.request
params = urllib.parse.urlencode({"hex": "1f6f5c", "against": "ffffff"})
url = "https://api.oddlathe.com/v1/color?" + params
# Send a User-Agent: the edge network refuses Python's default one.
req = urllib.request.Request(url, headers={"User-Agent": "my-script/1.0"})
with urllib.request.urlopen(req, timeout=10) as r:
data = json.load(r)
print(data)When it's useful
- Checking brand colours for accessible text before a release
- Design token pipelines that need OKLCH values
- Automated contrast checks in CI
Good to know
- Accepts 3- or 6-digit hex with or without
#. Encode # in a URL as%23, or just leave it out. - WCAG 2 contrast is (L1 + 0.05) / (L2 + 0.05). AA needs 4.5:1 for normal text and 3:1 for large text (24 px, or 18.66 px bold); AAA needs 7:1 and 4.5:1.
- The ratio is shown rounded to two decimals, but the pass/fail flags use the exact value, so a ratio of 4.497 displays as 4.5 and still fails AA.
best_texttells you whether black or white text reads better on the colour.
Contrast uses the WCAG 2 relative-luminance formula; AA needs 4.5:1 for body text and 3:1 for large text, AAA needs 7:1 and 4.5:1.
Errors
Errors are JSON like {"error": {"code": "…", "message": "…"}}. The ones this endpoint can return:
missing_param(400): a required parameter is missing or emptybad_param(400): a value is the wrong type or out of range (the message says which)rate_limited(429): over 60 requests a minute; wait for Retry-After seconds
Questions
Why does my brand colour fail on white?
Mid-tone colours like many greens and oranges sit near 3:1 against white. Darken them for body text, or keep them for large headings and icons.
What is OKLCH?
A newer way of describing colour by lightness, chroma and hue that matches how bright colours actually look, which makes it good for building even tint scales.
Related endpoints
/v1/slugTurn a title into a clean URL slug/v1/unitsConvert length, mass, temperature, data-size or data-rate units
Prefer a page to an API?
- Colour converter & contrast checker on Tooltern: same job, nothing leaves your browser.
Published , updated · OpenAPI 3.1 spec · Limits and privacy