Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 81 additions & 57 deletions doc/compiled.json
Original file line number Diff line number Diff line change
Expand Up @@ -5413,7 +5413,7 @@
"/icu/skeleton": {
"post": {
"summary": "Build ICU skeletons",
"description": "Returns ICU skeletons for multiple locale codes based on a source content.",
"description": "Generates ICU (International Components for Unicode) message format skeletons for one or more locale codes, given a source ICU string or a translation by code.\n\nUse this endpoint when you need to pre-build the plural-form shells for a given ICU message across multiple locales — for example, to pre-populate untranslated keys before sending them to a translator. The endpoint is synchronous and returns immediately.\n\nThe source content must be a valid ICU message format string. The operation extracts the plural categories required by each requested locale using CLDR (Common Locale Data Repository) plural rules for that locale code and returns an empty skeleton for each category. You must supply exactly one of `content` or `id`.\n\nPitfalls and constraints:\n- If the ICU string is syntactically invalid, the endpoint returns 422 with the parser error in the `error` field. Check the `error` field in the response body and correct the ICU syntax before retrying.\n- `locale_codes` must be valid CLDR locale codes; unknown or unsupported codes are silently skipped.\n- The `legacy` CLDR variant omits the `zero` form even when `zero_form_enabled` is true for locales that have it under CLDR 41. Switch to `cldr_version: cldr_41` to include it.\n- Rate limits apply: requests exceeding the account rate limit return 429. Implement exponential backoff and retry after the interval indicated by the `X-Rate-Limit-Reset` header.\n",
"operationId": "icu/skeleton",
"tags": [
"ICU"
Expand All @@ -5423,13 +5423,70 @@
"$ref": "#/components/parameters/X-PhraseApp-OTP"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"title": "icu/skeleton/parameters",
"properties": {
"content": {
"description": "Source ICU message format string to derive skeletons from. Mutually exclusive with `id`; exactly one of the two must be provided.\n",
"type": "string",
"example": "{number, plural, one {One item} other {# items}}"
},
"id": {
"description": "Code of an existing translation to source the ICU content from. Mutually exclusive with `content`; exactly one of the two must be provided. The token must have the `read` scope to access the translation.\n",
"type": "string",
"example": "abcd1234abcd1234abcd1234abcd1234"
},
"locale_codes": {
"description": "List of CLDR locale codes for which to generate skeletons. The response object contains one entry per requested locale code.\n",
"type": "array",
"items": {
"type": "string"
},
"example": [
"en",
"de"
]
},
"keep_content": {
"description": "When true, preserves existing plural forms from the source string and only adds missing forms for each locale. Defaults to false.\n",
"type": "boolean",
"example": false
},
"zero_form_enabled": {
"description": "When true, includes the `zero` plural form in skeletons for locales that require it under the selected CLDR variant. Defaults to false.\n",
"type": "boolean",
"example": true
},
"cldr_version": {
"description": "CLDR plural-rules variant to use. Accepted values: `legacy` (default) and `cldr_41`. Use `cldr_41` for full CLDR 41 plural category support, including distinct `zero` and `one` forms in locales such as Arabic.\n",
"type": "string",
"enum": [
"legacy",
"cldr_41"
],
"example": "cldr_41"
}
}
}
}
}
},
"responses": {
"200": {
"description": "OK",
"description": "OK — ICU skeletons keyed by locale code.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/icu"
},
"example": {
"en": "{number, plural, one {} other {}}",
"de": "{number, plural, one {} other {}}"
}
}
},
Expand All @@ -5442,9 +5499,6 @@
},
"X-Rate-Limit-Reset": {
"$ref": "#/components/headers/X-Rate-Limit-Reset"
},
"Link": {
"$ref": "#/components/headers/Link"
}
}
},
Expand All @@ -5456,74 +5510,44 @@
},
"403": {
"$ref": "#/components/responses/403",
"description": "Forbidden. Returned when the access token lacks the `read` scope."
"description": "Forbidden. Returned when the access token lacks the `read` scope, or when `id` is provided and the token does not have access to the referenced translation. Ensure the token was created with the `read` scope and that the authenticated user has access to the project containing the translation.\n"
},
"404": {
"$ref": "#/components/responses/404"
},
"422": {
"description": "Unprocessable entity. Returned when the source ICU string is syntactically invalid. The response body contains an `error` field with the parser error message.\n",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "ICU message format parser error description."
}
},
"example": {
"error": "Expected `}` but got `{` at position 42"
}
}
}
}
},
"429": {
"$ref": "#/components/responses/429"
}
},
"x-code-samples": [
{
"lang": "Curl",
"source": "curl \"https://api.phrase.com/v2/icu/skeleton\" \\\n -u USERNAME_OR_ACCESS_TOKEN \\\n -X POST \\\n -d '{\"content\":\"{number, plural, one {One} other {%{n}}}\",\"locale_codes\":[\"en\"],\"zero_form_enabled\": true}' \\\n -H 'Content-Type: application/json'"
"source": "curl \"https://api.phrase.com/v2/icu/skeleton\" \\\n -u USERNAME_OR_ACCESS_TOKEN \\\n -X POST \\\n -H 'Content-Type: application/json' \\\n -d '{\"content\":\"{number, plural, one {One item} other {# items}}\",\"locale_codes\":[\"en\",\"de\"],\"zero_form_enabled\":true,\"cldr_version\":\"cldr_41\"}'"
},
{
"lang": "CLI v2",
"source": "phrase icu skeleton \\\n--data '{\"content\":\"{number, plural, one {One} other {%{n}}}\",\"locale_codes\":[\"en\"],\"zero_form_enabled\": true}' \\\n--access_token <token>"
"source": "phrase icu skeleton \\\n--data '{\"content\":\"{number, plural, one {One item} other {# items}}\",\"locale_codes\":[\"en\",\"de\"],\"zero_form_enabled\":true}' \\\n--access_token <token>"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"title": "icu/skeleton/parameters",
"properties": {
"content": {
"description": "Source content to derive skeletons from. Mutually exclusive with `id`; exactly one of the two must be provided.\n",
"type": "string",
"example": "{number, plural, one {One} other {%{n}}}"
},
"id": {
"description": "Translation code to source content from. Mutually exclusive with `content`; exactly one of the two must be provided.\n",
"type": "string",
"example": "abcd1234abcd1234abcd1234abcd1234"
},
"locale_codes": {
"description": "Locale codes",
"type": "array",
"items": {
"type": "string",
"example": "en"
},
"example": [
"en"
]
},
"keep_content": {
"description": "Keep the content and add missing plural forms for each locale",
"type": "boolean",
"example": null
},
"zero_form_enabled": {
"description": "Indicates whether the zero form should be included or excluded in the returned skeletons",
"type": "boolean",
"example": null
},
"cldr_version": {
"description": "Strings supports two CLDR variants, when it comes to pluralization rules. \\\nYou can choose which one you want to use when constructing the skeletons. Possible values \\\nare `legacy` and `cldr_41`. Default value is `legacy`.",
"type": "string",
"example": "cldr_41"
}
}
}
}
}
},
"x-cli-version": "2.9"
}
},
Expand Down
133 changes: 81 additions & 52 deletions paths/icu/skeleton.yaml
Original file line number Diff line number Diff line change
@@ -1,36 +1,107 @@
---
summary: Build ICU skeletons
description: Returns ICU skeletons for multiple locale codes based on a source content.
description: |
Generates ICU (International Components for Unicode) message format skeletons for one or more locale codes, given a source ICU string or a translation by code.

Use this endpoint when you need to pre-build the plural-form shells for a given ICU message across multiple locales — for example, to pre-populate untranslated keys before sending them to a translator. The endpoint is synchronous and returns immediately.

The source content must be a valid ICU message format string. The operation extracts the plural categories required by each requested locale using CLDR (Common Locale Data Repository) plural rules for that locale code and returns an empty skeleton for each category. You must supply exactly one of `content` or `id`.

Pitfalls and constraints:
- If the ICU string is syntactically invalid, the endpoint returns 422 with the parser error in the `error` field. Check the `error` field in the response body and correct the ICU syntax before retrying.
- `locale_codes` must be valid CLDR locale codes; unknown or unsupported codes are silently skipped.
- The `legacy` CLDR variant omits the `zero` form even when `zero_form_enabled` is true for locales that have it under CLDR 41. Switch to `cldr_version: cldr_41` to include it.
- Rate limits apply: requests exceeding the account rate limit return 429. Implement exponential backoff and retry after the interval indicated by the `X-Rate-Limit-Reset` header.
operationId: icu/skeleton
tags:
- ICU
parameters:
- "$ref": "../../parameters.yaml#/X-PhraseApp-OTP"
requestBody:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm kinde torn when it comes to moving the existing sections around. While it's cleaner to have requestBody here rather than on the bottom, it makes (human) reviewing harder and it results with the same (human centric) reference document at the end.

required: true
content:
application/json:
schema:
type: object
title: icu/skeleton/parameters
properties:
content:
description: |
Source ICU message format string to derive skeletons from. Mutually exclusive with `id`; exactly one of the two must be provided.
type: string
example: "{number, plural, one {One item} other {# items}}"
id:
description: |
Code of an existing translation to source the ICU content from. Mutually exclusive with `content`; exactly one of the two must be provided. The token must have the `read` scope to access the translation.
type: string
example: abcd1234abcd1234abcd1234abcd1234
locale_codes:
description: |
List of CLDR locale codes for which to generate skeletons. The response object contains one entry per requested locale code.
type: array
items:
type: string
example:
- en
- de
keep_content:
description: |
When true, preserves existing plural forms from the source string and only adds missing forms for each locale. Defaults to false.
type: boolean
example: false
zero_form_enabled:
description: |
When true, includes the `zero` plural form in skeletons for locales that require it under the selected CLDR variant. Defaults to false.
type: boolean
example: true
cldr_version:
description: |
CLDR plural-rules variant to use. Accepted values: `legacy` (default) and `cldr_41`. Use `cldr_41` for full CLDR 41 plural category support, including distinct `zero` and `one` forms in locales such as Arabic.
type: string
enum:
- legacy
- cldr_41
example: cldr_41
responses:
'200':
description: OK
description: OK — ICU skeletons keyed by locale code.
content:
application/json:
schema:
"$ref": "../../schemas/icu.yaml#/skeleton"
example:
en: "{number, plural, one {} other {}}"
de: "{number, plural, one {} other {}}"
headers:
X-Rate-Limit-Limit:
"$ref": "../../headers.yaml#/X-Rate-Limit-Limit"
X-Rate-Limit-Remaining:
"$ref": "../../headers.yaml#/X-Rate-Limit-Remaining"
X-Rate-Limit-Reset:
"$ref": "../../headers.yaml#/X-Rate-Limit-Reset"
Link:
"$ref": "../../headers.yaml#/Link"
'400':
"$ref": "../../responses.yaml#/400"
'404':
"$ref": "../../responses.yaml#/404"
'401':
"$ref": "../../responses.yaml#/401"
'403':
"$ref": "../../responses.yaml#/403"
description: Forbidden. Returned when the access token lacks the `read` scope.
description: |
Forbidden. Returned when the access token lacks the `read` scope, or when `id` is provided and the token does not have access to the referenced translation. Ensure the token was created with the `read` scope and that the authenticated user has access to the project containing the translation.
'404':
"$ref": "../../responses.yaml#/404"
'422':
description: |
Unprocessable entity. Returned when the source ICU string is syntactically invalid. The response body contains an `error` field with the parser error message.
content:
application/json:
schema:
type: object
properties:
error:
type: string
description: ICU message format parser error description.
example:
error: "Expected `}` but got `{` at position 42"
'429':
"$ref": "../../responses.yaml#/429"
x-code-samples:
Expand All @@ -39,53 +110,11 @@ x-code-samples:
curl "https://api.phrase.com/v2/icu/skeleton" \
-u USERNAME_OR_ACCESS_TOKEN \
-X POST \
-d '{"content":"{number, plural, one {One} other {%{n}}}","locale_codes":["en"],"zero_form_enabled": true}' \
-H 'Content-Type: application/json'
-H 'Content-Type: application/json' \
-d '{"content":"{number, plural, one {One item} other {# items}}","locale_codes":["en","de"],"zero_form_enabled":true,"cldr_version":"cldr_41"}'
- lang: CLI v2
source: |-
phrase icu skeleton \
--data '{"content":"{number, plural, one {One} other {%{n}}}","locale_codes":["en"],"zero_form_enabled": true}' \
--data '{"content":"{number, plural, one {One item} other {# items}}","locale_codes":["en","de"],"zero_form_enabled":true}' \
--access_token <token>
requestBody:
required: true
content:
application/json:
schema:
type: object
title: icu/skeleton/parameters
properties:
content:
description: |
Source content to derive skeletons from. Mutually exclusive with `id`; exactly one of the two must be provided.
type: string
example: "{number, plural, one {One} other {%{n}}}"
id:
description: |
Translation code to source content from. Mutually exclusive with `content`; exactly one of the two must be provided.
type: string
example: abcd1234abcd1234abcd1234abcd1234
locale_codes:
description: Locale codes
type: array
items:
type: string
example: en
example:
- en
keep_content:
description: Keep the content and add missing plural forms for each locale
type: boolean
example:
zero_form_enabled:
description: Indicates whether the zero form should be included or excluded in the returned skeletons
type: boolean
example:
cldr_version:
description: |-
Strings supports two CLDR variants, when it comes to pluralization rules. \
You can choose which one you want to use when constructing the skeletons. Possible values \
are `legacy` and `cldr_41`. Default value is `legacy`.
type: string
example: cldr_41

x-cli-version: '2.9'
Loading