Drei Endpunkte für die Arbeit mit Farben: contrast für Barrierefreiheits-Audits, shades für Design-Tokens und harmonische Paletten sowie extract, um die dominanten Farben aus einem Bild zu holen. Die Rechen-Endpunkte laufen in reinem PHP und liefern byte-identische Ergebnisse wie unsere Web-Tools; die Extraktion nutzt eine Python-Pipeline und unterliegt daher demselben strengen Rate-Limit wie die Images API.

# Check black-on-white contrast
curl "https://jinero.online/api/v1/colors/contrast?fg=%23000&bg=%23fff"

# Generate shades for a brand color
curl "https://jinero.online/api/v1/colors/shades?hex=%233b82f6&step=10"
const r = await fetch("https://jinero.online/api/v1/colors/contrast?fg=%23000&bg=%23fff");
const { ratio, aa, aaa } = await r.json();

Alle Endpunkte sind öffentlich – kein Schlüssel nötig. Limits pro IP:

# Anonymous limits (per IP):
#   GET  /colors/contrast    60 req/min
#   GET  /colors/shades      60 req/min
#   GET  /colors/name        60 req/min
#   POST /colors/extract      5 req/min  (Python pipeline)

# Max image upload: 10 MB
# Max image_url fetch: 10 MB (server-side, image/* only)

Berechnet das WCAG-2.1-Kontrastverhältnis (auf Basis der relativen Luminanz) zwischen zwei Farben und gibt AA/AAA-Flags für normalen und großen Text zurück. Akzeptiert #rgb, #rrggbb, rgb(...) oder hsl(...) als Eingabe.

GET https://jinero.online/api/v1/colors/contrast
ParameterTypBeschreibung
fg string Vordergrundfarbe. Hex, rgb() oder hsl().
bg string Hintergrundfarbe. Gleiche Formate wie fg.
curl "https://jinero.online/api/v1/colors/contrast?fg=%23000000&bg=%23ffffff"

# Equivalent with rgb()
curl "https://jinero.online/api/v1/colors/contrast?fg=rgb(0,0,0)&bg=rgb(255,255,255)"
const url = new URL("https://jinero.online/api/v1/colors/contrast");
url.searchParams.set("fg", "#1d4ed8");
url.searchParams.set("bg", "#ffffff");

const r = await fetch(url);
const data = await r.json();
if (!data.aa.normal) console.warn(`Ratio ${data.ratio_string} fails WCAG AA`);
$r = Http::get("https://jinero.online/api/v1/colors/contrast", [
    "fg" => "#1d4ed8",
    "bg" => "#ffffff",
]);
$ratio = $r->json("ratio");
Beispielantwort
{
  "success": true,
  "foreground": "#000000",
  "background": "#ffffff",
  "ratio": 21,
  "ratio_string": "21.00:1",
  "aa":  { "normal": true, "large": true },
  "aaa": { "normal": true, "large": true },
  "thresholds": {
    "aa_normal": 4.5,
    "aa_large":  3,
    "aaa_normal": 7,
    "aaa_large": 4.5
  }
}

Erzeugt ein komplettes Design-Token-Set aus einer Grundfarbe: Tönungen (heller), Schattierungen (dunkler) und fünf Harmonien (komplementär, analog ±30°, triadisch ±120°, split-komplementär, tetradisch). Jede Farbe kommt mit hex/rgb/hsl-Strings, relativer Luminanz und einer empfohlenen Textfarbe.

GET https://jinero.online/api/v1/colors/shades
ParameterTypBeschreibung
hex string Grundfarbe. Hex/rgb()/hsl().
step integer Schrittweite in Prozent: 5, 10 (Standard), 20 oder 25.
limit integer Obergrenze für die Anzahl der Tönungen/Schattierungen. Standardmäßig wird in Schritten bis 100 % aufgefüllt (typischerweise 9 bei step=10).
curl "https://jinero.online/api/v1/colors/shades?hex=%233b82f6&step=20"
const r = await fetch("https://jinero.online/api/v1/colors/shades?hex=%231d4ed8&step=10");
const { base, tints, shades, harmonies } = await r.json();

// Drop into a design token map
const tokens = Object.fromEntries(
  tints.map(t => [`brand-${100 - t.percent}`, t.hex])
);
$res = Http::get("https://jinero.online/api/v1/colors/shades", ["hex" => "#3b82f6", "step" => 20]);
$harmony = $res->json("harmonies.complementary.0.hex");
Beispielantwort
{
  "success": true,
  "step": 20,
  "base": {
    "hex": "#3b82f6",
    "rgb": [59, 130, 246],
    "rgb_string": "rgb(59, 130, 246)",
    "hsl": [217, 91, 60],
    "hsl_string": "hsl(217, 91%, 60%)",
    "luminance": 0.2355,
    "is_light": true,
    "text_color": "#000000",
    "contrast_on_white": 3.68,
    "contrast_on_black": 5.71
  },
  "tints":  [ { "percent": 20, "hex": "#629bf8", ... } ],
  "shades": [ { "percent": 20, "hex": "#2f68c5", ... } ],
  "harmonies": {
    "complementary":      [ { "rotation": 180, "hex": "#f6af3b", ... } ],
    "analogous":          [ { "rotation": -30, ... }, { "rotation": 30, ... } ],
    "triadic":            [ { "rotation": -120, ... }, { "rotation": 120, ... } ],
    "split_complementary":[ { "rotation": 150, ... }, { "rotation": 210, ... } ],
    "tetradic":           [ { "rotation": 90, ... }, { "rotation": 180, ... }, { "rotation": 270, ... } ]
  }
}

Liefert den passendsten lesbaren Namen für eine oder mehrere Farben – nächster Treffer (wahrnehmungsbasierte redmean-Distanz) in einem Datensatz mit ~31.000 Farben. Praktisch zum Beschriften extrahierter Paletten, generierter Farbfelder oder beliebiger Hex-Werte.

GET https://jinero.online/api/v1/colors/name
ParameterTypBeschreibung
hex string Ein Hex-Wert oder mehrere, durch Kommas getrennt (bis zu 100). Z. B. #3b82f6,#000,#ff7f50.
# Single
curl "https://jinero.online/api/v1/colors/name?hex=%233b82f6"

# Batch (comma-separated)
curl "https://jinero.online/api/v1/colors/name?hex=%233b82f6,%23000,%23ff7f50"
const r = await fetch("https://jinero.online/api/v1/colors/name?hex=" + encodeURIComponent("#3b82f6,#ff7f50"));
const { colors } = await r.json();
// colors: [{ input, name, hex, exact, distance }]
$r = Http::get("https://jinero.online/api/v1/colors/name", ["hex" => "#3b82f6,#ff7f50"]);
$name = $r->json("colors.0.name"); // "Dodger Blue"
Beispielantwort
{
  "success": true,
  "count": 3,
  "colors": [
    { "input": "#3B82F6", "name": "Dodger Blue", "hex": "#3E82FC", "exact": false, "distance": 10.91 },
    { "input": "#000000", "name": "Black",       "hex": "#000000", "exact": true,  "distance": 0 },
    { "input": "#FF7F50", "name": "Coral",       "hex": "#FF7F50", "exact": true,  "distance": 0 }
  ]
}

Holt die N wichtigsten Farben aus einem beliebigen Bild – als hochgeladene Datei oder über eine öffentliche URL. Basiert auf k-Means-Clustering mit drei Modi: balanced, vibrant (bevorzugt gesättigte Farbtöne) und muted (bevorzugt gedeckte, neutrale Töne). Jede Farbe kommt mit Namen zurück (nächster Treffer) – eine einsatzbereite, beschriftete Palette mit einem einzigen Aufruf.

POST https://jinero.online/api/v1/colors/extract
ParameterTypBeschreibung
image Datei (multipart) Bild-Upload – jpg, jpeg, png, webp, gif, bmp. Max. 10 MB. Nicht mit image_url kombinierbar.
image_url string Öffentliche Bild-URL, die der Server abruft (max. 10 MB, Antwort muss image/* sein).
count integer Anzahl der zurückgegebenen dominanten Farben. 2–16, Standard 8.
mode string balanced (Standard) · vibrant · muted.
# Option 1: file upload
curl -X POST https://jinero.online/api/v1/colors/extract \
  -F "[email protected]" \
  -F "count=6" \
  -F "mode=vibrant"

# Option 2: URL fetch
curl -X POST https://jinero.online/api/v1/colors/extract \
  -H "Content-Type: application/json" \
  -d '{"image_url": "https://example.com/cover.jpg", "count": 6}'
// File upload
const form = new FormData();
form.append("image", file);
form.append("count", "6");
form.append("mode", "vibrant");

const r = await fetch("https://jinero.online/api/v1/colors/extract", { method: "POST", body: form });
const { colors } = await r.json();
// colors: [{ hex, rgb, hsl, percent, name, name_hex, name_exact }]
Beispielantwort
{
  "success": true,
  "mode": "vibrant",
  "count": 6,
  "colors": [
    { "hex": "#f9f9f9", "rgb": {"r":249,"g":249,"b":249}, "hsl": {"h":0,"s":0,"l":97.6}, "percent": 90.8, "name": "White", "name_hex": "#FFFFFF", "name_exact": false },
    { "hex": "#1d1c1b", "rgb": {"r":29,"g":28,"b":27},    "hsl": {"h":30,"s":3.6,"l":11}, "percent": 5.8, "name": "Cod Gray", "name_hex": "#1B1B1B", "name_exact": false },
    { "hex": "#a1989b", "rgb": {"r":161,"g":152,"b":155}, "hsl": {"h":340,"s":4.6,"l":61.4}, "percent": 1.9, "name": "Dusty Gray", "name_hex": "#A8989B", "name_exact": false }
  ]
}

Standard-HTTP-Semantik. Fehler liefern JSON mit dem Feld "message".

// 422 — invalid color format
{ "message": "Invalid color format. Accepts #rgb, #rrggbb, rgb(r,g,b), or hsl(h,s%,l%)." }

// 422 — neither image nor image_url provided
{ "message": "Provide one of: image (file) or image_url." }

// 422 — URL fetch failed (404 from remote, non-image content, > 10 MB)
{ "message": "Could not fetch image from URL." }

// 429 — rate limit exceeded (5 req/min on extract)
{ "message": "Too Many Attempts." }

Über die Colors API von jinero.online

Kostenlose REST-API für alle Farbberechnungen: WCAG-Kontrast, Schattierungen und Tönungen, fünf harmonische Paletten und Extraktion dominanter Farben per k-Means aus jedem Bild.

Bereit für WCAG 2.1

Kontrastverhältnisse durchlaufen dieselbe sRGB-Linearisierung wie in Google Lighthouse – deine Barrierefreiheits-CI kommt auf dieselben Zahlen.

Fünf Harmonien integriert

Komplementär, analog, triadisch, split-komplementär, tetradisch – alle als Drehung des Farbtons auf dem HSL-Farbkreis ausgehend von deiner Grundfarbe berechnet.

Bild → Palette

Extraktion dominanter Farben per k-Means in den Varianten vibrant / muted / balanced. Akzeptiert Uploads oder öffentliche URLs.

Design-Token-freundlich

Jede Farbe kommt mit hex, rgb, hsl, Luminanz und empfohlener Textfarbe zurück – übernimm sie direkt in deine Token-Map.

Häufig gestellte Fragen

Nein. Die Endpunkte für Kontrast und Schattierungen erlauben 60 Anfragen/min pro IP. Die Farbextraktion ist aufwendiger (k-Means in Python) und daher auf 5 Anfragen/min begrenzt. Für höhere Limits registriere dich und hol dir ein API-Token.

Hex mit oder ohne # (#rgb / #rrggbb), rgb(r,g,b) und hsl(h,s%,l%). Groß- und Kleinschreibung ist egal. Intern normalisieren wir vor der Berechnung auf 6-stelliges Hex in Kleinbuchstaben.

Es ist dieselbe Engine – die Webseite /colors/extract ruft dasselbe Python-Skript auf (resources/python/color_extract.py). Die API ergänzt nur einen JSON-Wrapper und lässt dich image_url übergeben, damit der Server das Bild abruft.

WCAG-2.1-Stufen: AA normaler Text 4,5:1, AA großer Text 3:1, AAA normal 7:1, AAA groß 4,5:1. Wir liefern das reine Verhältnis plus boolesche Flags für alle vier Prüfungen, damit du deine eigenen Regeln anwenden kannst.

Wir drehen den Farbton auf dem HSL-Farbkreis und behalten Sättigung und Helligkeit bei. Komplementär = +180°, analog = ±30°, triadisch = ±120°, split-komplementär = ±150°/210°, tetradisch = 90/180/270°. Andere Tools (auf Basis von LCH oder OKLCh) können unter denselben Namen andere Farben erzeugen.