CP
FOR DEVELOPERS & AI AGENTS

Free Paint Color Search API

Search 29,000+ real paint colors from all 21 major brands — with a plain sentence, a color name, a paint code, or a hex value. One GET request, JSON back, CORS open, no API key. Every result is a real, buyable paint with its SKU, hex, and LRV — never an invented color.

The Endpoint

GET https://compositepaint.com/api/colors/search?q={your query}

q — what you're looking for. All of these work:

  • A sentence: "calm warm sage, not too dark" — undertones, room light, and the room itself included: "greige with no purple undertones for a north bedroom"
  • A color name: "Agreeable Gray" — typos are fine
  • A paint code: "SW 7029", "OC-65", "PPU3-7"
  • A hex value: "#9CA88A" — returns the closest real paints by ΔE

limit — optional, 1–20 results (default 10).

A Real Example

GET https://compositepaint.com/api/colors/search?q=warm+greige+with+no+purple+undertones+for+a+north+bedroom&limit=3
{
  "query": "warm greige with no purple undertones for a north bedroom",
  "lane": "smart",
  "understood": {
    "hue": "neutral",
    "temperature": "warm",
    "avoidUndertone": "violet",
    "light": "north",
    "room": "bedroom",
    "anchor": "#CCC4B6"
  },
  "results": [
    {
      "name": "Creamy Mushroom",
      "brand": "Behr",
      "sku": "PPU5-13",
      "hex": "#CABDAF",
      "lrv": 52,
      "deltaE": 2.9,
      "undertone": "orange",
      "url": "https://compositepaint.com/colors/behr-creamy-mushroom/"
    },
    {
      "name": "Bungalow Beige",
      "brand": "Sherwin-Williams",
      "sku": "SW 7511",
      "hex": "#CDBFB0",
      "lrv": 53,
      "deltaE": 3.0,
      "undertone": "orange",
      "url": "https://compositepaint.com/colors/sherwin-williams-bungalow-beige/"
    },
    {
      "name": "Kilim Beige",
      "brand": "Sherwin-Williams",
      "sku": "SW 6106",
      "hex": "#D7C5AE",
      "lrv": 57,
      "deltaE": 4.7,
      "undertone": "orange",
      "url": "https://compositepaint.com/colors/sherwin-williams-kilim-beige/"
    }
  ]
}

The understood andignored fields keep it honest: you can always show your users exactly how the sentence was read, and which words weren't used.

Response Fields

queryYour query, echoed back after normalization.
lane"instant" (name / code / hex — answered by the deck engine directly) or "smart" (sentence read by AI).
understoodSmart lane only: exactly how the sentence was read — filter values plus an optional anchor hex.
understood.undertonepink | orange | yellow | green | blue | violet — an undertone the sentence asked for ("gray with green undertones"). avoidUndertone is one it ruled out ("no purple undertones").
understood.lightnorth | south | east | west | evening — the room light the sentence named. Colors whose researched reviews warn about that light are filtered out of the results.
understood.roomThe room or surface the sentence named ("bedroom", "kitchen", "front-door", "trim"). Results become the colors actually curated for that room — real picks, not the whole deck re-sorted.
ignoredWords the search could not use yet (style words like "farmhouse", things to match like "oak floors"). Rooms, light, and undertones are understood, not ignored. We show the rest so nothing is silently dropped.
notePresent only when AI parsing was briefly unavailable and keyword matching answered instead.
relaxedtrue when the strict read of the sentence matched nothing and a looser pass produced these — good colors, but not a literal answer to what was asked. Say so before presenting them.
missingBrandA brand the sentence named that our deck does not carry. The search ran without it, so the colors come from other brands — never present them as that brand’s.
results[].deltaEPerceptual distance (ΔE2000) from the anchor color, when the query pointed at one. Lower is closer; under ~2 reads as the same color.
results[].lrvLight Reflectance Value (0–100) — how much light the color bounces back.
results[].undertoneThe color’s undertone lean — taken from its researched review where we have one, otherwise computed from the color itself. Absent when a color is too neutral to call.
results[].urlThe color’s page on CompositePaint, with swatches, similar colors, and room previews.

MCP Server for AI Agents

The same search is available as a remote MCP server, so agents (Claude, and any MCP-capable client) can plug it in directly as a tool:

https://compositepaint.com/api/mcp

One tool: search_colors(arguments: query, optional limit). Same query, same colors — the website search box, the REST endpoint, and the MCP tool share one engine.

How to Connect

Claude (web or desktop): Settings → Connectors → Add custom connector → paste the URL above. No login, no key — it connects instantly.

Claude Code:

claude mcp add --transport http compositepaint https://compositepaint.com/api/mcp

Other MCP clients (Cursor, ChatGPT connectors, and any app that speaks Streamable HTTP): add it as a remote MCP server with the same URL. No authentication is required.

Then just ask your assistant something like "find me a calm warm sage for a north-facing bedroom" — it will search our real color database and answer with actual paints, SKUs, and links.

Fair-Use Limits

The API is free and needs no key. Name, code, and hex queries are answered directly from our color database and are effectively unlimited. Sentence queries use AI to read the sentence, so they share a sitewide daily budget plus per-minute caps; popular sentences are cached and don't count against it.

If the budget is briefly exhausted, sentence queries still work — they fall back to keyword matching and the response carries anote field saying so. Your integration never has to handle a dead search.

If you're building something that needs more headroom, emaildavid@compositepaint.com— we're happy to work something out. We only ask that you keep theurl links back to our color pages when you show results to users.