Call it with one GET request
curl https://aisenseapi.com/services/v1/random_color{"random_color":"#e378dc"}No parameters, no request body, no headers to set. Every call is an independent draw, so a fresh value comes back each time. Three consecutive calls returned #e378dc, then #6084e6, then #fa4137. Nothing is cached and nothing is sequential.
The response is a JSON object with a single key, so a one-line parse gets you the string. The base URL is https://aisenseapi.com/services/v1, and it needs no key and no account. The rest of the collection sits on the free public REST APIs index.
Response fields
| Field | Type | Description |
|---|---|---|
| random_color | string | A hex color in the form #rrggbb: a leading hash followed by exactly six lowercase hexadecimal digits. Total length is always 7 characters. |
Only one field comes back. Its length never varies: one hash plus six hexadecimal digits, seven characters in total. That fixed width is worth relying on. It lets you size a database column, validate with a single regular expression, and slice the channels by position without reaching for a parser.
What the free random color API endpoint guarantees
- Six digits, never three
Some generators shorten
#ffcc00to its equivalent three-digit form#fc0. That shortcut breaks naive string handling. Slicing characters 1 to 3 for the red channel, comparing two values for equality, or storing colors in a fixed-width column all go wrong the moment a short form appears. This endpoint never emits one. Every response carries the full six-digit triplet, sovalue.slice(1, 3),value.slice(3, 5)andvalue.slice(5, 7)are always the red, green and blue bytes. - Lowercase, and always hashed
Digits a through f come back lowercase, and the hash is always present. Use the string as a dictionary key or compare two values with a plain equality check. There is no case to normalize first and no prefix to add.
- Uniform across the 24-bit space
Each of the 16777216 possible colors is equally likely. That is genuine randomness rather than a curated palette. Results land anywhere: near-black, near-white, muddy low-saturation greys and eye-watering saturated primaries are all on the table.
Filtering by luminance when contrast matters
Uniform means unfiltered. The free random color API endpoint will not steer away from the extremes on your behalf, and over enough calls it will hand you white on white. Plan for that before you paint text on top of a generated background.
Filtering by luminance is the usual fix. Parse the three bytes, convert each to a 0 to 1 fraction, apply the sRGB transfer function, then weight the channels roughly 0.2126 red, 0.7152 green and 0.0722 blue. Reject anything above or below your threshold and draw again. A dozen lines of code buy you a guaranteed contrast floor.
Choosing from a small sample works too. Request three or four colors, then keep the one furthest from your background. Both approaches preserve the property that matters: the color itself was still picked without bias. Dark mode and light mode need different thresholds, so set them per theme rather than once.
Consecutive calls are independent draws. Two requests can return the same color, or two colors close enough that nobody can tell them apart. If you are coloring a set of items that must stay visually distinct, deduplicate and measure the distance between values yourself.
Reading the value in your code
Parsing takes one line in most languages. In JavaScript, parseInt(value.slice(1), 16) gives the full 24-bit integer, and shifting by 16, 8 and 0 with a 0xff mask pulls out the channels. In Python, int(value[1:], 16) does the same job. Because the width never changes, neither branch needs a guard for the short form.
Validation is equally short. The pattern ^#[0-9a-f]{6}$ matches every response the endpoint produces and rejects anything mangled in transit. Run it at the boundary if the value crosses a queue or a template layer before it reaches a stylesheet.
Building a palette you can live with
A palette needs more than randomness. Pick a minimum distance in a perceptually even space such as CIELAB, then reject any candidate that lands too close to a color you already hold. Twenty draws usually yield a comfortable set of eight.
Cache what you keep. Colors assigned to a user, a chart series or a log source should be stored once and reused, not refetched on every page load. That keeps rendering deterministic between sessions and keeps your request count low.
Colors rarely travel alone. Pair a fresh tint with a stable identifier from the UUID API endpoint, bound a numeric jitter with the random number API endpoint, or hand a seeded account a starting secret from the password API endpoint. The random generator APIs hub lists the whole set.
Where a random color earns its place
Placeholder avatars
Give every new account a background tint before a profile picture is uploaded.
Chart series colors
Fill a plot config when the number of series is not known ahead of time.
Design mockups
Seed a wireframe or component gallery with real color values instead of grey boxes.
Log stream tinting
Give each agent, worker or log source its own shade so lines separate at a glance.
Visual test data
Feed theme pickers, snapshot tests and CSS validators without hardcoding a list.
Privacy, rate limits and fair use
The free random color API endpoint accepts no input, so there is nothing of yours to log beyond the request itself. No key, no account, no sign-up form.
The service-wide limit is 5000 requests per IP per 24 hours. That is generous for interactive work, but worth a thought before you color thousands of table rows. Fetch a handful of seeds and vary them locally, or batch the work across a longer window.