Dyes
The full dye database — 125 standard dyes, keyed by stainID. Facewear colors are no longer served as dyes; legacy negative IDs return an explanatory 404.
Every dye in a response is the same Dye Object — every card on this page carries a Fields fold listing its 19 fields (/categories and /consolidation-groups return summaries, not dyes). Two of them are easy to confuse:
stainIDis the canonical key (the game's stain table,1–254);itemIDis the legacy per-dye item.marketItemIDis for market-board lookups only and is never a dye lookup key. Since Patch 7.5, 105 dyes share three consolidated items (52254/52255/52256), so look prices up on Universalis bymarketItemID— never by a dye's legacyitemID— and use/v1/dyes/consolidation-groupsto learn which dyes share which item.
GET /v1/dyes
List all dyes with filtering, sorting, and pagination. Returns 125 entries across ~3 pages at the default perPage of 50.
/v1/dyesList all dyes with filtering, sorting, and pagination.List all dyes with filtering, sorting, and pagination.
Parameters · queryGET /v1/dyes/:id
Look up a single dye. The ID type is inferred by numeric range — see ID auto-detection. A consolidated market item (52254–52256) is rejected with a hint pointing at /v1/dyes/consolidation-groups; a legacy negative Facewear ID answers 404 with the color's new slug, name and hex.
/v1/dyes/:idLook up a single dye; ID type inferred by range.Look up a single dye; ID type inferred by range.
Parameters · pathGET /v1/dyes/stain/:stainId
Explicit stainID lookup — bypasses range-based auto-detection. Use this when you specifically have a stainID and want to be unambiguous.
/v1/dyes/stain/:stainIdLook up a dye by stain table ID (1–254).Look up a dye by stain table ID (1–254).
Parameters · pathGET /v1/dyes/search
Search dyes by name. Case-insensitive substring match; with a non-English locale the localized names are searched and returned. Returns an array (not paginated) of every matching dye.
From core 5.4.0, the localized search (any non-English locale) is also accent-, ß- and width-insensitive (q=schneeweiss&locale=de matches Schneeweißer), so q= may return more rows than before. The default English search is unchanged.
/v1/dyes/searchCase-insensitive substring match on names; localized when locale is set.Case-insensitive substring match on names; localized when locale is set.
Parameters · queryGET /v1/dyes/categories
List all dye categories with their dye counts.
/v1/dyes/categoriesAll dye categories with their counts.All dye categories with their counts.
cURL$ curl https://data.xivdyetools.app/v1/dyes/categoriesJavaScriptconst r = await fetch('https://data.xivdyetools.app/v1/dyes/categories');
const { data } = await r.json();GET /v1/dyes/batch
Look up multiple dyes by ID in a single request. Returns the dyes found and a notFound array for any IDs that didn't resolve.
/v1/dyes/batchMultiple dyes by ID in one request; notFound array for misses.Multiple dyes by ID in one request; notFound array for misses.
Parameters · query{
"success": true,
"data": {
"dyes": [ { "itemID": 5729, "name": "Snow White", ... }, ... ],
"notFound": []
},
"meta": { ... }
}GET /v1/dyes/consolidation-groups
Patch 7.5 consolidation metadata. In Patch 7.5, 105 individual dyes were reorganized into three consolidated dye items (Type-A, Type-B, Type-C). This endpoint exposes which dyes belong to which group and whether consolidation is currently active in the game.
Consolidation is active (since April 2026) — all three consolidated itemIDs (52254, 52255, 52256) are populated, and the marketItemID field on each consolidated dye points to the consolidated item rather than the legacy per-dye itemID. Use this endpoint to discover which legacy itemIDs map to which consolidated parent, e.g. when caching market-board prices.
/v1/dyes/consolidation-groupsPatch 7.5 consolidation groups A / B / C and their members.Patch 7.5 consolidation groups A / B / C and their members.
cURL$ curl https://data.xivdyetools.app/v1/dyes/consolidation-groupsJavaScriptconst r = await fetch('https://data.xivdyetools.app/v1/dyes/consolidation-groups');
const { data } = await r.json();{
"success": true,
"data": {
"consolidationActive": true,
"groups": [
{
"type": "A",
"consolidatedItemID": 52254,
"dyeCount": 85,
"dyes": [
{ "itemID": 5729, "stainID": 1, "name": "Snow White" }
]
},
{ "type": "B", "consolidatedItemID": 52255, "dyeCount": 9, "dyes": [] },
{ "type": "C", "consolidatedItemID": 52256, "dyeCount": 11, "dyes": [] }
],
"unconsolidated": {
"count": 20,
"dyes": []
}
},
"meta": {}
}