{
  "openapi": "3.1.1",
  "info": {
    "title": "Delta E Color Difference (CIEDE2000) API",
    "version": "1.0.0",
    "summary": "Measure color differences with CIEDE2000, CIE94, CIE76 and OKLab, with a pass/fail tolerance.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://luminacolordifference.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Measure color differences with CIEDE2000, CIE94, CIE76 and OKLab, with a pass/fail tolerance.",
        "description": "Compare a reference color with up to 50 samples written as HEX, CSS names or any CSS color function, including lab(). Each row shows ΔE2000, ΔE94, ΔE76 and the OKLab distance, plus pass or fail against your tolerance, with a CSV report.\n\nMethodology:\n- Parse each color with CSS Color 4 syntax and convert it to CIELAB with the D50 white, as CSS lab() does. lab() inputs therefore keep their exact L, a and b values.\n- ΔE2000 follows CIE 142-2001 as implemented by Sharma, Wu and Dalal (2005), with kL = kC = kH = 1; it reproduces their 34 published test pairs to four decimals. ΔE94 uses graphic-arts weights (kL 1, K1 0.045, K2 0.015) with the reference as the first color. ΔE76 is Euclidean Lab distance.\n- The OKLab column is the Euclidean OKLab distance multiplied by 100, so 2 is the one just-noticeable difference used by CSS gamut mapping.\n- A sample passes when the selected difference is at most the tolerance. Out-of-gamut colors are compared unmapped; their HEX column shows the CSS gamut-mapped display value.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "lumina_color_difference",
        "x-owner-app": "lumina",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LuminaColorDifferenceInput"
              },
              "examples": {
                "example1": {
                  "summary": "Three samples against a teal reference",
                  "value": {
                    "reference": "#164E63",
                    "samples": "#1A5A6F\n#164E64\nlab(30 -12 -20)",
                    "method": "2000",
                    "tolerance": 2
                  }
                },
                "example2": {
                  "summary": "Sharma test pair 1 (expected ΔE2000 2.0425)",
                  "value": {
                    "reference": "lab(50 2.6772 -79.7751)",
                    "samples": "lab(50 0 -82.7485)",
                    "method": "2000",
                    "tolerance": 2
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LuminaColorDifferenceResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "LuminaColorDifferenceInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "reference": {
            "title": "Reference color (CSS color)",
            "type": "string",
            "maxLength": 200,
            "default": "#164E63"
          },
          "samples": {
            "title": "Sample colors (one per line)",
            "type": "string",
            "maxLength": 16384,
            "default": "#1A5A6F\n#164E64\nlab(30 -12 -20)"
          },
          "method": {
            "title": "Tolerance method",
            "type": "string",
            "enum": [
              "2000",
              "94",
              "76",
              "ok"
            ],
            "default": "2000"
          },
          "tolerance": {
            "title": "Pass tolerance (ΔE)",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 2
          }
        },
        "required": []
      },
      "LuminaColorDifferenceResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "method",
              "tolerance",
              "rows",
              "passed",
              "failed"
            ],
            "properties": {
              "method": {
                "type": "string"
              },
              "tolerance": {
                "type": "number"
              },
              "passed": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              },
              "rows": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "reference",
                    "sample",
                    "referenceHex",
                    "sampleHex",
                    "deltaE2000",
                    "deltaE94",
                    "deltaE76",
                    "deltaEOK100",
                    "pass"
                  ],
                  "properties": {
                    "reference": {
                      "type": "string"
                    },
                    "sample": {
                      "type": "string"
                    },
                    "referenceHex": {
                      "type": "string"
                    },
                    "sampleHex": {
                      "type": "string"
                    },
                    "deltaE2000": {
                      "type": "number"
                    },
                    "deltaE94": {
                      "type": "number"
                    },
                    "deltaE76": {
                      "type": "number"
                    },
                    "deltaEOK100": {
                      "type": "number"
                    },
                    "pass": {
                      "type": [
                        "boolean",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}