ForHosting KIT · Developer Utilities

Color palette contrast matrix

A palette can look coherent and still contain combinations that make text difficult or impossible to read.

● BetaFree · in your browser
Use it from WebAPIEmailTelegramApp soon

This color palette contrast matrix calculates the WCAG 2 relative luminance of every supplied hex color, compares every color with every other color, and returns the results in a stable square matrix. Designers, developers, and accessibility reviewers can inspect an entire design-system palette at once instead of checking pairs individually. Inputs are validated, colors are normalized, and the deterministic result is suitable for automated audits and versioned reports.

Read the matrix without losing track of the colors

Send an array containing between two and one hundred hex colors. Three-digit and six-digit forms are accepted, with or without a leading hash, and every valid value is normalized to a lowercase six-digit code. The response lists those normalized colors in the same order and assigns each an index. Rows and columns of the matrix use precisely that order, so the value at row two and column five describes the contrast between colors at indexes two and five. The diagonal is always 1 because a color has no contrast with itself, and the matrix is symmetric because reversing foreground and background does not change the WCAG contrast ratio. Each displayed ratio is rounded to two decimal places for readable, stable output. The accompanying luminance values are rounded to six decimal places. Duplicate colors are retained as separate palette positions, which is useful when auditing tokens that share a value but serve different semantic roles. This positional design makes the response straightforward to render as a table, store as an audit artifact, or compare between releases.

Understand the WCAG calculation and thresholds

The calculation follows the WCAG 2 relative-luminance method for sRGB colors. Each red, green, and blue channel is converted from its encoded sRGB value to linear light, then combined with the standard luminance coefficients. For any pair, the lighter luminance plus 0.05 is divided by the darker luminance plus 0.05, producing a ratio from 1 to 21. The response includes the familiar WCAG reference thresholds: 4.5 for AA normal text, 7 for AAA normal text, 3 for AA large text, and 4.5 for AAA large text. Compare matrix cells with the threshold appropriate to the actual content and typography. A ratio alone does not declare a complete interface accessible, because font size, weight, interaction state, non-text elements, and user context still matter. The tool deliberately returns numeric evidence instead of a single blanket pass or fail. That lets an audit apply the correct rule to each intended pairing and prevents a rounded presentation value from being mistaken for a broader accessibility guarantee.

Use deterministic output in design-system audits

A full matrix is most useful when palette checking is repeatable. Keep colors in a documented order, such as neutrals followed by brand, status, and accent tokens, then save the returned matrix with the design-system release. A continuous-integration check can compare selected cells against required thresholds, while a reviewer can scan the complete table for unexpected weak combinations. Because the algorithm uses no network calls, randomness, current time, browser styling, or color-profile guessing, identical JSON input produces identical JSON output. Invalid array shapes, palettes outside the supported size, and malformed hex values are rejected with a clear index so data problems do not become misleading ratios. The one-hundred-color ceiling bounds the quadratic matrix at ten thousand cells and keeps both execution and response size practical. Treat transparency and compositing before calling this capability: alpha colors are intentionally rejected because their visible result depends on a background. Likewise, convert named colors, HSL, wide-gamut values, or design-tool objects to opaque sRGB hex first so every audit has an explicit and reproducible color basis.

Audit design tokens

Generate one indexed matrix for brand, surface, text, border, and status tokens before publishing a design-system release.

Check theme migrations

Compare the matrix produced by old and new palettes to find combinations whose contrast weakened during a redesign.

Automate accessibility review

Feed stable ratios into continuous-integration rules that enforce the appropriate WCAG threshold for approved token pairings.

What does one request cost?

The API base price is $0.002 per request.

Which color formats are accepted?

Opaque three- or six-digit sRGB hex colors are accepted, with or without a leading hash. Alpha, named, HSL, and wide-gamut formats are rejected.

How do rows and columns map to colors?

Both axes follow the original input order. Each returned color includes its index, and matrix[row][column] is the ratio for those two indexed colors.

Why is every diagonal value 1?

A color compared with itself has identical luminance, so the WCAG contrast formula always produces a ratio of 1.

Does a ratio prove that a design is accessible?

No. It provides the color-contrast evidence used by WCAG checks, but accessibility also depends on typography, component states, content, and correct use of each color pair.

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.

POSThttps://api.kit.forhosting.com/color/palette-contrast-matrix

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.

curl -X POST https://api.kit.forhosting.com/color/palette-contrast-matrix \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"colors":["#ffffff","#111827","#2563eb","#facc15"]}'
{
  "colors": [
    "#ffffff",
    "#111827",
    "#2563eb",
    "#facc15"
  ]
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "color.palette_contrast_matrix",
  "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.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

max_items100
HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

Read the full KIT documentation →