Skip to main content
Back
API Integrations · Dev Tools

Pantone Color Matcher API

Cloudflare Worker API that matches any CMYK or RGB input to the nearest available Pantone fabric shade using Euclidean distance — built as the color engine for the Mockup Builder.

Cloudflare WorkersJavaScriptREST APICMYKPantone

A lightweight Cloudflare Worker that accepts CMYK or RGB color values and returns the nearest available Pantone fabric shade — ensuring every design produced by the Mockup Builder maps to a color that actually exists in production stock.

Tech Stack

LayerTools
RuntimeCloudflare Workers — serverless edge deployment
LanguageJavaScript (ESM)
MatchingEuclidean distance in 4D CMYK space and 3D RGB space
DatabasesTwo static JSON bundles — available kit fabric shades and sock stock options
EdgeDeployment
ZeroCold Start
4D CMYK + 3D RGBColor Spaces
4Input Buckets

Why It Exists

Designers were occasionally applying colors that looked right on screen but had no equivalent in the available Pantone fabric or sock stock — causing rework at production. Rather than relying on a designer knowing the full color catalogue by heart, a simple API was deployed that maps any picked color to the nearest real option automatically. The Mockup Builder calls it in the background when Match Colors is triggered.

How It Works

The API accepts up to four color buckets in a single POST — CMYK primary, RGB primary, CMYK secondary (socks), and RGB secondary — and returns the nearest Pantone match for each label.

Each input is scored against every entry in the reference database using straight-line (Euclidean) distance across all channels — the entry with the smallest distance wins.

The general Euclidean distance formula across n dimensions:

d(A, B) = √( (a₁−b₁)² + (a₂−b₂)² + ··· + (aₙ−bₙ)² )

Applied to each color space:

CMYK (4D):  d = √( (C₁−C₂)² + (M₁−M₂)² + (Y₁−Y₂)² + (K₁−K₂)² )

RGB  (3D):  d = √( (R₁−R₂)² + (G₁−G₂)² + (B₁−B₂)² )

In code, Math.hypot handles the squaring, summing, and square-root in one call:

// 4-dimensional CMYK space (C, M, Y, K)
const distanceCMYK = (a, b) =>
  Math.hypot(a.c - b.c, a.m - b.m, a.y - b.y, a.k - b.k);

// 3-dimensional RGB space (R, G, B)
const distanceRGB = (a, b) =>
  Math.hypot(a.r - b.r, a.g - b.g, a.b - b.b);

The full matching loop — scan every entry, track the minimum:

function distanceCMYK(a, b) {
  return Math.hypot(a.c - b.c, a.m - b.m, a.y - b.y, a.k - b.k);
}

function findClosestCMYK(input, db) {
  let best = null, dist = Infinity;
  for (const key in db) {
    const d = distanceCMYK(input, db[key].main);
    if (d < dist) { dist = d; best = key; }
  }
  return best;
}

export default {
  async fetch(request) {
    const { primary, primaryRGB, secondary, secondaryRGB } = await request.json();
    return new Response(JSON.stringify({
      primary:     matchBucket(primary,     cmykPrimaryDB,  'cmyk'),
      primaryRGB:  matchBucket(primaryRGB,  rgbPrimaryDB,   'rgb'),
      secondary:   matchBucket(secondary,   cmykSecondaryDB,'cmyk'),
      secondaryRGB:matchBucket(secondaryRGB,rgbSecondaryDB, 'rgb'),
    }), { headers: { 'Content-Type': 'application/json' } });
  }
};

Databases

Two separate reference sets are bundled directly into the Worker — no external DB calls, zero cold-start latency:

DatabaseUse
Kit_Colors.jsonAvailable garment Pantone fabric shades (CMYK)
Kit_Colors_RGB.jsonSame palette in RGB for screen preview
Socks_Colors.jsonAvailable sock stock shades (CMYK)
Socks_Colors_RGB.jsonSock palette in RGB