Average color of a list
Paste a list of hex swatches and get the one color that stands for the whole set: #FF0000, #00FF00 and #0000FF average to #555555. Each channel is a plain mean, so the answer matches a spreadsheet. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Colors
- #FF0000, #00FF00, #0000FF
- Hex
- #555555
- Rgb string
- rgb(85, 85, 85)
- Red
- 85
- Green
- 85
When a brand kit, a chart series, or a design-token file hands you a pile of hex swatches, you often need one colour that stands for the whole set: a folder thumbnail, a palette-average chip, a default fill, or a sanity check that a new token did not pull the group toward a surprise hue. This average-color-of-list calculator takes a list of hex colours and returns the arithmetic mean of their red, green, and blue channels, rounded to whole 0–255 steps, plus a six-digit hex token you can paste into CSS. The path is deterministic: the same list always yields the same hex.
How the RGB mean of a colour list is computed
Send a list of hex colours. Each swatch is expanded to three integer channels in the zero-to-two-hundred-fifty-five range. Three-digit shorthand such as hash f zero zero doubles each nibble, so hash f zero zero and hash FF0000 are the same pure red.
An optional leading hash is stripped before validation; a 0x prefix is rejected so a packed integer is never mistaken for a colour token. After every swatch parses, the solver adds the red values, the green values, and the blue values, then divides each sum by the count of colours. That quotient is the arithmetic mean of that channel.
Each mean is rounded to the nearest integer with the language half-up rule for positive numbers, so one hundred twenty-seven point five becomes one hundred twenty-eight, and the result is clamped to the legal 0–255 band. The three integers become the result hex as six uppercase digits with a leading hash. Linear RGB mean is not a perceptual midpoint in LAB or HSL: a neon yellow and a near-black navy can pull the average toward the brighter parent because channel space is not uniform.
That is the documented contract of this product, and it is the same mean designers already compute in spreadsheets and theme scripts. A single colour is a legal list and returns itself after normalization. Two copies of the same hex still return that hex.
Pure red, pure green, and pure blue together average to a mid grey, because each channel sums to two hundred fifty-five over three samples.
When one color must stand for a whole set
Design systems collapse a brand palette into one chip for a folder, a Figma component thumbnail, or a marketing tile that must represent many tokens at once. Chart libraries pick a default series colour from the set of already-used strokes so a new line does not clash by accident. Continuous-integration jobs hash the returned hex and fail the build when a token change shifts the palette average more than a review allows.
This landing is the dedicated average color of a list tool: it is not color.mix, which blends exactly two hexes at a chosen ratio, and it is not an image dominant-colour extractor that reads pixels from a photograph. Prefer it when the search intent is summarize these swatches, not mix two, not convert formats, and not pull colours from a bitmap.
Keep the list at or below two hundred fifty-six swatches, pin hex and rgb in tests, and you get a reproducible summary colour for tickets, LMS plugins, and edge workers without standing up a colour-management library of your own.
What you can do with it
Brand palette summary chip
Collapse a kit of brand hex tokens into one average swatch for a folder thumbnail, a style-guide header, or a marketing tile that must represent the whole palette.
Chart and theme defaults
Pick a default series or surface colour from the hexes already in use so a new chart line or UI panel sits in the same family without a hand-picked extra token.
FAQ
How do I get the average color of a list of hex colours?
The response hex field is the RGB-channel mean as #RRGGBB.
Is the average computed in RGB, HSL, or LAB?
In RGB. Each channel is the arithmetic mean of the matching channel across the list, then rounded to an integer 0–255. Perceptual spaces are a different product intent.
What happens if one swatch in the list is invalid?
Eight-digit alpha, named CSS colours, and non-hex text are rejected and not billed.
How many colours can I average at once?
From one to two hundred fifty-six hex tokens. A single colour returns itself after normalization.
Why do pure red, green and blue average to grey?
Each channel adds up to 255 across three colors, and 255 divided by three is 85, so the result is #555555. It is a straight channel mean, not a perceptual midpoint, which is why bright parents can pull the average.
Related tools
For developers — API access
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.
API endpoint
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.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/color/average-color \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"colors":["#FF0000","#00FF00","#0000FF"]}'const res = await fetch("https://api.kit.forhosting.com/color/average-color", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"colors": [
"#FF0000",
"#00FF00",
"#0000FF"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/color/average-color",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"colors": [
"#FF0000",
"#00FF00",
"#0000FF"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/color/average-color", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"colors":["#FF0000","#00FF00","#0000FF"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"colors":["#FF0000","#00FF00","#0000FF"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/color/average-color", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"colors": [
"#FF0000",
"#00FF00",
"#0000FF"
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "color.average_color",
"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.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_colors | 256 |
max_color_chars | 16 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Invalid swatches fail with invalid_input and are not billed.
Input contract, validation, and the response shape
A comma, space, semicolon, or pipe separated string is also accepted and split into tokens, which is handy when you paste a palette from a notes file. Example: colors hash FF0000, hash 00FF00, and hash 0000FF yields hex hash 555555 because each channel mean is two hundred fifty-five divided by three, which is eighty-five. Example: black and white yields hash 808080 because two hundred fifty-five over two rounds to one hundred twenty-eight. Use hex when you need one token for a style file; use rgb when a canvas or contrast checker expects separate channels. POST a JSON body with the required field colors, an array of hex strings. Aliases colours, palette, list, hexes, and swatches are accepted when a form or older script uses those names. Each token must be three or six hexadecimal digits with an optional leading hash; eight-digit alpha forms, named CSS colours such as tomato, and rgb parenthesis strings are out of scope and fail with invalid_input. An empty list, a missing field, more than two hundred fifty-six entries, a token longer than sixteen characters, or any invalid hex raises invalid_input naming the index so a client can highlight the bad row. Those failures are not billed. On success the body returns hex, the primary average swatch as six-digit uppercase hash RRGGBB; rgb as an object with integer r, g, and b; rgb_string as a paste-ready rgb parenthesis line; red, green, and blue as the same integers for form labels; count, the number of colours that entered the mean; colors, the normalized input list; method always rgb_mean; and a short English message.
Integration use cases
Palette drift checks in CI
Pin the returned hex in continuous-integration fixtures and fail the build when a token change shifts the RGB mean of the published palette.
Technical questions
What does the average color of a list calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful item; invalid input is not billed.