-
Notifications
You must be signed in to change notification settings - Fork 11
feat: Document translation memory management endpoints #418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
13 changes: 13 additions & 0 deletions
13
api-reference/translation-memory/delete-a-translation-memory.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| --- | ||
| openapi: delete /v3/translation_memories/{translation_memory_id} | ||
| title: "Delete a translation memory" | ||
| description: "Learn how to permanently delete a translation memory and all of its segments." | ||
| --- | ||
|
|
||
| Deletion is permanent and removes every segment in the translation memory. There is no recovery step and no trash to restore from. [Export the translation memory](/api-reference/translation-memory/export-a-translation-memory) first if you need a copy. | ||
|
|
||
| <Warning> | ||
| Translation requests that pass a deleted `translation_memory_id` fail. Update your integration to stop referencing the ID before you delete it, not after. | ||
| </Warning> | ||
|
|
||
| A successful delete returns `204 No Content` with an empty body, so check the status code rather than trying to parse a response. |
74 changes: 74 additions & 0 deletions
74
api-reference/translation-memory/export-a-translation-memory.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| --- | ||
| openapi: post /v3/translation_memories/{translation_memory_id}/export | ||
| title: "Export a translation memory" | ||
| description: "Learn how to export a translation memory as a TMX file, including how DeepL reuses recent exports and when it returns 409." | ||
| --- | ||
|
|
||
| Exporting runs as a background job. This request starts the job and returns a `job_id`; the TMX file is downloaded separately once the job completes. TMX is currently the only export format, so there is no format parameter. | ||
|
|
||
| ## Exporting a translation memory | ||
|
|
||
| <Steps> | ||
| <Step title="Start the export"> | ||
| ```bash | ||
| curl -X POST "https://api.deepl.com/v3/translation_memories/a74d88fb-ed2a-4943-a664-a4512398b994/export" \ | ||
| -H "Authorization: DeepL-Auth-Key <yourAuthKey>" | ||
| ``` | ||
|
|
||
| ```json | ||
| { | ||
| "job_id": "7c2e5a91-3b8d-4f16-8e0a-6d4c2b7f9a13", | ||
| "parameters": { | ||
| "translation_memory_id": "a74d88fb-ed2a-4943-a664-a4512398b994" | ||
| } | ||
| } | ||
| ``` | ||
| </Step> | ||
|
|
||
| <Step title="Poll the job and download the file"> | ||
| Check [the job](/api-reference/translation-memory/retrieve-a-translation-memory-job) until `status` is `completed`, then download the file from `download_url` on the job result. | ||
|
|
||
| ```bash | ||
| curl -X GET "https://api.deepl.com/v3/translation_memories/jobs/7c2e5a91-3b8d-4f16-8e0a-6d4c2b7f9a13" \ | ||
| -H "Authorization: DeepL-Auth-Key <yourAuthKey>" | ||
| ``` | ||
|
|
||
| ```json | ||
| { | ||
| "job_id": "7c2e5a91-3b8d-4f16-8e0a-6d4c2b7f9a13", | ||
| "product": "translation_memory", | ||
| "operation": "export", | ||
| "creation_time": "2026-08-06T15:04:25.223Z", | ||
| "updated_time": "2026-08-06T15:05:02.771Z", | ||
| "parameters": { | ||
| "translation_memory_id": "a74d88fb-ed2a-4943-a664-a4512398b994" | ||
| }, | ||
| "results": [ | ||
| { | ||
| "status": "completed", | ||
| "download_url": "https://assets.deepl.com/download/7c2e5a91-3b8d-4f16-8e0a-6d4c2b7f9a13", | ||
| "expires_at": "2026-08-06T16:05:02.771Z" | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ## Handling 200, 202, and 409 | ||
|
|
||
| The status code tells you whether a new job was started: | ||
|
|
||
| | **Status** | **Meaning** | **What to do** | | ||
| |---|---|---| | ||
| | `202 Accepted` | A new export job was started | Poll `job_id` | | ||
| | `200 OK` | A recent export was still available and was reused | Poll `job_id` | | ||
| | `409 Conflict` | An export of this translation memory is already running | Poll the job you already have; do not retry the export | | ||
|
|
||
| Treat `200` and `202` the same way. Both return a usable `job_id`, and the only difference is whether DeepL did the work again. | ||
|
|
||
| <Warning> | ||
| Do not retry on `409`. Retrying will keep conflicting with the in-progress export. Poll the `job_id` from your earlier request instead, and hold onto that ID so you can recover without a retry loop. | ||
| </Warning> | ||
|
|
||
| `download_url` is short-lived and stops working at `expires_at`. Download the file when the job completes rather than storing the URL for later. If the URL has expired, start a new export. |
102 changes: 102 additions & 0 deletions
102
api-reference/translation-memory/import-a-translation-memory.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| --- | ||
| openapi: post /v3/translation_memories/import | ||
| title: "Import a translation memory" | ||
| description: "Learn how to create a translation memory by declaring a TMX file, uploading it to a signed URL, and polling the import job." | ||
| --- | ||
|
|
||
| This is how you create a translation memory: there is no endpoint that creates an empty one. Importing a TMX file creates the translation memory and fills it in a single job. | ||
|
|
||
| The request body describes the file you intend to upload; it does not carry the file. DeepL returns a signed `upload_url`, you upload the file to that URL, and processing starts automatically once the upload finishes. | ||
|
|
||
| ## Importing a file | ||
|
|
||
| <Steps> | ||
| <Step title="Create the import job"> | ||
| Send the file's name and size in bytes. The response returns the `job_id`, the `upload_url`, and the `expires_at` deadline for the upload. | ||
|
|
||
| ```bash | ||
| curl -X POST "https://api.deepl.com/v3/translation_memories/import" \ | ||
| -H "Authorization: DeepL-Auth-Key <yourAuthKey>" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "source_file": { | ||
| "file_name": "legal.tmx", | ||
| "content_type": "application/xml", | ||
| "content_length": 1024 | ||
| }, | ||
| "parameters": { | ||
| "display_name": "Legal" | ||
| } | ||
| }' | ||
| ``` | ||
|
|
||
| ```json | ||
| { | ||
| "job_id": "0f8b6c1e-4d2a-4c77-9a3e-1b5d8c9e2f40", | ||
| "upload_url": "https://assets.deepl.com/upload/0f8b6c1e-4d2a-4c77-9a3e-1b5d8c9e2f40", | ||
| "expires_at": "2026-08-06T15:34:25.223Z" | ||
| } | ||
| ``` | ||
| </Step> | ||
|
|
||
| <Step title="Upload the TMX file"> | ||
| `PUT` the file to `upload_url` before `expires_at`. The URL is already signed, so this request carries no DeepL credentials. | ||
|
|
||
| ```bash | ||
| curl -X PUT "https://assets.deepl.com/upload/0f8b6c1e-4d2a-4c77-9a3e-1b5d8c9e2f40" \ | ||
| -H "Content-Type: application/xml" \ | ||
| --data-binary @legal.tmx | ||
| ``` | ||
|
|
||
| A successful upload returns no DeepL response body. Processing begins on its own, so there is no call to confirm the upload. | ||
| </Step> | ||
|
|
||
| <Step title="Poll the job"> | ||
| Check [the job](/api-reference/translation-memory/retrieve-a-translation-memory-job) until `status` is `completed` or `failed`. | ||
|
|
||
| ```bash | ||
| curl -X GET "https://api.deepl.com/v3/translation_memories/jobs/0f8b6c1e-4d2a-4c77-9a3e-1b5d8c9e2f40" \ | ||
| -H "Authorization: DeepL-Auth-Key <yourAuthKey>" | ||
| ``` | ||
|
|
||
| On completion, the job result carries the `translation_memory_id` of the new translation memory. | ||
|
|
||
| ```json | ||
| { | ||
| "job_id": "0f8b6c1e-4d2a-4c77-9a3e-1b5d8c9e2f40", | ||
| "product": "translation_memory", | ||
| "operation": "import", | ||
| "creation_time": "2026-08-06T15:04:25.223Z", | ||
| "updated_time": "2026-08-06T15:06:11.418Z", | ||
| "source_file": { | ||
| "content_type": "application/xml", | ||
| "content_length": 1024 | ||
| }, | ||
| "parameters": { | ||
| "display_name": "Legal" | ||
| }, | ||
| "results": [ | ||
| { | ||
| "status": "completed", | ||
| "translation_memory_id": "a74d88fb-ed2a-4943-a664-a4512398b994", | ||
| "skipped_segment_count": 12 | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ## Common mistakes | ||
|
|
||
| `content_length` must be greater than 0 and at most 1 GB. An oversize value is rejected as `400 Bad Request` with a message pointing at `source_file.content_length`. | ||
|
|
||
| `file_name` accepts at most 100 characters and `content_type` at most 127, both rejected as `400 Bad Request` if longer. TMX is the only supported format, so leave `content_type` unset or set it to `application/xml`. | ||
|
|
||
| A `202 Accepted` means the job exists, not that a translation memory does. Until the upload completes and the job reports `completed`, no translation memory has been created and there is no ID to reference. | ||
|
|
||
| If `expires_at` passes before you upload, the signed URL stops working. Create a new import job to get a fresh URL rather than retrying the old one. | ||
|
|
||
| A non-zero `skipped_segment_count` on a completed import is not a failure. Some segments were not stored, for example because they were malformed or duplicated an existing segment, but the rest imported normally. Check the value if you are reconciling segment counts against your source file. | ||
|
|
||
| If your account has reached its translation memory limit, the request returns `456`. Delete a translation memory before importing another. | ||
29 changes: 29 additions & 0 deletions
29
api-reference/translation-memory/list-translation-memory-segments.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| --- | ||
| openapi: get /v3/translation_memories/{translation_memory_id}/segments | ||
| title: "List translation memory segments" | ||
| description: "Learn how to page through the source segments and translations stored in a translation memory using cursor-based pagination." | ||
| --- | ||
|
|
||
| ## Paginating with cursors | ||
|
|
||
| This endpoint pages with an opaque cursor, unlike [List translation memories](/api-reference/translation-memory/list-translation-memories), which uses numbered `page` values. Omit `page_cursor` on the first request, then pass each response's `next_page_cursor` to get the following page. A response with no `next_page_cursor` is the last page. | ||
|
|
||
| ```bash | ||
| # First page | ||
| curl -X GET "https://api.deepl.com/v3/translation_memories/a74d88fb-ed2a-4943-a664-a4512398b994/segments?page_size=50" \ | ||
| -H "Authorization: DeepL-Auth-Key <yourAuthKey>" | ||
|
|
||
| # Next page, using next_page_cursor from the response above | ||
| curl -X GET "https://api.deepl.com/v3/translation_memories/a74d88fb-ed2a-4943-a664-a4512398b994/segments?page_size=50&page_cursor=eyJvZmZzZXQiOjUwfQ" \ | ||
| -H "Authorization: DeepL-Auth-Key <yourAuthKey>" | ||
| ``` | ||
|
|
||
| Treat the cursor as opaque. Its format is not part of the API contract, so do not construct, decode, or increment it yourself. Cursors also encode the filter they were issued under: if you change `filter_text` or `filter_case_sensitive`, start again without a cursor. | ||
|
|
||
| <Warning> | ||
| `segment_count` is the total for the whole translation memory and is not reduced by `filter_text`. A filtered request still reports the full count, so do not use it to decide how many pages of filtered results to expect. Stop paginating when `next_page_cursor` is absent. | ||
| </Warning> | ||
|
|
||
| ## Filtering | ||
|
|
||
| `filter_text` matches against both source text and every target translation, and must be at least 2 characters. Matching is case-insensitive unless you set `filter_case_sensitive=true`. |
32 changes: 32 additions & 0 deletions
32
api-reference/translation-memory/retrieve-a-translation-memory-job.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| --- | ||
| openapi: get /v3/translation_memories/jobs/{job_id} | ||
| title: "Retrieve an import or export job" | ||
| description: "Learn how to poll a translation memory import or export job and read its status values and results." | ||
| --- | ||
|
|
||
| One endpoint covers both [import](/api-reference/translation-memory/import-a-translation-memory) and [export](/api-reference/translation-memory/export-a-translation-memory) jobs. Read `operation` to tell them apart, then read `results[0]` for the status and, once the job finishes, its output. | ||
|
|
||
| `results` always holds exactly one entry. It is an array so that jobs producing multiple outputs can be added later without a breaking change, so index into it rather than assuming a single object. | ||
|
|
||
| ## Status values | ||
|
|
||
| | **Status** | **Applies to** | **Meaning** | | ||
| |---|---|---| | ||
| | `awaiting_input` | Import | The job exists but the file has not been uploaded yet. `status_metadata.required_action` says what is missing. | | ||
| | `processing` | Import, export | The file was received and is being processed. | | ||
| | `completed` | Import, export | The job succeeded. Read `translation_memory_id` (import) or `download_url` (export). | | ||
| | `failed` | Import, export | The job did not finish. `error.message` says why. | | ||
| | `expired` | Import, export | The job is too old to act on. Create a new one. | | ||
|
|
||
| Poll until the status is `completed`, `failed`, or `expired`. The other states are transient and will change on their own. | ||
|
|
||
| ## Which fields to expect | ||
|
|
||
| Fields that do not apply to a job's `operation` are omitted rather than returned as `null`, so check for a field's presence before reading it: | ||
|
|
||
| - **Import jobs** include `source_file` and `parameters.display_name`. On completion, the result adds `translation_memory_id` and may add `skipped_segment_count`. | ||
| - **Export jobs** include `parameters.translation_memory_id`. On completion, the result adds `download_url` and `expires_at`. | ||
|
|
||
| <Note> | ||
| An import that sits at `awaiting_input` means DeepL is still waiting for the file. Upload it to the `upload_url` from the import response; the status will not advance on its own. | ||
| </Note> |
9 changes: 9 additions & 0 deletions
9
api-reference/translation-memory/retrieve-a-translation-memory.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| openapi: get /v3/translation_memories/{translation_memory_id} | ||
| title: "Retrieve a translation memory" | ||
| description: "Learn how to fetch a single translation memory's languages, segment count, and timestamps by its ID." | ||
| --- | ||
|
|
||
| This returns the translation memory's metadata, not its contents. To read the stored segments, use [List translation memory segments](/api-reference/translation-memory/list-translation-memory-segments). | ||
|
|
||
| A translation memory that belongs to another account returns `404 Not Found` rather than `403 Forbidden`, so a 404 does not confirm that the ID is unused. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we document what the max content length is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just added here and also in the openapi specs