items list required Comma-separated strings to sort: at most 200 entries, at most 100 characters each and at most 8000 characters in total. Entries are trimmed, empty entries are dropped, and an entry cannot contain a comma.
Sort and compare strings the way a locale actually orders them: German sorts ä with a, Swedish sorts it after z. Every option visibly changes the answer.
Authoritative reference data or standards computation
Returns the input order and the sorted order side by side, plus the collator's resolved options. The sort is stable, so equal-comparing entries keep their input order in both directions.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
items
required
| list | example: b,a,z,ä | Comma-separated strings to sort: at most 200 entries, at most 100 characters each and at most 8000 characters in total. Entries are trimmed, empty entries are dropped, and an entry cannot contain a comma. |
locale | string | default: en allowed: 2 – 64 example: de | Unicode BCP 47 locale identifier whose ordering rules to use. It is canonicalized first; a malformed tag returns 400 instead of falling back to English, and a tag this runtime has no collation data for still answers but reports 'hasCollationData': false plus a warning naming the locale that actually served it. Tags carrying a Unicode '-u-' extension are rejected — use the option parameters. |
sensitivity | enum | default: variant allowed: base | accent | case | variant example: base | ECMA-402 comparison strength. base: a = á = A. accent: a ≠ á, a = A. case: a = á, a ≠ A. variant: everything counts (the default for sorting). |
numeric | boolean | default: false example: true | Compare digit runs as numbers (the '-u-kn' key), so 'item2' sorts before 'item10' instead of after it. |
caseFirst | enum | default: false allowed: false | upper | lower example: upper | Which case wins when only case separates two strings (the '-u-kf' key). 'false' keeps the locale's own default. |
collation | string | allowed: 3 – 32 example: phonebk | Named CLDR collation to request through the '-u-co-' key, e.g. phonebk, pinyin or stroke. Values outside this runtime's Intl.supportedValuesOf('collation') return 400; a value the locale does not tailor is reported as a warning, and a 'search…' tailoring is answered with a warning that its order is not a display order. |
descending | boolean | default: false example: true | Reverse the comparator. Equal-comparing entries still keep their input order. |
items list required Comma-separated strings to sort: at most 200 entries, at most 100 characters each and at most 8000 characters in total. Entries are trimmed, empty entries are dropped, and an entry cannot contain a comma.
locale string Unicode BCP 47 locale identifier whose ordering rules to use. It is canonicalized first; a malformed tag returns 400 instead of falling back to English, and a tag this runtime has no collation data for still answers but reports 'hasCollationData': false plus a warning naming the locale that actually served it. Tags carrying a Unicode '-u-' extension are rejected — use the option parameters.
sensitivity enum ECMA-402 comparison strength. base: a = á = A. accent: a ≠ á, a = A. case: a = á, a ≠ A. variant: everything counts (the default for sorting).
numeric boolean Compare digit runs as numbers (the '-u-kn' key), so 'item2' sorts before 'item10' instead of after it.
caseFirst enum Which case wins when only case separates two strings (the '-u-kf' key). 'false' keeps the locale's own default.
collation string Named CLDR collation to request through the '-u-co-' key, e.g. phonebk, pinyin or stroke. Values outside this runtime's Intl.supportedValuesOf('collation') return 400; a value the locale does not tailor is reported as a warning, and a 'search…' tailoring is answered with a warning that its order is not a display order.
descending boolean Reverse the comparator. Equal-comparing entries still keep their input order.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
fields | list | example: locale,hasCollationData | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: movedCount | Return all fields except these (comma-separated). |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
locale | string | The requested locale in canonical BCP 47 form — what was asked for, before the runtime resolved it. | de |
hasCollationData | boolean | Whether this runtime has collation data for the requested locale (Intl.Collator.supportedLocalesOf). False means the ordering below is the fallback locale named in resolvedLocale, not the one you asked for — check it before trusting a locale-specific result, because ICU builds differ and an edge runtime can lack languages a Node build has. | true |
resolvedLocale | string | The locale Intl.Collator actually used, including any '-u-co-' keyword it kept. | de |
resolvedOptions | object | The collator's complete ECMA-402 resolvedOptions: locale, usage, sensitivity, ignorePunctuation, collation, numeric and caseFirst. Echoed so the answer stays auditable against the serving runtime's ICU/CLDR version. numeric and caseFirst are null on a runtime that does not implement the optional '-u-kn'/'-u-kf' keys. | {"locale":"de","usage":"sort","sensitivity":"variant","ignorePunctuation":false,"collation":"default","numeric":false,"caseFirst":"false"} |
items | string[] | The parsed input list, in the order supplied. | ["b","a","z","ä"] |
sorted | string[] | The same entries in this locale's collation order. | ["a","ä","b","z"] |
movedCount | integer | How many positions hold a different string than the input did; 0 means the input was already in this order. | 4 |
locale string The requested locale in canonical BCP 47 form — what was asked for, before the runtime resolved it.
example: de
hasCollationData boolean Whether this runtime has collation data for the requested locale (Intl.Collator.supportedLocalesOf). False means the ordering below is the fallback locale named in resolvedLocale, not the one you asked for — check it before trusting a locale-specific result, because ICU builds differ and an edge runtime can lack languages a Node build has.
example: true
resolvedLocale string The locale Intl.Collator actually used, including any '-u-co-' keyword it kept.
example: de
resolvedOptions object The collator's complete ECMA-402 resolvedOptions: locale, usage, sensitivity, ignorePunctuation, collation, numeric and caseFirst. Echoed so the answer stays auditable against the serving runtime's ICU/CLDR version. numeric and caseFirst are null on a runtime that does not implement the optional '-u-kn'/'-u-kf' keys.
example: {"locale":"de","usage":"sort","sensitivity":"variant","ignorePunctuation":false,"collation":"default","numeric":false,"caseFirst":"false"}
items string[] The parsed input list, in the order supplied.
example: ["b","a","z","ä"]
sorted string[] The same entries in this locale's collation order.
example: ["a","ä","b","z"]
movedCount integer How many positions hold a different string than the input did; 0 means the input was already in this order.
example: 4
/api/collation/sort?items=b%2Ca%2Cz%2C%C3%A4&locale=de {
"data": {
"locale": "de",
"hasCollationData": true,
"resolvedLocale": "de",
"resolvedOptions": {
"locale": "de",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "false"
},
"items": [
"b",
"a",
"z",
"ä"
],
"sorted": [
"a",
"ä",
"b",
"z"
],
"movedCount": 4
},
"meta": {
"endpoint": "collation",
"route": "/sort",
"params": {
"items": [
"b",
"a",
"z",
"ä"
],
"locale": "de",
"sensitivity": "variant",
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/sort?items=b%2Ca%2Cz%2C%C3%A4&locale=sv {
"data": {
"locale": "sv",
"hasCollationData": true,
"resolvedLocale": "sv",
"resolvedOptions": {
"locale": "sv",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "false"
},
"items": [
"b",
"a",
"z",
"ä"
],
"sorted": [
"a",
"b",
"z",
"ä"
],
"movedCount": 2
},
"meta": {
"endpoint": "collation",
"route": "/sort",
"params": {
"items": [
"b",
"a",
"z",
"ä"
],
"locale": "sv",
"sensitivity": "variant",
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/sort?items=item10%2Citem2%2Citem1&numeric=true {
"data": {
"locale": "en",
"hasCollationData": true,
"resolvedLocale": "en",
"resolvedOptions": {
"locale": "en",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": true,
"caseFirst": "false"
},
"items": [
"item10",
"item2",
"item1"
],
"sorted": [
"item1",
"item2",
"item10"
],
"movedCount": 2
},
"meta": {
"endpoint": "collation",
"route": "/sort",
"params": {
"items": [
"item10",
"item2",
"item1"
],
"locale": "en",
"sensitivity": "variant",
"numeric": true,
"caseFirst": "false",
"descending": false
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/sort?items=a%2CA%2Cb%2CB&caseFirst=upper {
"data": {
"locale": "en",
"hasCollationData": true,
"resolvedLocale": "en",
"resolvedOptions": {
"locale": "en",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "upper"
},
"items": [
"a",
"A",
"b",
"B"
],
"sorted": [
"A",
"a",
"B",
"b"
],
"movedCount": 4
},
"meta": {
"endpoint": "collation",
"route": "/sort",
"params": {
"items": [
"a",
"A",
"b",
"B"
],
"locale": "en",
"sensitivity": "variant",
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/sort?items=Alter%2CApfel%2C%C3%84pfel&locale=de&collation=phonebk {
"data": {
"locale": "de",
"hasCollationData": true,
"resolvedLocale": "de-u-co-phonebk",
"resolvedOptions": {
"locale": "de-u-co-phonebk",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "phonebk",
"numeric": false,
"caseFirst": "false"
},
"items": [
"Alter",
"Apfel",
"Äpfel"
],
"sorted": [
"Äpfel",
"Alter",
"Apfel"
],
"movedCount": 3
},
"meta": {
"endpoint": "collation",
"route": "/sort",
"params": {
"items": [
"Alter",
"Apfel",
"Äpfel"
],
"locale": "de",
"sensitivity": "variant",
"numeric": false,
"caseFirst": "false",
"collation": "phonebk",
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} | Parameter | Type | Default & allowed | Description |
|---|---|---|---|
left
required
| string | allowed: 1 – 200 example: a | First string, compared exactly as sent (leading and trailing spaces included). |
right
required
| string | allowed: 1 – 200 example: A | Second string, compared exactly as sent (leading and trailing spaces included). |
locale | string | default: en allowed: 2 – 64 example: de | Unicode BCP 47 locale identifier whose ordering rules to use. It is canonicalized first; a malformed tag returns 400 instead of falling back to English, and a tag this runtime has no collation data for still answers but reports 'hasCollationData': false plus a warning naming the locale that actually served it. Tags carrying a Unicode '-u-' extension are rejected — use the option parameters. |
sensitivity | enum | default: variant allowed: base | accent | case | variant example: base | ECMA-402 comparison strength. base: a = á = A. accent: a ≠ á, a = A. case: a = á, a ≠ A. variant: everything counts (the default for sorting). |
numeric | boolean | default: false example: true | Compare digit runs as numbers (the '-u-kn' key), so 'item2' sorts before 'item10' instead of after it. |
caseFirst | enum | default: false allowed: false | upper | lower example: upper | Which case wins when only case separates two strings (the '-u-kf' key). 'false' keeps the locale's own default. |
collation | string | allowed: 3 – 32 example: phonebk | Named CLDR collation to request through the '-u-co-' key, e.g. phonebk, pinyin or stroke. Values outside this runtime's Intl.supportedValuesOf('collation') return 400; a value the locale does not tailor is reported as a warning, and a 'search…' tailoring is answered with a warning that its order is not a display order. |
left string required First string, compared exactly as sent (leading and trailing spaces included).
right string required Second string, compared exactly as sent (leading and trailing spaces included).
locale string Unicode BCP 47 locale identifier whose ordering rules to use. It is canonicalized first; a malformed tag returns 400 instead of falling back to English, and a tag this runtime has no collation data for still answers but reports 'hasCollationData': false plus a warning naming the locale that actually served it. Tags carrying a Unicode '-u-' extension are rejected — use the option parameters.
sensitivity enum ECMA-402 comparison strength. base: a = á = A. accent: a ≠ á, a = A. case: a = á, a ≠ A. variant: everything counts (the default for sorting).
numeric boolean Compare digit runs as numbers (the '-u-kn' key), so 'item2' sorts before 'item10' instead of after it.
caseFirst enum Which case wins when only case separates two strings (the '-u-kf' key). 'false' keeps the locale's own default.
collation string Named CLDR collation to request through the '-u-co-' key, e.g. phonebk, pinyin or stroke. Values outside this runtime's Intl.supportedValuesOf('collation') return 400; a value the locale does not tailor is reported as a warning, and a 'search…' tailoring is answered with a warning that its order is not a display order.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
fields | list | example: left,right | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: decidedAt | Return all fields except these (comma-separated). |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
left | string | The left operand as supplied. | a |
right | string | The right operand as supplied. | á |
result | integer (-1 | 0 | 1) | -1 when left sorts first, 0 when the two are equivalent at the requested sensitivity, 1 when right sorts first. | -1 |
relation | string (before | equivalent | after) | The same answer in words: where left falls relative to right. | before |
locale | string | The requested locale in canonical BCP 47 form — what was asked for, before the runtime resolved it. | en |
hasCollationData | boolean | Whether this runtime has collation data for the requested locale (Intl.Collator.supportedLocalesOf). False means the ordering below is the fallback locale named in resolvedLocale, not the one you asked for — check it before trusting a locale-specific result, because ICU builds differ and an edge runtime can lack languages a Node build has. | true |
resolvedLocale | string | The locale Intl.Collator actually used, including any '-u-co-' keyword it kept. | en |
resolvedOptions | object | The collator's complete ECMA-402 resolvedOptions: locale, usage, sensitivity, ignorePunctuation, collation, numeric and caseFirst. Echoed so the answer stays auditable against the serving runtime's ICU/CLDR version. numeric and caseFirst are null on a runtime that does not implement the optional '-u-kn'/'-u-kf' keys. | {"locale":"en","usage":"sort","sensitivity":"variant","ignorePunctuation":false,"collation":"default","numeric":false,"caseFirst":"false"} |
decidedAt | string (base | accent | case | variant | equivalent-at-all-levels) | Coarsest sensitivity at which the strings still differ, found by re-running the comparison at base, accent, case then variant with the other options unchanged. Independent of the requested sensitivity. | accent |
left string The left operand as supplied.
example: a
right string The right operand as supplied.
example: á
result integer (-1 | 0 | 1) -1 when left sorts first, 0 when the two are equivalent at the requested sensitivity, 1 when right sorts first.
example: -1
relation string (before | equivalent | after) The same answer in words: where left falls relative to right.
example: before
locale string The requested locale in canonical BCP 47 form — what was asked for, before the runtime resolved it.
example: en
hasCollationData boolean Whether this runtime has collation data for the requested locale (Intl.Collator.supportedLocalesOf). False means the ordering below is the fallback locale named in resolvedLocale, not the one you asked for — check it before trusting a locale-specific result, because ICU builds differ and an edge runtime can lack languages a Node build has.
example: true
resolvedLocale string The locale Intl.Collator actually used, including any '-u-co-' keyword it kept.
example: en
resolvedOptions object The collator's complete ECMA-402 resolvedOptions: locale, usage, sensitivity, ignorePunctuation, collation, numeric and caseFirst. Echoed so the answer stays auditable against the serving runtime's ICU/CLDR version. numeric and caseFirst are null on a runtime that does not implement the optional '-u-kn'/'-u-kf' keys.
example: {"locale":"en","usage":"sort","sensitivity":"variant","ignorePunctuation":false,"collation":"default","numeric":false,"caseFirst":"false"}
decidedAt string (base | accent | case | variant | equivalent-at-all-levels) Coarsest sensitivity at which the strings still differ, found by re-running the comparison at base, accent, case then variant with the other options unchanged. Independent of the requested sensitivity.
example: accent
/api/collation/compare?left=a&right=%C3%A1 {
"data": {
"left": "a",
"right": "á",
"result": -1,
"relation": "before",
"locale": "en",
"hasCollationData": true,
"resolvedLocale": "en",
"resolvedOptions": {
"locale": "en",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "false"
},
"decidedAt": "accent"
},
"meta": {
"endpoint": "collation",
"route": "/compare",
"params": {
"left": "a",
"right": "á",
"locale": "en",
"sensitivity": "variant",
"numeric": false,
"caseFirst": "false"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/compare?left=a&right=A {
"data": {
"left": "a",
"right": "A",
"result": -1,
"relation": "before",
"locale": "en",
"hasCollationData": true,
"resolvedLocale": "en",
"resolvedOptions": {
"locale": "en",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "false"
},
"decidedAt": "case"
},
"meta": {
"endpoint": "collation",
"route": "/compare",
"params": {
"left": "a",
"right": "A",
"locale": "en",
"sensitivity": "variant",
"numeric": false,
"caseFirst": "false"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/compare?left=%C3%A9&right=e%CC%81 {
"data": {
"left": "é",
"right": "é",
"result": 0,
"relation": "equivalent",
"locale": "en",
"hasCollationData": true,
"resolvedLocale": "en",
"resolvedOptions": {
"locale": "en",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "false"
},
"decidedAt": "equivalent-at-all-levels"
},
"meta": {
"endpoint": "collation",
"route": "/compare",
"params": {
"left": "é",
"right": "é",
"locale": "en",
"sensitivity": "variant",
"numeric": false,
"caseFirst": "false"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/compare?left=%C3%A4&right=z&locale=sv {
"data": {
"left": "ä",
"right": "z",
"result": 1,
"relation": "after",
"locale": "sv",
"hasCollationData": true,
"resolvedLocale": "sv",
"resolvedOptions": {
"locale": "sv",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "false"
},
"decidedAt": "base"
},
"meta": {
"endpoint": "collation",
"route": "/compare",
"params": {
"left": "ä",
"right": "z",
"locale": "sv",
"sensitivity": "variant",
"numeric": false,
"caseFirst": "false"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/compare?left=item2&right=item10&numeric=true {
"data": {
"left": "item2",
"right": "item10",
"result": -1,
"relation": "before",
"locale": "en",
"hasCollationData": true,
"resolvedLocale": "en",
"resolvedOptions": {
"locale": "en",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": true,
"caseFirst": "false"
},
"decidedAt": "base"
},
"meta": {
"endpoint": "collation",
"route": "/compare",
"params": {
"left": "item2",
"right": "item10",
"locale": "en",
"sensitivity": "variant",
"numeric": true,
"caseFirst": "false"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/compare?left=a&right=A&caseFirst=upper {
"data": {
"left": "a",
"right": "A",
"result": 1,
"relation": "after",
"locale": "en",
"hasCollationData": true,
"resolvedLocale": "en",
"resolvedOptions": {
"locale": "en",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "upper"
},
"decidedAt": "case"
},
"meta": {
"endpoint": "collation",
"route": "/compare",
"params": {
"left": "a",
"right": "A",
"locale": "en",
"sensitivity": "variant",
"numeric": false,
"caseFirst": "upper"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/compare?left=%C3%84pfel&right=Alter&locale=de&collation=phonebk {
"data": {
"left": "Äpfel",
"right": "Alter",
"result": -1,
"relation": "before",
"locale": "de",
"hasCollationData": true,
"resolvedLocale": "de-u-co-phonebk",
"resolvedOptions": {
"locale": "de-u-co-phonebk",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "phonebk",
"numeric": false,
"caseFirst": "false"
},
"decidedAt": "base"
},
"meta": {
"endpoint": "collation",
"route": "/compare",
"params": {
"left": "Äpfel",
"right": "Alter",
"locale": "de",
"sensitivity": "variant",
"numeric": false,
"caseFirst": "false",
"collation": "phonebk"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} One row per tag you send, in the order you sent them. ECMA-402 leaves Intl.Collator's locale list implementation-defined, and reduced-ICU builds genuinely lack whole languages, so this asks the serving runtime directly with Intl.Collator.supportedLocalesOf instead of consulting a pinned table. A tag with no data reports resolvedLocale and defaultCollation as null, because what it would fall back to is the runtime's own default locale rather than anything derived from your tag.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
locales
required
| list | example: de,sv,ja,zz | Comma-separated Unicode BCP 47 locale identifiers to check — at most 50. Each is canonicalized first (so 'iw' is checked as 'he'), and a malformed tag or one carrying a '-u-' extension returns 400 naming the offending entry. |
locales list required Comma-separated Unicode BCP 47 locale identifiers to check — at most 50. Each is canonicalized first (so 'iw' is checked as 'he'), and a malformed tag or one carrying a '-u-' extension returns 400 naming the offending entry.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
count | int | default: all matches allowed: 1 – 100 example: 3 | Limit the number of returned records (1–100). Defaults to all matches. |
fields | list | example: requested,locale | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: defaultCollation | Return all fields except these (comma-separated). |
format | enum | default: json allowed: json | ndjson | csv example: csv | Response format: json envelope, ndjson (one record per line) or csv. |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
count int Limit the number of returned records (1–100). Defaults to all matches.
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
format enum Response format: json envelope, ndjson (one record per line) or csv.
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
requested | string | The tag exactly as you sent it (trimmed), so a row maps back to your input list even when canonicalization renames it. | de |
locale | string | The same tag in canonical Unicode BCP 47 form. | de |
hasCollationData | boolean | Whether Intl.Collator.supportedLocalesOf reports collation data for this tag on the runtime answering the request. False means /sort and /compare will answer this tag with the runtime's default ordering and warn about it. | true |
resolvedLocale nullable | string | The locale Intl.Collator resolves this tag to — usually the tag itself, sometimes a parent when the runtime has no data for the exact tag ('en-GB' typically resolves to 'en', while 'fr-CA' keeps its own backwards-accent tailoring). Always the same language as 'locale'. Null when the runtime has no data for the tag. | de |
defaultCollation nullable | string | resolvedOptions().collation with no '-u-co-' keyword: the ordering you get when no collation is requested. Reported verbatim, so a runtime that names a locale's standard ordering after its CLDR tailoring (for example 'pinyin' for 'zh') shows that name rather than 'default'. Null when the runtime has no data for the tag. | default |
requested string The tag exactly as you sent it (trimmed), so a row maps back to your input list even when canonicalization renames it.
example: de
locale string The same tag in canonical Unicode BCP 47 form.
example: de
hasCollationData boolean Whether Intl.Collator.supportedLocalesOf reports collation data for this tag on the runtime answering the request. False means /sort and /compare will answer this tag with the runtime's default ordering and warn about it.
example: true
resolvedLocale string nullable The locale Intl.Collator resolves this tag to — usually the tag itself, sometimes a parent when the runtime has no data for the exact tag ('en-GB' typically resolves to 'en', while 'fr-CA' keeps its own backwards-accent tailoring). Always the same language as 'locale'. Null when the runtime has no data for the tag.
example: de
defaultCollation string nullable resolvedOptions().collation with no '-u-co-' keyword: the ordering you get when no collation is requested. Reported verbatim, so a runtime that names a locale's standard ordering after its CLDR tailoring (for example 'pinyin' for 'zh') shows that name rather than 'default'. Null when the runtime has no data for the tag.
example: default
/api/collation/locales?locales=de%2Csv%2Cja%2Czz {
"data": [
{
"requested": "de",
"locale": "de",
"hasCollationData": true,
"resolvedLocale": "de",
"defaultCollation": "default"
},
{
"requested": "sv",
"locale": "sv",
"hasCollationData": true,
"resolvedLocale": "sv",
"defaultCollation": "default"
},
{
"requested": "ja",
"locale": "ja",
"hasCollationData": true,
"resolvedLocale": "ja",
"defaultCollation": "default"
},
{
"requested": "zz",
"locale": "zz",
"hasCollationData": false,
"resolvedLocale": null,
"defaultCollation": null
}
],
"meta": {
"endpoint": "collation",
"route": "/locales",
"count": 4,
"params": {
"locales": [
"de",
"sv",
"ja",
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/locales?locales=en%2Cde%2Cfr%2Ces%2Cit%2Cnl {
"data": [
{
"requested": "en",
"locale": "en",
"hasCollationData": true,
"resolvedLocale": "en",
"defaultCollation": "default"
},
{
"requested": "de",
"locale": "de",
"hasCollationData": true,
"resolvedLocale": "de",
"defaultCollation": "default"
},
{
"requested": "fr",
"locale": "fr",
"hasCollationData": true,
"resolvedLocale": "fr",
"defaultCollation": "default"
},
{
"requested": "es",
"locale": "es",
"hasCollationData": true,
"resolvedLocale": "es",
"defaultCollation": "default"
},
{
"requested": "it",
"locale": "it",
"hasCollationData": true,
"resolvedLocale": "it",
"defaultCollation": "default"
},
{
"requested": "nl",
"locale": "nl",
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/locales?locales=iw%2Cin%2Ctl {
"data": [
{
"requested": "iw",
"locale": "he",
"hasCollationData": true,
"resolvedLocale": "he",
"defaultCollation": "default"
},
{
"requested": "in",
"locale": "id",
"hasCollationData": true,
"resolvedLocale": "id",
"defaultCollation": "default"
},
{
"requested": "tl",
"locale": "fil",
"hasCollationData": true,
"resolvedLocale": "fil",
"defaultCollation": "default"
}
],
"meta": {
"endpoint": "collation",
"route": "/locales",
"count": 3,
"params": {
"locales": [
"iw",
"in",
"tl"
]
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} The bare route lists every identifier Intl.supportedValuesOf('collation') reports. ECMA-402 leaves that set implementation-defined, so it varies between JavaScript runtimes and ICU versions. Add 'locale' to see which of them that locale actually tailors.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
locale | string | allowed: 2 – 64 example: de | Optional Unicode BCP 47 locale identifier, validated exactly as on the other routes (malformed tags 400; '-u-' extensions rejected). When given, every row reports whether that locale tailors the collation, what the runtime resolved, and the locale's default collation; when omitted those fields are null rather than guessed. |
search | string | allowed: 1 – 32 example: phonebk | Case-insensitive substring filter over the collation identifiers. No match returns an empty list plus a warning listing what this runtime does support. |
locale string Optional Unicode BCP 47 locale identifier, validated exactly as on the other routes (malformed tags 400; '-u-' extensions rejected). When given, every row reports whether that locale tailors the collation, what the runtime resolved, and the locale's default collation; when omitted those fields are null rather than guessed.
search string Case-insensitive substring filter over the collation identifiers. No match returns an empty list plus a warning listing what this runtime does support.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
count | int | default: all matches allowed: 1 – 100 example: 3 | Limit the number of returned records (1–100). Defaults to all matches. |
fields | list | example: collation,supportedForLocale | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: resolvedOptions | Return all fields except these (comma-separated). |
format | enum | default: json allowed: json | ndjson | csv example: csv | Response format: json envelope, ndjson (one record per line) or csv. |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
count int Limit the number of returned records (1–100). Defaults to all matches.
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
format enum Response format: json envelope, ndjson (one record per line) or csv.
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
collation | string | Collation identifier, usable as the 'collation' parameter or a '-u-co-' keyword. | phonebk |
supportedForLocale nullable | boolean | True when the runtime kept the '-u-co-' keyword in the resolved locale, which ECMA-402 does only when that locale's collation list contains this identifier. Null when no locale was given. | true |
resolvedCollation nullable | string | resolvedOptions().collation for this locale plus this collation. To detect a dropped keyword, compare it with localeDefaultCollation — equal values mean the requested collation was not applied; a runtime may report a locale's standard ordering by its CLDR name ('pinyin' for 'zh') rather than as 'default'. Null when no locale was given. | phonebk |
resolvedLocale nullable | string | The locale the runtime resolved for this collation. Null when no locale was given. | de-u-co-phonebk |
localeDefaultCollation nullable | string | resolvedOptions().collation for the locale with no '-u-co-' keyword — the ordering you get when no collation is requested. Runtimes report this either as 'default' or as the underlying CLDR tailoring's name, so it is echoed verbatim rather than normalized. Null when no locale was given. | default |
resolvedOptions nullable | object | The complete ECMA-402 resolvedOptions for this locale plus this collation. Null when no locale was given. | {"locale":"de-u-co-phonebk","usage":"sort","sensitivity":"variant","ignorePunctuation":false,"collation":"phonebk","numeric":false,"caseFirst":"false"} |
collation string Collation identifier, usable as the 'collation' parameter or a '-u-co-' keyword.
example: phonebk
supportedForLocale boolean nullable True when the runtime kept the '-u-co-' keyword in the resolved locale, which ECMA-402 does only when that locale's collation list contains this identifier. Null when no locale was given.
example: true
resolvedCollation string nullable resolvedOptions().collation for this locale plus this collation. To detect a dropped keyword, compare it with localeDefaultCollation — equal values mean the requested collation was not applied; a runtime may report a locale's standard ordering by its CLDR name ('pinyin' for 'zh') rather than as 'default'. Null when no locale was given.
example: phonebk
resolvedLocale string nullable The locale the runtime resolved for this collation. Null when no locale was given.
example: de-u-co-phonebk
localeDefaultCollation string nullable resolvedOptions().collation for the locale with no '-u-co-' keyword — the ordering you get when no collation is requested. Runtimes report this either as 'default' or as the underlying CLDR tailoring's name, so it is echoed verbatim rather than normalized. Null when no locale was given.
example: default
resolvedOptions object nullable The complete ECMA-402 resolvedOptions for this locale plus this collation. Null when no locale was given.
example: {"locale":"de-u-co-phonebk","usage":"sort","sensitivity":"variant","ignorePunctuation":false,"collation":"phonebk","numeric":false,"caseFirst":"false"}
/api/collation/collations?locale=de&search=phonebk {
"data": [
{
"collation": "phonebk",
"supportedForLocale": true,
"resolvedCollation": "phonebk",
"resolvedLocale": "de-u-co-phonebk",
"localeDefaultCollation": "default",
"resolvedOptions": {
"locale": "de-u-co-phonebk",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "phonebk",
"numeric": false,
"caseFirst": "false"
}
}
],
"meta": {
"endpoint": "collation",
"route": "/collations",
"count": 1,
"params": {
"locale": "de",
"search": "phonebk"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/collations?locale=en&search=phonebk {
"data": [
{
"collation": "phonebk",
"supportedForLocale": false,
"resolvedCollation": "default",
"resolvedLocale": "en",
"localeDefaultCollation": "default",
"resolvedOptions": {
"locale": "en",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "default",
"numeric": false,
"caseFirst": "false"
}
}
],
"meta": {
"endpoint": "collation",
"route": "/collations",
"count": 1,
"params": {
"locale": "en",
"search": "phonebk"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/collation/collations?locale=es&search=trad {
"data": [
{
"collation": "trad",
"supportedForLocale": true,
"resolvedCollation": "trad",
"resolvedLocale": "es-u-co-trad",
"localeDefaultCollation": "default",
"resolvedOptions": {
"locale": "es-u-co-trad",
"usage": "sort",
"sensitivity": "variant",
"ignorePunctuation": false,
"collation": "trad",
"numeric": false,
"caseFirst": "false"
}
}
],
"meta": {
"endpoint": "collation",
"route": "/collations",
"count": 1,
"params": {
"locale": "es",
"search": "trad"
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} Sorting and comparison through the runtime's standards-based Intl.Collator — the engine behind String.prototype.localeCompare — so strings order by a language's real alphabet instead of UTF-16 code-unit order. A plain array.sort() puts ä (U+00E4) after z (U+007A) in every language; here German orders ä with a, Swedish orders it after z, and Spanish keeps ñ between n and o.
Every documented option demonstrably changes the output:
sensitivity picks the comparison strength: base (a = á = A), accent (a ≠ á, a = A), case (a = á, a ≠ A) or variant (everything, and the default for sorting).numeric=true turns on numeric collation, so item2 sorts before item10.caseFirst=upper|lower decides which case wins when only case separates two strings.collation requests a named CLDR tailoring through the -u-co- key: phonebk sorts German ä as ae, stroke orders Han characters by stroke count.descending flips the comparator. Ties keep their input order in both directions, because the underlying sort is stable./compare additionally reports decidedAt — the coarsest level at which the two strings still differ. The comparison is re-run at base, then accent, then case, then variant with your other options unchanged, and the first level returning a non-zero result is named. a vs á is decided at accent and a vs A at case. equivalent-at-all-levels means the pair differs at no level: canonically equivalent strings such as NFC é (U+00E9) and NFD é (U+0065 U+0301), but also anything the locale's tailoring folds together at tertiary strength — hiragana あ and katakana ア under the ja tailoring (they are decided at variant in en), or a-b and ab in th, whose locale data defaults ignorePunctuation to true. resolvedOptions echoes that default so you can see it.
/locales answers the question you have to settle before trusting any of the above: does the runtime serving you actually have collation data for your tags?
[[AvailableLocales]] implementation-defined, and a reduced-ICU build — which is what edge runtimes commonly ship — can lack whole languages: Icelandic, Welsh, Irish, Armenian, Georgian, Albanian, Zulu and Mongolian are the kind of tags that come back with no collation data at all on a lean build while a full Node build handles every one of them. On such a build that is a large minority of common language tags, not an exotic edge case. Such a request still answers, and never pretends: hasCollationData is false, resolvedLocale names the locale that really served it, and a warning spells it out. Check your own tags with /locales — it reports what the runtime behind this API has, not a list we pinned. (The sibling plural-rules endpoint returns 400 for an unsupported locale instead. The difference is deliberate: a plural category from the wrong language is indistinguishable from a right one, whereas here the fallback is visible in the payload — and reproducing exactly what localeCompare does on a given runtime is the point of this endpoint.)resolvedOptions back to you, and /collations reports exactly the identifier set this runtime supports rather than a curated list.LC_COLLATE, or an ICU locale), and MySQL by its own utf8mb4_* collations. The same list can come back in a different order from your database than from JavaScript. Diagnosing that mismatch is exactly what this endpoint is for — but it cannot tell you what your database will do.usage option is always sort (never search-usage matching). A runtime's collation list can still contain a search tailoring such as searchjl (CLDR: "Special collation type for Korean initial consonant search"); it is accepted, because it is a real collation this runtime supports, but the response warns that ECMA-402 does not guarantee any particular order for it.unicode_locale_id, which is what Intl.getCanonicalLocales accepts and is narrower than RFC 5646 — root, for instance, is a legal BCP 47 tag and still rejected here.items is a comma-separated list, so an entry cannot itself contain a comma, and each entry is trimmed of surrounding whitespace. Up to 200 entries, up to 100 characters each and up to 8 000 characters in total. /compare keeps left and right exactly as sent, including leading and trailing spaces, and accepts up to 200 characters each.Array.prototype.sort compares UTF-16 code units, and ä is U+00E4 while z is U+007A, so it lands last in every language. /sort?items=b,a,z,ä&locale=de answers a, ä, b, z, and the identical request with locale=sv answers a, b, z, ä.
Set numeric=true, which switches on ECMA-402 numeric collation so digit runs compare as numbers. With the default numeric=false, item10 still sorts before item2.
/compare returns decidedAt. The comparison is re-run at base, accent, case and variant with your other options unchanged, and the first level with a non-zero result is reported. equivalent-at-all-levels means no level separated them — identical or canonically equivalent input, but also any pair the locale's tailoring treats as equal at tertiary strength, such as hiragana vs katakana in ja or punctuation in th, where ignorePunctuation defaults to true.
No. Coverage comes from the serving runtime's ICU build, and reduced-ICU builds — common on edge runtimes — can lack languages such as Icelandic, Welsh or Georgian outright. Those requests still answer, with hasCollationData: false, a warning, and resolvedLocale naming the locale that really served them. /locales?locales=is,cy,ka reports what this deployment actually has.
Not necessarily. Databases sort with their own collations — PostgreSQL with the database or column collation (often the OS LC_COLLATE), MySQL with its utf8mb4_* collations. This endpoint reports what ECMA-402 Intl.Collator does in the serving runtime, which is the JavaScript half of that mismatch.
The request succeeds but never pretends: en has no phonebk tailoring, so the response carries a warning, resolvedOptions.collation reads default, and /collations?locale=en&search=phonebk reports supportedForLocale: false.
Select real cardinal or ordinal plural categories for a BCP 47 locale with runtime ECMA-402/CLDR rules and explicit locale validation.
Canonicalize BCP 47 language tags and run RFC 4647 lookup or basic filtering with bounded, deterministic matching.
Inspect UTF-16 and Unicode scalar values, apply the four standard normalization forms, and segment text into graphemes, words or sentences.
All 183 active ISO 639 two-letter language codes with matching terminology and bibliographic three-letter codes, searchable with exact lookups.
Random English words by part of speech — nouns, verbs, adjectives or adverbs — with working length filters, seedable output and honest 400s when nothing fits.