# DeepL

> Translate text and whole documents with DeepL, keeping layout and formatting intact. Build glossaries so your product names and house terms always come out the same way, and check what the account has left to translate; all of it on DeepL's free API plan.

App · Translation · 16 actions. Web page: https://docs.lodol.com/docs/integrations/deepl

## Actions

### Add or replace a glossary language pair

Set the terms for one language pair inside a glossary. If the glossary does not cover that pair yet it is added; if it does, its terms are replaced.

**Inputs**

- Glossary (`glossary_id`, text, required): The glossary to act on.
- Terms are written in (`source_lang`, text, required): The language the glossary's source terms are written in.
- Terms translate into (`target_lang`, text, required): The language the glossary's target terms are written in.
- Terms (`entries`, text, required): The term pairs, one per line, with the original term and its translation separated by a tab (or a comma if you switch the format below). For example: 'shuttle<tab>Zubringer'.
- Separated by (`entries_format`, text): What separates each term from its translation. One of: `tsv` (One pair per line, separated by a tab (default)), `csv` (One pair per line, separated by a comma). Default: `tsv`.

**Outputs**

- `entry_count` (number): How many terms the pair now holds.
- `glossary_id` (text)
- `source_lang` (text)
- `target_lang` (text)

**Example output**

```json
{
  "entry_count": 24,
  "glossary_id": "def3a26b-3e84-45b3-84ae-0c0aaf3525f7",
  "source_lang": "en",
  "target_lang": "fr"
}
```

### Check a document's translation status

Ask DeepL how far along an uploaded document is: queued, translating with an estimate of the seconds left, done, or failed.

**Inputs**

- Document ID (`document_id`, text, required): The document ID from the 'Upload a document' step.
- Document key (`document_key`, text, required): The document key from the 'Upload a document' step. DeepL encrypts the document with it and cannot look it up again, so chain it from that step.

**Outputs**

- `billed_characters` (number): Characters the document is billed for.
- `document_id` (text): The document's ID.
- `done` (true/false): True once the translation can be downloaded.
- `error_message` (text): Why the translation failed, when it did.
- `seconds_remaining` (number): DeepL's estimate while it is translating.
- `status` (text): 'queued', 'translating', 'done', or 'error'.

**Example output**

```json
{
  "billed_characters": 5120,
  "document_id": "45A9C1BE5B0C4C9EA1D2F3B4C5D6E7F8",
  "done": true,
  "error_message": null,
  "seconds_remaining": null,
  "status": "done"
}
```

### Check usage and limits

Report how much of this DeepL account's allowance is used in the current billing period, and what is left. Use it to warn someone before a workflow runs out of characters.

**Inputs**: None.

**Outputs**

- `api_key_character_count` (number)
- `api_key_character_limit` (number)
- `character_count` (number): Characters translated this period.
- `character_limit` (number): Characters allowed this period.
- `characters_remaining` (number): What is left of the character allowance.
- `document_count` (number)
- `document_limit` (number)
- `end_time` (text): When it ends.
- `products` (list): Per-product usage, on the paid plans.
- `speech_to_speech_minutes_count` (number)
- `speech_to_speech_minutes_limit` (number)
- `speech_to_text_minutes_count` (number)
- `speech_to_text_minutes_limit` (number)
- `start_time` (text): When the current billing period began.
- `team_document_count` (number)
- `team_document_limit` (number)

**Example output**

```json
{
  "api_key_character_count": 184320,
  "api_key_character_limit": 500000,
  "character_count": 184320,
  "character_limit": 500000,
  "characters_remaining": 315680,
  "document_count": 12,
  "document_limit": 100,
  "end_time": "2026-08-31T23:59:59Z",
  "products": [],
  "speech_to_speech_minutes_count": 0,
  "speech_to_speech_minutes_limit": 0,
  "speech_to_text_minutes_count": 0,
  "speech_to_text_minutes_limit": 0,
  "start_time": "2026-08-01T00:00:00Z",
  "team_document_count": null,
  "team_document_limit": null
}
```

### Create a glossary

Create a glossary so DeepL always translates your terms the same way: product names, job titles, anything with a house translation. Give it the pairs for one language pair; more language pairs can be added to the same glossary afterwards.

**Inputs**

- Name (`name`, text, required): What to call the glossary.
- Terms are written in (`source_lang`, text, required): The language the glossary's source terms are written in.
- Terms translate into (`target_lang`, text, required): The language the glossary's target terms are written in.
- Terms (`entries`, text, required): The term pairs, one per line, with the original term and its translation separated by a tab (or a comma if you switch the format below). For example: 'shuttle<tab>Zubringer'.
- Separated by (`entries_format`, text): What separates each term from its translation. One of: `tsv` (One pair per line, separated by a tab (default)), `csv` (One pair per line, separated by a comma). Default: `tsv`.

**Outputs**

- `creation_time` (text): When the glossary was created.
- `dictionaries` (list): One entry per language pair the glossary covers.
- `glossary_id` (text): The glossary's ID.
- `language_pairs` (list): The language pairs, written as 'en → de'.
- `name` (text): The glossary's name.

**Example output**

```json
{
  "creation_time": "2026-07-14T09:12:44.517Z",
  "dictionaries": [
    {
      "entry_count": 24,
      "source_lang": "en",
      "target_lang": "de"
    }
  ],
  "glossary_id": "def3a26b-3e84-45b3-84ae-0c0aaf3525f7",
  "language_pairs": [
    "en \u2192 de"
  ],
  "name": "Product terms"
}
```

### Delete a glossary

Delete a glossary and every language pair in it. Translations that name it start failing, so update those steps first.

**Inputs**

- Glossary (`glossary_id`, text, required): The glossary to act on.

**Outputs**

- `deleted` (true/false)
- `glossary_id` (text): The glossary that was deleted.
- `message` (text)

**Example output**

```json
{
  "deleted": true,
  "glossary_id": "def3a26b-3e84-45b3-84ae-0c0aaf3525f7",
  "message": "Deleted glossary def3a26b-3e84-45b3-84ae-0c0aaf3525f7."
}
```

### Delete a glossary language pair

Remove one language pair from a glossary, leaving its other pairs in place.

**Inputs**

- Glossary (`glossary_id`, text, required): The glossary to act on.
- Terms are written in (`source_lang`, text, required): The 'from' language of the dictionary inside this glossary. The list shows the language pairs the chosen glossary actually has.
- Terms translate into (`target_lang`, text, required): The 'into' language of the dictionary inside this glossary. The list shows the language pairs the chosen glossary actually has.

**Outputs**

- `deleted` (true/false)
- `glossary_id` (text)
- `message` (text)
- `source_lang` (text)
- `target_lang` (text)

**Example output**

```json
{
  "deleted": true,
  "glossary_id": "def3a26b-3e84-45b3-84ae-0c0aaf3525f7",
  "message": "Deleted the en \u2192 fr dictionary.",
  "source_lang": "en",
  "target_lang": "fr"
}
```

### Download a translated document

Download a document DeepL has finished translating and save it, so a later step can email, upload, or store it. The translation is only available for a short time after it is ready.

**Inputs**

- Document ID (`document_id`, text, required): The document ID from the 'Upload a document' step.
- Document key (`document_key`, text, required): The document key from the 'Upload a document' step. DeepL encrypts the document with it and cannot look it up again, so chain it from that step.
- Save the file as (`filename`, text): The name to save the translation under, including its extension (for example 'handbook-DE.docx').

**Outputs**

- `billed_characters` (number): Characters the document was billed for.
- `content_type` (text): Its media type.
- `document_ref` (text): The saved file's reference.
- `documents` (list): The saved file, for a later step that takes documents.
- `filename` (text): The name it was saved under.
- `size_bytes` (number): Its size in bytes.
- `url` (text): A link that serves the file.

**Example output**

```json
{
  "billed_characters": 5120,
  "content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  "document_ref": "doc_9f1c2b7a4e",
  "documents": [
    {
      "content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "document_ref": "doc_9f1c2b7a4e",
      "filename": "handbook-DE.docx",
      "size_bytes": 48213,
      "url": "/actions/core/serve-document/doc_9f1c2b7a4e"
    }
  ],
  "filename": "handbook-DE.docx",
  "size_bytes": 48213,
  "url": "/actions/core/serve-document/doc_9f1c2b7a4e"
}
```

### Get a glossary

Get one glossary's name, language pairs, and how many terms each pair holds.

**Inputs**

- Glossary (`glossary_id`, text, required): The glossary to act on.

**Outputs**

- `creation_time` (text): When the glossary was created.
- `dictionaries` (list): One entry per language pair the glossary covers.
- `glossary_id` (text): The glossary's ID.
- `language_pairs` (list): The language pairs, written as 'en → de'.
- `name` (text): The glossary's name.

**Example output**

```json
{
  "creation_time": "2026-07-14T09:12:44.517Z",
  "dictionaries": [
    {
      "entry_count": 24,
      "source_lang": "en",
      "target_lang": "de"
    }
  ],
  "glossary_id": "def3a26b-3e84-45b3-84ae-0c0aaf3525f7",
  "language_pairs": [
    "en \u2192 de"
  ],
  "name": "Product terms"
}
```

### Get a glossary's terms

Read the term pairs a glossary holds for one language pair, both as a list a later step can loop over and as the original text block.

**Inputs**

- Glossary (`glossary_id`, text, required): The glossary to act on.
- Terms are written in (`source_lang`, text, required): The 'from' language of the dictionary inside this glossary. The list shows the language pairs the chosen glossary actually has.
- Terms translate into (`target_lang`, text, required): The 'into' language of the dictionary inside this glossary. The list shows the language pairs the chosen glossary actually has.

**Outputs**

- `entries` (list): The same terms, split into pairs.
- `entries_format` (text): How the text block separates each pair.
- `entries_text` (text): The terms exactly as DeepL stores them.
- `glossary_id` (text)
- `source_lang` (text)
- `target_lang` (text)

**Example output**

```json
{
  "entries": [
    {
      "source": "shuttle",
      "target": "Zubringer"
    },
    {
      "source": "boarding pass",
      "target": "Bordkarte"
    }
  ],
  "entries_format": "tsv",
  "entries_text": "shuttle\tZubringer\nboarding pass\tBordkarte",
  "glossary_id": "def3a26b-3e84-45b3-84ae-0c0aaf3525f7",
  "source_lang": "en",
  "target_lang": "de"
}
```

### List glossaries

List the glossaries on this DeepL account with the language pairs each one covers, without their terms.

**Inputs**: None.

**Outputs**

- `glossaries` (list): Every glossary on the account.

**Example output**

```json
{
  "glossaries": [
    {
      "creation_time": "2026-07-14T09:12:44.517Z",
      "dictionaries": [
        {
          "entry_count": 24,
          "source_lang": "en",
          "target_lang": "de"
        }
      ],
      "glossary_id": "def3a26b-3e84-45b3-84ae-0c0aaf3525f7",
      "language_pairs": [
        "en \u2192 de"
      ],
      "name": "Product terms"
    }
  ]
}
```

### List language features

List every part of DeepL and the optional features it offers (formality, glossaries, tag handling, tone, and the rest), and whether a feature depends on the source language, the target language, or both.

**Inputs**: None.

**Outputs**

- `resources` (list): Every part of DeepL and its features.

**Example output**

```json
{
  "resources": [
    {
      "features": [
        {
          "name": "formality",
          "needs_source_support": false,
          "needs_target_support": true
        },
        {
          "name": "glossary",
          "needs_source_support": true,
          "needs_target_support": true
        }
      ],
      "name": "translate_text"
    }
  ]
}
```

### List supported languages

List the languages DeepL supports for translating text, for translating documents, or in a glossary, and whether each one can be a source, a target, or both.

**Inputs**

- For (`resource`, text): Which part of DeepL to list the languages for. One of: `translate_text` (Translating text), `translate_document` (Translating documents), `glossary` (Glossaries). Default: `translate_text`.
- Also include (`include`, list): Languages beyond the stable ones. Leave empty for the stable list. One or more of: `beta` (Languages still in beta), `external` (Languages served by an external model).

**Outputs**

- `languages` (list): Every language, with what it supports.
- `resource` (text): The part of DeepL these languages are for.
- `source_languages` (list): The codes usable as a source language.
- `target_languages` (list): The codes usable as a target language.

**Example output**

```json
{
  "languages": [
    {
      "features": [
        "formality",
        "glossary"
      ],
      "lang": "de",
      "name": "German",
      "status": "stable",
      "usable_as_source": true,
      "usable_as_target": true
    },
    {
      "features": [
        "glossary"
      ],
      "lang": "en-US",
      "name": "English (American)",
      "status": "stable",
      "usable_as_source": false,
      "usable_as_target": true
    }
  ],
  "resource": "translate_text",
  "source_languages": [
    "de"
  ],
  "target_languages": [
    "de",
    "en-US"
  ]
}
```

### Rename or edit a glossary

Rename a glossary, replace the terms for one of its language pairs, or both. To change the terms, give the language pair and the full replacement list.

**Inputs**

- Glossary (`glossary_id`, text, required): The glossary to act on.
- New name (`name`, text): A new name for the glossary. Leave blank to keep it.
- Terms are written in (`source_lang`, text): The 'from' language of the pair whose terms you are replacing. Only needed when replacing terms.
- Terms translate into (`target_lang`, text): The 'into' language of the pair whose terms you are replacing. Only needed when replacing terms.
- Terms (`entries`, text): The replacement term pairs, one per line, separated by a tab (or a comma if you switch the format below). They replace that language pair's terms entirely.
- Separated by (`entries_format`, text): What separates each term from its translation. One of: `tsv` (One pair per line, separated by a tab (default)), `csv` (One pair per line, separated by a comma). Default: `tsv`.

**Outputs**

- `creation_time` (text): When the glossary was created.
- `dictionaries` (list): One entry per language pair the glossary covers.
- `glossary_id` (text): The glossary's ID.
- `language_pairs` (list): The language pairs, written as 'en → de'.
- `name` (text): The glossary's name.

**Example output**

```json
{
  "creation_time": "2026-07-14T09:12:44.517Z",
  "dictionaries": [
    {
      "entry_count": 24,
      "source_lang": "en",
      "target_lang": "de"
    }
  ],
  "glossary_id": "def3a26b-3e84-45b3-84ae-0c0aaf3525f7",
  "language_pairs": [
    "en \u2192 de"
  ],
  "name": "Product terms"
}
```

### Translate a document

Translate a whole file and save the result: Word, PowerPoint, Excel, PDF, HTML, text, subtitles, XLIFF, InDesign, XML, JSON, DITA, FrameMaker, and images. Layout and formatting are kept. The step hands the file to DeepL, waits for it, and saves the translation for a later step to email or upload.

**Inputs**

- Document (`file`, text, required): The file to translate: upload one, pick a file from an earlier step, or paste a public file address.
- Translate into (`target_lang`, text, required): The language to translate the document into.
- Translate from (`source_lang`, text): The document's language. Leave blank and DeepL detects it. Set it when you use a glossary.
- Formality (`formality`, text): How formal the translation should sound. Only some languages (such as German, French, and Spanish) have a formality setting; the 'where the language allows it' choices are ignored elsewhere instead of failing. One of: `default` (DeepL decides (default)), `prefer_more` (More formal where the language allows it), `prefer_less` (Less formal where the language allows it), `more` (More formal (fails if unsupported)), `less` (Less formal (fails if unsupported)). Default: `default`.
- Glossaries (`glossary_ids`, list): Glossaries whose terms must be used, up to 5. Each one needs a dictionary for this language pair, and 'Translate from' must be set.
- Save as (`output_format`, text): The format to write the translation in. Leave blank to keep the original's format. One of: `docx` (Word (.docx)), `pptx` (PowerPoint (.pptx)), `xlsx` (Excel (.xlsx)), `pdf`, `html`, `htm` (HTML (.htm)), `txt` (Plain text), `xlf` (XLIFF (.xlf)), `xliff` (XLIFF (.xliff)), `srt` (Subtitles (.srt)), and 8 more.
- Add a 'Translated by DeepL' watermark (`enable_watermark`, true/false): Mark the translation as machine translated. Only applies to Word and PDF output. Default: `false`.
- Save the file as (`output_filename`, text): The name to save the translation under. Leave blank and it takes the original's name with the language added, such as 'handbook-DE.docx'.

**Outputs**

- `billed_characters` (number): Characters billed for the document.
- `content_type` (text): Its media type.
- `document_id` (text): DeepL's ID for the translation job.
- `document_ref` (text): The saved file's reference.
- `documents` (list): The saved file, for a later step that takes documents.
- `filename` (text): The name it was saved under.
- `size_bytes` (number): Its size in bytes.
- `target_language` (text): The language it was translated into.
- `url` (text): A link that serves the file.

**Example output**

```json
{
  "billed_characters": 5120,
  "content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  "document_id": "45A9C1BE5B0C4C9EA1D2F3B4C5D6E7F8",
  "document_ref": "doc_9f1c2b7a4e",
  "documents": [
    {
      "content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "document_ref": "doc_9f1c2b7a4e",
      "filename": "handbook-DE.docx",
      "size_bytes": 48213,
      "url": "/actions/core/serve-document/doc_9f1c2b7a4e"
    }
  ],
  "filename": "handbook-DE.docx",
  "size_bytes": 48213,
  "target_language": "DE",
  "url": "/actions/core/serve-document/doc_9f1c2b7a4e"
}
```

### Translate text

Translate text into another language with DeepL. Point it at a message, a description, or anything an earlier step produced, pick the language, and the translation comes back as text a later step can send on. Glossaries and written instructions can be applied so the wording matches how your team already writes.

**Inputs**

- Text (`text`, text, required): The text to translate. Paste it in, or chain it from an earlier step. A list of texts from an earlier step works too; each one is translated on its own and they come back in the same order.
- Translate into (`target_lang`, text, required): The language to translate into.
- Translate from (`source_lang`, text): The language the text is in. Leave blank and DeepL detects it. Set it when you use a glossary: DeepL needs to know which dictionary to use.
- Context (`context`, text): Surrounding information that helps DeepL choose the right wording (what the text is about, or the sentences around it). It is not translated and is not billed.
- Formality (`formality`, text): How formal the translation should sound. Only some languages (such as German, French, and Spanish) have a formality setting; the 'where the language allows it' choices are ignored elsewhere instead of failing. One of: `default` (DeepL decides (default)), `prefer_more` (More formal where the language allows it), `prefer_less` (Less formal where the language allows it), `more` (More formal (fails if unsupported)), `less` (Less formal (fails if unsupported)). Default: `default`.
- Model (`model_type`, text): Which DeepL model translates: the best-quality one, or the faster one. One of: `quality_optimized` (Best quality), `prefer_quality_optimized` (Best quality where available, else the fast model), `latency_optimized` (Fastest).
- Glossaries (`glossary_ids`, list): Glossaries whose terms must be used, up to 5. Each one needs a dictionary for this language pair, and 'Translate from' must be set.
- Custom instructions (`custom_instructions`, list): Plain-language instructions for this translation, such as 'use a friendly, diplomatic tone'. Up to 10, each 300 characters. Supported when translating into German, English, Spanish, French, Italian, Japanese, Korean, or Chinese.
- Keep the original formatting (`preserve_formatting`, true/false): Leave punctuation and capitalization as they are instead of letting DeepL tidy them up. Default: `false`.
- Sentence splitting (`split_sentences`, text): How the text is broken into sentences before it is translated. Change it for a list or a table cell that should stay in one piece. One of: `1` (Split on punctuation and line breaks (default)), `nonewlines` (Split on punctuation only, keep line breaks), `0` (Treat the whole text as one sentence). Default: `1`.
- Markup in the text (`tag_handling`, text): Set this when the text is HTML or XML so the tags are left intact and only the words inside them are translated. One of: `html`, `xml`.
- Markup handling version (`tag_handling_version`, text): Which version of DeepL's tag handling to use. Only applies with 'Markup in the text' set. One of: `v1` (Original (current default)), `v2` (Improved (released October 2025)).
- Detect the XML structure (`outline_detection`, true/false): Leave on to let DeepL work out an XML document's structure. Turn it off to control the split yourself with the tag lists below. Only applies with 'Markup in the text' set to XML. Default: `true`.
- Tags that split sentences (`splitting_tags`, list): XML tags that always end a sentence, such as 'para'. Only applies with 'Markup in the text' set.
- Tags that never split sentences (`non_splitting_tags`, list): XML tags that never end a sentence, such as an inline 'b'. Only applies with 'Markup in the text' set.
- Tags to leave alone (`ignore_tags`, list): Tags whose contents must not be translated, such as 'code'. Only applies with 'Markup in the text' set.
- Report the billed characters (`show_billed_characters`, true/false): Have DeepL report how many characters this translation is billed for. Default: `false`.
- Usage tag (`reporting_tag`, text): A label for this request on DeepL's usage reports, so a team or customer's translations can be told apart. Up to 100 characters; it does not affect the translation.

**Outputs**

- `billed_characters` (number): Characters billed, when the step asked for them.
- `detected_source_language` (text): The language DeepL read the text as.
- `model_type_used` (text): Which model answered, when one was chosen.
- `target_language` (text): The language translated into.
- `text` (text): The translation. When several texts were sent, this is the first one.
- `texts` (list): Every translation, in the order they were sent.
- `translations` (list): DeepL's own record for each text.

**Example output**

```json
{
  "billed_characters": 20,
  "detected_source_language": "EN",
  "model_type_used": "quality_optimized",
  "target_language": "DE",
  "text": "Willkommen bei Lodol.",
  "texts": [
    "Willkommen bei Lodol."
  ],
  "translations": [
    {
      "detected_source_language": "EN",
      "text": "Willkommen bei Lodol."
    }
  ]
}
```

### Upload a document to translate

Hand a file to DeepL and get back the ID and key that track it, without waiting for the translation. Use this for a long document: a later step checks its status and downloads it. For everything else 'Translate a document' does all three in one step.

**Inputs**

- Document (`file`, text, required): The file to translate: upload one, pick a file from an earlier step, or paste a public file address.
- Translate into (`target_lang`, text, required): The language to translate the document into.
- Translate from (`source_lang`, text): The document's language. Leave blank and DeepL detects it. Set it when you use a glossary.
- Formality (`formality`, text): How formal the translation should sound. Only some languages (such as German, French, and Spanish) have a formality setting; the 'where the language allows it' choices are ignored elsewhere instead of failing. One of: `default` (DeepL decides (default)), `prefer_more` (More formal where the language allows it), `prefer_less` (Less formal where the language allows it), `more` (More formal (fails if unsupported)), `less` (Less formal (fails if unsupported)). Default: `default`.
- Glossaries (`glossary_ids`, list): Glossaries whose terms must be used, up to 5. Each one needs a dictionary for this language pair, and 'Translate from' must be set.
- Save as (`output_format`, text): The format to write the translation in. Leave blank to keep the original's format. One of: `docx` (Word (.docx)), `pptx` (PowerPoint (.pptx)), `xlsx` (Excel (.xlsx)), `pdf`, `html`, `htm` (HTML (.htm)), `txt` (Plain text), `xlf` (XLIFF (.xlf)), `xliff` (XLIFF (.xliff)), `srt` (Subtitles (.srt)), and 8 more.
- Add a 'Translated by DeepL' watermark (`enable_watermark`, true/false): Mark the translation as machine translated. Only applies to Word and PDF output. Default: `false`.

**Outputs**

- `document_id` (text): DeepL's ID for this document.
- `document_key` (text): The key DeepL encrypted the document with. Every later step about this document needs it, and it cannot be looked up again.
- `filename` (text): The name the file was sent under.
- `output_format` (text): The format the translation will come back in.
- `target_language` (text): The language it is being translated into.

**Example output**

```json
{
  "document_id": "45A9C1BE5B0C4C9EA1D2F3B4C5D6E7F8",
  "document_key": "2FDA9B1F1E0C4A5D8B7C6E5F4A3B2C1D0E9F8A7B6C5D4E3F2A1B0C9D8E7F6A5B",
  "filename": "handbook.docx",
  "output_format": "docx",
  "target_language": "DE"
}
```
