diff --git a/api-reference/openapi.json b/api-reference/openapi.json index e186ba34..4c23cc16 100644 --- a/api-reference/openapi.json +++ b/api-reference/openapi.json @@ -830,6 +830,9 @@ "translation_memory_threshold": { "$ref": "#/components/schemas/TranslationMemoryThreshold" }, + "show_translation_memory_matches": { + "$ref": "#/components/schemas/ShowTranslationMemoryMatches" + }, "custom_instructions": { "description": "Specify a list of instructions to customize the translation behavior. Up to 10 custom instructions can be specified, each with a maximum of 300 characters.\n\n**Important:** The target language must be `de`, `en`, `es`, `fr`, `it`, `ja`, `ko`, `zh` or any variants of these languages.", "type": "array", @@ -940,6 +943,9 @@ "translation_memory_threshold": { "$ref": "#/components/schemas/TranslationMemoryThreshold" }, + "show_translation_memory_matches": { + "$ref": "#/components/schemas/ShowTranslationMemoryMatches" + }, "tag_handling": { "$ref": "#/components/schemas/TagHandlingOption" }, @@ -1034,6 +1040,53 @@ "v1" ], "example": "v2" + }, + "customizations": { + "description": "Details about the customizations applied to this text. Only present if the `show_translation_memory_matches` parameter is set to true.", + "type": "object", + "properties": { + "translation_memory_matches": { + "description": "The translation memory segments that were integrated into the translated text, in text order.\nAn empty list means nothing from the translation memory reached the output.\n\nWhether a segment counts as integrated, and where, is determined by a model after\ntranslation. A fuzzy match that was adapted can be reported in several pieces.", + "type": "array", + "items": { + "type": "object", + "properties": { + "translation_memory_id": { + "$ref": "#/components/schemas/TranslationMemoryId" + }, + "segment_id": { + "description": "Identifier of the matched segment inside the translation memory.", + "type": "string", + "example": "8b1d5c2e-3f4a-4b6c-9d7e-0f1a2b3c4d5e" + }, + "match_score": { + "description": "Similarity between the source text and the matched segment, from 50 to 100. 100 means the two are identical.", + "type": "number", + "example": 100 + }, + "text_ranges": { + "description": "Where the segment appears in `text`, as half-open ranges of Unicode code points.\nNot present when `tag_handling` is set, because positions cannot be mapped onto\nthe output with reinserted tags.", + "type": "array", + "items": { + "type": "object", + "properties": { + "start": { + "description": "Position of the first code point of the range.", + "type": "integer", + "example": 0 + }, + "end": { + "description": "Position after the last code point of the range.", + "type": "integer", + "example": 15 + } + } + } + } + } + } + } + } } } } @@ -9418,6 +9471,11 @@ "description": "When true, the response will include the billed_characters parameter, giving the\nnumber of characters from the request that will be counted by DeepL for billing purposes.", "type": "boolean" }, + "ShowTranslationMemoryMatches": { + "description": "When true, each translation includes a `customizations.translation_memory_matches` list with the\ntranslation memory segments that were integrated into the translated text and where they appear.\nRequires a translation memory on the request; without one the request fails with a 400.\n\nAdds a model call after translation, so only set it when you use the result. This parameter is\ncurrently available to selected accounts; if it is not enabled for yours, the request fails with a 400.", + "type": "boolean", + "default": false + }, "SplitSentencesOption": { "description": "Sets whether the translation engine should first split the input into sentences.\n\nPossible values are:\n * 0 - no splitting at all, whole input is treated as one sentence\n * 1 (default when tag_handling is not set to html) - splits on punctuation and on newlines\n * nonewlines (default when tag_handling=html) - splits on punctuation only, ignoring newlines", "type": "string", diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 0887da1d..d5ada302 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -656,6 +656,8 @@ paths: $ref: '#/components/schemas/TranslationMemoryId' translation_memory_threshold: $ref: '#/components/schemas/TranslationMemoryThreshold' + show_translation_memory_matches: + $ref: '#/components/schemas/ShowTranslationMemoryMatches' custom_instructions: description: |- Specify a list of instructions to customize the translation behavior. Up to 10 custom instructions can be specified, each with a maximum of 300 characters. @@ -752,6 +754,8 @@ paths: $ref: '#/components/schemas/TranslationMemoryId' translation_memory_threshold: $ref: '#/components/schemas/TranslationMemoryThreshold' + show_translation_memory_matches: + $ref: '#/components/schemas/ShowTranslationMemoryMatches' tag_handling: $ref: '#/components/schemas/TagHandlingOption' outline_detection: @@ -832,6 +836,50 @@ paths: - v2 - v1 example: v2 + customizations: + description: Details about the customizations applied to this text. + Only present if the `show_translation_memory_matches` parameter is set to true. + type: object + properties: + translation_memory_matches: + description: |- + The translation memory segments that were integrated into the translated text, in text order. + An empty list means nothing from the translation memory reached the output. + + Whether a segment counts as integrated, and where, is determined by a model after + translation. A fuzzy match that was adapted can be reported in several pieces. + type: array + items: + type: object + properties: + translation_memory_id: + $ref: '#/components/schemas/TranslationMemoryId' + segment_id: + description: Identifier of the matched segment inside the translation memory. + type: string + example: 8b1d5c2e-3f4a-4b6c-9d7e-0f1a2b3c4d5e + match_score: + description: Similarity between the source text and the matched segment, from 50 to 100. + 100 means the two are identical. + type: number + example: 100 + text_ranges: + description: |- + Where the segment appears in `text`, as half-open ranges of Unicode code points. + Not present when `tag_handling` is set, because positions cannot be mapped onto + the output with reinserted tags. + type: array + items: + type: object + properties: + start: + description: Position of the first code point of the range. + type: integer + example: 0 + end: + description: Position after the last code point of the range. + type: integer + example: 15 '400': $ref: '#/components/responses/BadRequest' @@ -6857,6 +6905,16 @@ components: When true, the response will include the billed_characters parameter, giving the number of characters from the request that will be counted by DeepL for billing purposes. type: boolean + ShowTranslationMemoryMatches: + description: |- + When true, each translation includes a `customizations.translation_memory_matches` list with the + translation memory segments that were integrated into the translated text and where they appear. + Requires a translation memory on the request; without one the request fails with a 400. + + Adds a model call after translation, so only set it when you use the result. This parameter is + currently available to selected accounts; if it is not enabled for yours, the request fails with a 400. + type: boolean + default: false SplitSentencesOption: description: |- Sets whether the translation engine should first split the input into sentences. diff --git a/docs/customize/using-translation-memories.mdx b/docs/customize/using-translation-memories.mdx index 7c10354f..d699c95a 100644 --- a/docs/customize/using-translation-memories.mdx +++ b/docs/customize/using-translation-memories.mdx @@ -163,6 +163,62 @@ curl -X POST 'https://api.deepl.com/v2/translate' \ With a threshold of `100`, "Halloo Welt!" is no longer an exact match for "Hallo Welt!", so the translation memory segment is not applied. DeepL falls back to its default translation: "Hello world!". +## Step 4: See which segments came from the translation memory + +When you route translations to human review, you may want to skip the segments that came from your translation memory and only review freshly translated ones. Set `show_translation_memory_matches` to `true` to find out which stored segments made it into the output and where. + + +This parameter is currently available to selected accounts. If it is not enabled for your account, the request fails with a 400 error. Contact your DeepL representative to request access. + + +```sh +curl -X POST 'https://api.deepl.com/v2/translate' \ +--header 'Authorization: DeepL-Auth-Key [yourAuthKey]' \ +--header 'Content-Type: application/json' \ +--data '{ + "text": [ + "Hallo Welt! Wie geht es dir?" + ], + "target_lang": "EN", + "translation_memory_id": "a74d88fb-ed2a-4943-a664-a4512398b994", + "show_translation_memory_matches": true +}' +``` + +**Expected output:** + +```json +{ + "translations": [ + { + "detected_source_language": "DE", + "text": "Hello everyone! How are you?", + "customizations": { + "translation_memory_matches": [ + { + "translation_memory_id": "a74d88fb-ed2a-4943-a664-a4512398b994", + "segment_id": "8b1d5c2e-3f4a-4b6c-9d7e-0f1a2b3c4d5e", + "match_score": 100, + "text_ranges": [ + { "start": 0, "end": 15 } + ] + } + ] + } + } + ] +} +``` + +Each entry names the stored segment that was used, its match score, and the `text_ranges` it covers in `text`, counted in Unicode code points. Here, "Hello everyone!" (positions 0 to 15) came from the translation memory, while "How are you?" was freshly translated. An empty `translation_memory_matches` list means nothing from the translation memory reached the output. + +A few things to keep in mind: + +- The list only contains segments that were integrated into the output. A stored segment that was found but not used does not appear. +- Whether a segment counts as integrated, and where, is determined by a model after translation. A fuzzy match that was adapted can be reported in several ranges, with the adapted words in the gaps. +- Setting the parameter adds a processing step to each request, so only use it when you need the result. +- With `tag_handling` set, the entries are returned without `text_ranges`, because positions cannot be mapped onto the output with reinserted tags. + ## What you've accomplished You've learned how to: @@ -170,9 +226,11 @@ You've learned how to: - Retrieve the translation memories on your account - Use a translation memory in a translation request - Control the matching threshold to tune how closely source text must match a stored segment +- Find out which segments of a translation came from the translation memory ## See also - [List translation memories](/api-reference/translation-memory/list-translation-memories) — API reference - [Text translation endpoint](/api-reference/translate/request-translation#body-translation-memory-id) — `translation_memory_id` and `translation_memory_threshold` parameter reference +- [Text translation endpoint](/api-reference/translate/request-translation#body-show-translation-memory-matches) — `show_translation_memory_matches` parameter reference - [Supported languages](/docs/getting-started/supported-languages) — check which languages support translation memories