Skip to content
xivdyetools.app ↗

Error Reference ​

All /v1 errors use the same envelope. The error field is a stable machine-readable code — safe to switch on in your application code.

json
{
  "success": false,
  "error": "NOT_FOUND",
  "message": "No dye found with ID 999999.",
  "meta": { "requestId": "...", "apiVersion": "v1", "locale": "ja" }
}

meta.locale follows the same rule as a success response's: present only when a non-English ?locale= was in effect for the request (omitted for en). Since locale resolution runs only on /v1/* routes, an error outside that tree — /health, the developer docs site — never carries a locale, whatever ?locale= the request itself included.

Error Codes ​

Client Errors (4xx) ​

CodeHTTPDescription
VALIDATION_ERROR400Invalid parameter value or format
MISSING_PARAMETER400Required parameter not provided
INVALID_HEX400Hex color format invalid
INVALID_MATCHING_METHOD400Unknown color distance algorithm
INVALID_LOCALE400Unsupported locale code
INVALID_STAIN_ID400stainId is not a positive integer
INVALID_COLOR_WHEEL400wheel (or the /v1/wheels/:id path) is not one of the five wheel ids — details.expected lists them
INVALID_HARMONY_TYPE400type is not one of the ten harmony types — details.expected lists them
INVALID_BODY400 / 413POST /v1/chara/resolve body is not a JSON object (400) or exceeds 8 KB (413)
NOT_FOUND404Dye, stain, icon, or route not found — also returned for consolidated market itemIDs (52254–52256) and legacy negative Facewear IDs, each with an explanatory message (an unknown category is not an error; it simply matches no dyes)
RATE_LIMITED429Rate limit exceeded

Server Errors (5xx) ​

CodeHTTPDescription
INTERNAL_ERROR500Unexpected server error
UPSTREAM_UNAVAILABLE503XIVAPI is down, timed out, or re-indexing after a game patch — only on /v1/chara/*, which is the one surface with an upstream. Retry later.

The dye and matching endpoints have no upstream, so they never answer 502 / 503.

Validation Details ​

When validation fails, details includes the offending parameter:

json
{
  "error": "INVALID_HEX",
  "details": {
    "parameter": "hex",
    "received": "#F53",
    "expected": "Hex color string matching /^#?[0-9A-Fa-f]{6}$/"
  }
}

Validation stops at the first failing parameter — a response never reports more than one validation error, so fix them one at a time:

json
{
  "error": "VALIDATION_ERROR",
  "message": "Parameter \"perPage\" must be <= 200.",
  "details": { "parameter": "perPage", "received": 500, "expected": "<= 200" }
}

Hex Color Rules ​

RuleDetail
Format/^#?[0-9A-Fa-f]{6}$/
Missing #Auto-prepended — FF0000 is valid
CaseCase-insensitive
3-digit shorthandNot supported — #F00 returns INVALID_HEX

Numeric Ranges ​

ParameterRangeDefault
page1 – 10001
perPage1 – 20050
q (search)≤ 100 characters—
stainId (path)≥ 1—
minPrice, maxPrice≥ 0—
ids (batch), excludeIds≤ 50 comma-separated integers—
maxDistance≥ 0.01—
limit (within-distance)1 – 125 (the whole dye database)20
iconId (path)1 – 999999, canonical decimal—
stops (wheels)3 – 36072
companions (harmony)0 – 50

Enum Values ​

ParameterValid values
localeen ja de fr ko zh
method (matching)ciede2000 (default) oklab cie76 redmean rgb distinguish — the retired hyab / oklch-weighted are still accepted and silently normalised to ciede2000 (euclidean → rgb); the old kL/kC/kH weights are ignored
sort (dyes)name brightness saturation hue cost
orderasc desc
idType (batch)auto item stain
consolidationTypeA B C
wheel (harmony)rgb (default) ryb munsell oklch-hue oklch-lightness
type (harmony)complementary (default) analogous triadic split-complementary tetradic inverted-tetradic square monochromatic compound shades
strict, preventDuplicates (harmony)true false 1 0

Rate Limited Response ​

A 429 response carries the seconds to wait as a top-level retryAfter field:

json
{
  "success": false,
  "error": "RATE_LIMITED",
  "message": "Rate limit exceeded. 60 requests per minute allowed. Retry after the indicated number of seconds.",
  "retryAfter": 30,
  "meta": { ... }
}

(API keys are not yet available — see Rate Limits — the message anticipates them.)

The Retry-After header is also set on 429 responses. See Rate Limits.

FINAL FANTASY XIV © 2010-2026 SQUARE ENIX CO., LTD. All Rights Reserved.
XIV Dye Tools is a fan-made application and is not affiliated with or endorsed by Square Enix. · Discord ↗