Colors
Info
The color endpoints provide two things: a statistical overview of all colors present in the collection with weighted distribution data and renderable hex values, and a way to find the objects where a specific color is most dominant. Together they make it possible to build color-based interfaces without guessing what values exist.
Color index
endpoint:
GET https://data.designmuseumgent.be/v2/id/colors
Returns all available base colors and named color tones with weighted statistics across the full collection.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
onDisplay | boolean | — | Set to true to compute statistics over only the objects currently on display in the collection presentation |
minCount | integer | 1 | Minimum number of objects a color must appear on to be listed. Use a higher value to suppress rare tones in a color picker |
GET https://data.designmuseumgent.be/v2/id/colors
GET https://data.designmuseumgent.be/v2/id/colors?onDisplay=true
GET https://data.designmuseumgent.be/v2/id/colors?minCount=10
Response format
| Prefix | Namespace |
|---|---|
crm | http://www.cidoc-crm.org/cidoc-crm/ |
hydra | http://www.w3.org/ns/hydra/core# |
rdfs | http://www.w3.org/2000/01/rdf-schema# |
| Code | Description |
|---|---|
| 200 | Successful request |
| 500 | Server error |
Fields
The response contains two top-level arrays — base_colors and css_colors.
| Field | In | Description | Example |
|---|---|---|---|
value | both | Color name | "black" / "Old rose" |
hex | both | Renderable hex value for this color. On css_colors this is the tone's own value; on base_colors it is the heaviest constituent tone. null if no hex could be computed. | "#7d3d18" |
swatches | base_colors | The constituent named tones that make up this base color, heaviest first | see below |
object_count | both | Number of objects that contain this color | 3241 |
collection_share_pct | both | Percentage of the total collection palette this color represents | 18.4 |
avg_dominance_pct | both | When this color appears, how dominant it typically is on average | 34.2 |
filter | both | Ready-to-use URL to filter the objects collection by this color | ...?color=black |
dominant | both | Ready-to-use URL to get the objects where this color is most dominant | ...dominant?color=black |
Each entry in swatches contains:
| Field | Description |
|---|---|
label | Name of the constituent tone (e.g. "Fuzzy Wuzzy") |
hex | Hex value of that tone |
object_count | Objects containing that tone within this base color |
weight | Relative weight of the tone within the base color — higher means it accounts for more of the collection's use of this color |
These are not CSS keywords
Despite the array name, the values in css_colors are names from the extended Wikipedia/xkcd color lists — Davy's grey, Grullo, Tuscan tan. They are not CSS named colors and cannot be passed to a stylesheet directly. Use the hex field to render them.
Why base colors carry multiple swatches
A base color is a bucket, not a tone. orange spans everything from #5a3f29 to #b79585, so a single averaged color would land on an unrepresentative muddy brown. swatches therefore exposes the constituent named tones with their own hex values — use them to render a base color as a small palette rather than one square.
hex on a base color is provided as a shortcut for clients that need exactly one value, and is simply swatches[0].hex.
How hex values are computed
Each hex is a weighted centroid of every occurrence of that tone across the collection, weighted by how much of each image the color covered. Averaging is done in linear light rather than on the gamma-encoded sRGB values, which avoids the darkening and desaturation that channel-wise hex averaging produces.
Reading the statistics
collection_share_pct answers: "what percentage of the entire collection palette is this color?"
avg_dominance_pct answers: "when this color appears in an object, how much of the object does it typically cover?"
For example: grey might have a high collection_share_pct (it appears in many objects) but a moderate avg_dominance_pct (it's often a secondary color). Pink might have a lower collection_share_pct but a high avg_dominance_pct (when an object is pink, it's very pink).
Available base colors
red orange yellow green blue purple pink brown grey black white
Example response
{
"@id": "https://data.designmuseumgent.be/v2/id/colors",
"@type": "hydra:Collection",
"rdfs:label": "Color index",
"rdfs:comment": "Color distribution across the Design Museum Gent collection with weighted statistics",
"base_colors": [
{
"value": "orange",
"hex": "#9f6c47",
"swatches": [
{ "label": "Brown sugar", "hex": "#9f6c47", "object_count": 412, "weight": 38.62 },
{ "label": "Russet", "hex": "#8c542e", "object_count": 298, "weight": 27.14 },
{ "label": "Café noir", "hex": "#5a3f29", "object_count": 211, "weight": 19.08 },
{ "label": "Grullo", "hex": "#b79585", "object_count": 167, "weight": 12.44 }
],
"object_count": 894,
"collection_share_pct": 8.7,
"avg_dominance_pct": 29.4,
"filter": "https://data.designmuseumgent.be/v2/id/objects?color=orange",
"dominant": "https://data.designmuseumgent.be/v2/id/colors/dominant?color=orange"
},
{
"value": "grey",
"hex": "#8b8b8b",
"swatches": [
{ "label": "Davy's grey", "hex": "#585352", "object_count": 989, "weight": 44.31 },
{ "label": "Spanish gray", "hex": "#9a9a99", "object_count": 904, "weight": 31.07 }
],
"object_count": 3241,
"collection_share_pct": 22.4,
"avg_dominance_pct": 41.3,
"filter": "https://data.designmuseumgent.be/v2/id/objects?color=grey",
"dominant": "https://data.designmuseumgent.be/v2/id/colors/dominant?color=grey"
}
],
"css_colors": [
{
"value": "Davy's grey",
"hex": "#585352",
"object_count": 892,
"collection_share_pct": 4.12,
"avg_dominance_pct": 18.6,
"filter": "https://data.designmuseumgent.be/v2/id/objects?cssColor=Davy%27s%20grey",
"dominant": "https://data.designmuseumgent.be/v2/id/colors/dominant?cssColor=Davy%27s%20grey"
},
{
"value": "Old rose",
"hex": "#c08081",
"object_count": 312,
"collection_share_pct": 0.94,
"avg_dominance_pct": 22.1,
"filter": "https://data.designmuseumgent.be/v2/id/objects?cssColor=Old%20rose",
"dominant": "https://data.designmuseumgent.be/v2/id/colors/dominant?cssColor=Old%20rose"
}
]
}
Dominant objects
endpoint:
GET https://data.designmuseumgent.be/v2/id/colors/dominant
Returns the objects where a specific color is most dominant — sorted by the percentage of the object covered by that color. Works for both base colors and named tones.
Each result includes direct links to validated IIIF image URIs together with their rights statement and attribution, so clients can render images without having to dereference the IIIF manifest first.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
color | string | — | Base color to rank by. Use values from base_colors in the color index. |
cssColor | string | — | Named tone to rank by. Use values from css_colors in the color index. |
limit | integer | 20 | Number of results to return (max 100) |
Warning
Provide either ?color= or ?cssColor= — not both. Returns 400 Bad Request if neither is provided.
Examples:
GET https://data.designmuseumgent.be/v2/id/colors/dominant?color=black
GET https://data.designmuseumgent.be/v2/id/colors/dominant?color=pink&limit=50
GET https://data.designmuseumgent.be/v2/id/colors/dominant?cssColor=Old rose
GET https://data.designmuseumgent.be/v2/id/colors/dominant?cssColor=English lavender&limit=10
Response fields
| Field | Description |
|---|---|
@id | URI of the object |
@type | Always crm:E22_Human-Made_Object |
rdfs:label | Dutch title of the object |
dominance_pct | Percentage of the object covered by this color |
crm:P138i_has_representation | Array of crm:E38_Image blocks — every validated image for the object, in canvas order. Omitted if the object has no validated images. |
image | Convenience field: the first crm:E38_Image from the array above, repeated for clients that only need a single thumbnail. Not a CIDOC property — purely a developer shortcut. Omitted when the array is empty. |
crm:P129i_is_subject_of | IIIF manifest link, typed as crm:E73_Information_Object. Omitted if not available. |
Image fields
Each crm:E38_Image is modeled in CIDOC-CRM and contains:
| Field | Description |
|---|---|
@id | Full-resolution IIIF image URI |
@type | Always crm:E38_Image |
thumbnail | 400px-wide IIIF derivative of the same image — convenient for grid views |
crm:P3_has_note | Attribution string (photographer, rights holder, source) |
crm:P104_is_subject_to | Rights statement, typed as crm:E30_Right. The @id is the canonical rights URI (e.g. a rightsstatements.org or Creative Commons URI). |
Why both crm:P138i_has_representation and image?
crm:P138i_has_representation is the canonical CIDOC property carrying all images in canvas order. It is always an array, even when there is only one image — that consistency is what makes it usable as a stable contract.
image is a non-CIDOC convenience key carrying just the first image, repeated. It exists so client code can write obj.image.thumbnail instead of iterating an array when all they need is a single picture. Think of it the same way Linked Art uses _label alongside rdfs:label.
If you are a JSON-LD consumer doing proper triple processing, ignore image and only read crm:P138i_has_representation.
Image validation
Image URIs returned by this endpoint have been validated against the IIIF image server with a HEAD request — only URIs returning a 2xx/3xx response are included. Forbidden (403) and missing (404) images are pruned from the response. This means the image fields contain working links by construction; you don't need defensive 403 handling on the client.
If every image of an object failed validation, the object will still appear in results (the manifest reference is preserved) but crm:P138i_has_representation and image will be omitted.
Example response
{
"@context": {
"crm": "http://www.cidoc-crm.org/cidoc-crm/",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"hydra": "http://www.w3.org/ns/hydra/core#"
},
"@id": "https://data.designmuseumgent.be/v2/id/colors/dominant?color=black&limit=20",
"@type": "hydra:Collection",
"rdfs:label": "Objects most dominant in black",
"hydra:totalItems": 20,
"hydra:member": [
{
"@id": "https://data.designmuseumgent.be/v2/id/object/1987-1105",
"@type": "crm:E22_Human-Made_Object",
"rdfs:label": "Beeldje van een vis in opaalglas",
"dominance_pct": 94.3,
"crm:P138i_has_representation": [
{
"@id": "https://api.collectie.gent/iiif/image/iiif/2/faa08ed8c1f74e26c424cd738a0b5297-1987-1105.jpg/full/full/0/default.jpg",
"@type": "crm:E38_Image",
"thumbnail": "https://api.collectie.gent/iiif/image/iiif/2/faa08ed8c1f74e26c424cd738a0b5297-1987-1105.jpg/full/400,/0/default.jpg",
"crm:P3_has_note": "photographer: Foto Design Museum Gent, source: Design Museum Gent",
"crm:P104_is_subject_to": {
"@id": "http://creativecommons.org/publicdomain/zero/1.0/",
"@type": "crm:E30_Right"
}
},
{
"@id": "https://api.collectie.gent/iiif/image/iiif/2/55421ea9d625d9edf4e89064e2b00ba7-1987-1105.jpg/full/full/0/default.jpg",
"@type": "crm:E38_Image",
"thumbnail": "https://api.collectie.gent/iiif/image/iiif/2/55421ea9d625d9edf4e89064e2b00ba7-1987-1105.jpg/full/400,/0/default.jpg",
"crm:P3_has_note": "rightsholder: photographer Foto Design Museum Gent, source: Design Museum Gent",
"crm:P104_is_subject_to": {
"@id": "http://creativecommons.org/publicdomain/zero/1.0/",
"@type": "crm:E30_Right"
}
}
],
"image": {
"@id": "https://api.collectie.gent/iiif/image/iiif/2/faa08ed8c1f74e26c424cd738a0b5297-1987-1105.jpg/full/full/0/default.jpg",
"@type": "crm:E38_Image",
"thumbnail": "https://api.collectie.gent/iiif/image/iiif/2/faa08ed8c1f74e26c424cd738a0b5297-1987-1105.jpg/full/400,/0/default.jpg",
"crm:P3_has_note": "photographer: Foto Design Museum Gent, source: Design Museum Gent",
"crm:P104_is_subject_to": {
"@id": "http://creativecommons.org/publicdomain/zero/1.0/",
"@type": "crm:E30_Right"
}
},
"crm:P129i_is_subject_of": {
"@id": "https://api.collectie.gent/iiif/presentation/v2/manifest/dmg:1987-1105",
"@type": "crm:E73_Information_Object"
}
}
]
}
Building a color picker
Use the color index and dominant endpoint together to build a color picker UI:
// 1. fetch the color index — minCount hides one-off tones from the picker
const index = await fetch('https://data.designmuseumgent.be/v2/id/colors?minCount=5')
.then(r => r.json())
// 2. render each base color as a real swatch strip using its constituent tones
index.base_colors.forEach(c => {
renderSwatchGroup({
name: c.value,
primary: c.hex, // single square, if that's all you need
palette: c.swatches.map(s => s.hex), // the honest multi-tone version
weight: c.collection_share_pct, // visual weight indicator
})
})
// 3. named tones carry one hex each and can be rendered directly
index.css_colors.forEach(c => {
if (!c.hex) return // no computable hex — skip rather than guess
renderChip({ label: c.value, swatch: c.hex, count: c.object_count })
})
// 4. when a color is selected, fetch the most dominant objects (now with images!)
const selected = 'pink'
const url = index.base_colors.find(c => c.value === selected).dominant
const dominantObjects = await fetch(url).then(r => r.json())
// 5. render directly using the convenience `image` field — no manifest round-trip needed
dominantObjects['hydra:member'].forEach(obj => {
if (!obj.image) return // some objects may have no validated images
renderCard({
title: obj['rdfs:label'],
thumbnail: obj.image.thumbnail,
full: obj.image['@id'],
rights: obj.image['crm:P104_is_subject_to']['@id'],
credit: obj.image['crm:P3_has_note'],
})
})
// 6. or use the full array for an object-detail page that shows all views
const detailObject = dominantObjects['hydra:member'][0]
const allImages = detailObject['crm:P138i_has_representation'] ?? []
allImages.forEach((img, i) => renderViewpoint(i, img.thumbnail))