Version: 1.0.0 Last Updated: February 17, 2026
Complete reference for all DeepL CLI commands, options, and configuration.
Options that work with all commands:
--version, -V Show version number
--help Show help message
--quiet, -q Suppress all non-essential output (errors and results only)
--verbose, -v Show extra information (source language, timing, cache status)
--config, -c FILE Use alternate configuration file
--no-input Disable all interactive prompts (abort instead of prompting)Examples:
# Show version
deepl --version
# Get help
deepl --help
deepl translate --help
# Quiet mode - suppress informational messages, keep errors and results
deepl --quiet translate "Hello" --to es
# Output: Hola (no "Translation (ES):" label)
deepl -q cache stats
# Shows cache statistics without decorative output
# Quiet mode with batch operations (no spinners or progress indicators)
deepl --quiet translate docs/ --to es --output docs-es/
# Shows final statistics only, no progress updates
# Use custom config file
deepl --config ~/.deepl-work.json translate "Hello" --to es
# Use custom config directory (via environment variable)
export DEEPL_CONFIG_DIR=/path/to/config
deepl translate "Hello" --to es
# Disable cache
deepl cache disable
deepl translate "Hello" --to es
deepl cache enableQuiet Mode Behavior:
- ✅ Always shown: Errors, warnings about critical issues, essential output (translation results, JSON data, command output)
- ❌ Suppressed: Informational messages, success confirmations, progress spinners, status updates
- 🎯 Use cases: CI/CD pipelines, scripting, parsing output, quiet automation
Non-Interactive Mode (--no-input):
# Abort instead of prompting for confirmation
deepl --no-input cache clear
# Output: Aborted.
# Combine with --yes to skip prompts and proceed
deepl --no-input cache clear --yes
# Interactive-only commands error with exit code 6
deepl --no-input init
deepl --no-input write "text" --interactive- Commands that require confirmation (e.g.,
cache clear) abort with "Aborted." instead of prompting --yestakes precedence over--no-input— the combination proceeds without prompting- Interactive-only commands (
init,write --interactive) exit with code 6 (InvalidInput) - Use cases: CI/CD pipelines, scripts, automation where a forgotten prompt would hang
Example comparison:
# Normal mode
$ deepl cache enable
✓ Cache enabled
# Quiet mode
$ deepl --quiet cache enable
(no output - command succeeded silently)
# Normal mode with errors
$ deepl translate "Hello" --to invalid
Error: Invalid target language: invalid
# Quiet mode with errors (errors always shown)
$ deepl --quiet translate "Hello" --to invalid
Error: Invalid target language: invalidCustom Configuration Files:
The --config flag allows you to use alternate configuration files for different projects, environments, or accounts:
# Use work configuration
deepl --config ~/.deepl-work.json translate "Hello" --to es
# Use project-specific configuration
deepl --config ./project/.deepl.json translate docs/ --to fr --output docs-fr/
# Use test environment configuration
deepl --config /path/to/test-config.json usageUse cases:
- Multiple API keys: Switch between free and paid accounts
- Project isolation: Different settings per project (glossaries, formality, etc.)
- Environment separation: Separate configs for dev/staging/production
- Testing: Use test configurations without affecting default settings
Precedence: --config overrides DEEPL_CONFIG_DIR. If neither is specified, uses default location.
Command Suggestions:
Mistype a command? The CLI suggests the closest match:
$ deepl transalte "Hello" --to es
Error: Unknown command 'transalte'. Did you mean 'translate'?Commands are organized into six groups, matching the deepl --help output:
| Group | Commands | Description |
|---|---|---|
| Core Commands | translate, write, voice |
Translation, writing enhancement, and speech translation |
| Resources | glossary |
Manage translation glossaries |
| Workflow | watch, hooks |
File watching and git hook automation |
| Configuration | init, auth, config, cache, style-rules |
Setup wizard, authentication, settings, caching, and style rules |
| Information | usage, languages, detect, completion |
API usage, supported languages, language detection, and shell completions |
| Administration | admin |
Organization key management and usage analytics |
Translate text, files, or directories.
deepl translate [OPTIONS] [TEXT|FILE|DIRECTORY]Translate text directly, from stdin, from files, or entire directories. Supports multiple target languages, code preservation, and context-aware translation.
Input Sources:
- Direct text argument:
deepl translate "Hello" --to es - From stdin:
echo "Hello" | deepl translate --to es - Single file:
deepl translate README.md --to es --output README.es.md - Directory:
deepl translate docs/ --to es --output docs-es/
Note: When reading from stdin or translating files, omit the text argument.
Target Language:
--to, -t LANGS- Target language(s), comma-separated (e.g.,es,es,fr,de). Required unlessdefaults.targetLangsis configured.
Source Options:
--from, -f LANG- Source language (auto-detect if omitted)--context TEXT- Additional context for better translation
Output Options:
--output, -o PATH- Output file or directory (required for file/directory translation, optional for text). Use-for stdout (text-based files only)--output-format FORMAT- Convert PDF to DOCX during translation. Valid choices:docx(only supported conversion)--enable-minification- Enable document minification for PPTX/DOCX files (reduces file size)--format FORMAT- Output format:text,json,table(default:text)
Translation Options:
--formality LEVEL- Formality:default,more,less,prefer_more,prefer_less,formal,informal--model-type TYPE- Model type:quality_optimized,prefer_quality_optimized,latency_optimized(no CLI default; the API server selects the model when omitted)--preserve-code- Preserve code blocks (markdown, etc.)--preserve-formatting- Preserve line breaks and whitespace formatting--split-sentences LEVEL- Sentence splitting:on(default),off,nonewlines--tag-handling MODE- XML tag handling:xml,html--outline-detection BOOL- Control automatic XML structure detection:true(default),false(requires--tag-handling xml)--splitting-tags TAGS- Comma-separated XML tags that split sentences (requires--tag-handling xml)--non-splitting-tags TAGS- Comma-separated XML tags that should not be used to split sentences (requires--tag-handling xml)--ignore-tags TAGS- Comma-separated XML tags with content to ignore (requires--tag-handling xml)--tag-handling-version VERSION- Tag handling version:v1,v2. v2 improves XML/HTML structure handling (requires--tag-handling)--glossary NAME-OR-ID- Use glossary by name or ID for consistent terminology--custom-instruction INSTRUCTION- Custom instruction for translation (repeatable, max 10, max 300 chars each). Forcesquality_optimizedmodel. Cannot be used withlatency_optimized.--style-id UUID- Style rule ID for translation (Pro API only). Forcesquality_optimizedmodel. Cannot be used withlatency_optimized. Usedeepl style-rules listto see available IDs.--enable-beta-languages- Include beta languages that are not yet stable (forward-compatibility with new DeepL languages)--no-cache- Bypass cache for this translation (useful for testing/forcing fresh translation)--dry-run- Show what would be translated without performing the operation
API Options:
--api-url URL- Custom API endpoint URL (for testing or private instances)--show-billed-characters- Request and display actual billed character count for cost transparency
Batch Options (for directories):
--no-recursive- Do not recurse into subdirectories (recursive is the default)--pattern GLOB- File pattern (e.g.,*.md,**/*.txt)--concurrency N- Number of parallel translations (default: 5)
Basic text translation:
# Single language
deepl translate "Hello, world!" --to es
# Multiple languages
deepl translate "Hello, world!" --to es,fr,de
# With source language
deepl translate "Bonjour" --from fr --to enFrom stdin:
# Pipe text
echo "Hello" | deepl translate --to es
# From file via stdin
cat README.md | deepl translate --to frFile translation:
# Single file
deepl translate README.md --to es --output README.es.md
# Multiple languages
deepl translate README.md --to es,fr,de --output translations/
# With code preservation
deepl translate tutorial.md --to es --output tutorial.es.md --preserve-codeOutput to stdout:
# Pipe translated file content to stdout
deepl translate README.md --to es --output -
# Combine with shell tools
deepl translate README.md --to es --output - | wc -l
# Redirect to a file
deepl translate README.md --to es --output - > translated.mdNote: --output - only works with text-based files (.txt, .md, .html, .srt, .xlf). Binary documents (PDF, DOCX, etc.), structured files (JSON, YAML), and multi-target translations do not support stdout output.
Smart caching for text-based files:
Small text-based files are automatically routed to the cached text API for faster, more efficient translations:
# Text files under 100 KiB are automatically cached
deepl translate README.md --to es --output README.es.md
# First translation: Makes API call
# Subsequent identical translations: Instant (from cache)
# HTML files also benefit from caching
deepl translate index.html --to fr --output index.fr.html
# Subtitle files
deepl translate subtitles.srt --to ja --output subtitles.ja.srt
# XLIFF localization files
deepl translate strings.xlf --to de --output strings.de.xlfStructured file formats (i18n):
The following structured formats are parsed to extract only string values, translated via the batch text API, then reassembled preserving keys, nesting, non-string values, indentation, and YAML comments:
.json- JSON files (i18n locale files, config files).yaml,.yml- YAML files (Rails i18n, config files)
# Translate JSON locale file
deepl translate en.json --to es --output es.json
# Translate YAML locale file (comments preserved)
deepl translate en.yaml --to de --output de.yamlCached text-based formats:
The following formats use the cached text API when files are under 100 KiB:
.txt- Plain text files.md- Markdown files.html,.htm- HTML files.srt- Subtitle files.xlf,.xliff- XLIFF localization files
Large file automatic fallback:
When text-based files exceed 100 KiB, they automatically fall back to the document API:
# Large text file (>100 KiB) - uses document API
deepl translate large-document.txt --to es --output large-document.es.txt
# ⚠ File exceeds 100 KiB limit for cached translation (150.5 KiB), using document API instead
# Translated large-document.txt -> large-document.es.txtBenefits of smart caching:
- Performance: Only small text files (<100 KiB) benefit from instant cached translations
- Efficiency: Reduces API calls and character usage for small text files
- Cost savings: Only small text files avoid repeated API quota consumption
- Automatic: No configuration needed - works out of the box
- Transparent: Warning shown when falling back to document API
Important: Large text files (≥100 KiB) and all binary documents use the document API, which is NOT cached. Repeated translations of large files always make fresh API calls.
Document translation:
# Translate PDF document
deepl translate document.pdf --to es --output document.es.pdf
# Translate PowerPoint with formality
deepl translate presentation.pptx --to de --formality more --output presentation.de.pptx
# Translate Excel spreadsheet
deepl translate report.xlsx --to fr --output report.fr.xlsx
# Translate HTML file
deepl translate website.html --to ja --output website.ja.html
# Convert format during translation (PDF to DOCX - only supported conversion)
deepl translate document.pdf --to es --output document.es.docx --output-format docx
# Enable document minification for smaller file size (PPTX/DOCX only)
deepl translate presentation.pptx --to de --output presentation.de.pptx --enable-minification
deepl translate report.docx --to fr --output report.fr.docx --enable-minificationSupported Document Formats:
.pdf- PDF documents (up to 10MB) - Document API only.docx,.doc- Microsoft Word - Document API only.pptx- Microsoft PowerPoint - Document API only.xlsx- Microsoft Excel - Document API only.jpg,.jpeg- JPEG images - Document API only.png- PNG images - Document API only.html,.htm- HTML files - Smart routing (cached text API <100 KiB, document API ≥100 KiB).txt- Plain text files (up to 30MB) - Smart routing (cached text API <100 KiB, document API ≥100 KiB).srt- Subtitle files - Smart routing (cached text API <100 KiB, document API ≥100 KiB).xlf,.xliff- XLIFF localization files - Smart routing (cached text API <100 KiB, document API ≥100 KiB).md- Markdown files - Cached text API (all sizes).json- JSON files - Structured file API (string extraction + batch translation).yaml,.yml- YAML files - Structured file API (string extraction + batch translation, comments preserved)
Document Translation Notes:
- Structured files:
.json,.yaml,.ymlare parsed to extract string values, translated via batch text API, and reassembled preserving structure - Smart routing: Text-based files (
.txt,.md,.html,.srt,.xlf,.xliff) under 100 KiB automatically use the cached text API for better performance - Binary formats (PDF, DOCX, PPTX, XLSX) and image formats (JPEG, PNG) always use the document API regardless of size
- Documents are translated on DeepL servers using async processing
- Progress updates show status (queued → translating → done)
- Billed characters are displayed after completion
- Formatting, structure, and layout are automatically preserved
- Large documents may take several seconds to translate
- Maximum file sizes: 10MB (PDF), 30MB (other formats), 100 KiB (cached text API)
- Document minification (
--enable-minification): Reduces file size for PPTX and DOCX files only. Useful for large presentations and documents.
Directory translation:
# Translate all supported files
deepl translate docs/ --to es --output docs-es/
# With glob pattern
deepl translate docs/ --to es --output docs-es/ --pattern "*.md"
# Recursive (default) with custom concurrency
deepl translate src/ --to es,fr --output translations/ --concurrency 10Context-aware translation:
# Add context for better disambiguation
deepl translate "Bank" --to es --context "Financial institution"
# → "Banco" (not "Orilla" for riverbank)
deepl translate app.json --to es --context "E-commerce checkout flow"Note: The --context feature may not be supported by all DeepL API tiers. Check your API plan for context support availability.
Formality levels:
# Formal
deepl translate "How are you?" --to de --formality more
# → "Wie geht es Ihnen?" (formal)
# Informal
deepl translate "How are you?" --to de --formality less
# → "Wie geht es dir?" (informal)Sentence splitting:
# Default behavior (sentences split on punctuation and newlines)
deepl translate "Hello. How are you?" --to es
# → "Hola. ¿Cómo estás?"
# Disable sentence splitting (treat as one unit)
deepl translate "Hello. How are you?" --to es --split-sentences off
# → May produce different translation
# Split only on punctuation, not newlines
deepl translate "Line 1\nLine 2" --to es --split-sentences nonewlines
# → Preserves line breaks while splitting sentencesTag handling (XML/HTML):
# Basic XML tag preservation
deepl translate "<p>Hello world</p>" --to es --tag-handling xml
# → "<p>Hola mundo</p>"
# Translate HTML content
deepl translate "<div><span>Welcome</span></div>" --to de --tag-handling html
# → "<div><span>Willkommen</span></div>"
# Useful for localizing markup files
deepl translate content.html --to fr --tag-handling html --output content.fr.html
# Advanced XML tag handling: Disable automatic structure detection
deepl translate "<doc><p>Text</p></doc>" --to es --tag-handling xml --outline-detection false
# Forces manual tag handling instead of automatic detection
# Specify tags that split sentences (useful for custom XML formats)
deepl translate "<article><br/>Content<hr/>More</article>" --to es --tag-handling xml --splitting-tags "br,hr"
# Treats <br/> and <hr/> as sentence boundaries
# Specify tags for non-translatable content (like code blocks)
deepl translate "<doc><code>let x = 1;</code><p>Text</p></doc>" --to es --tag-handling xml --non-splitting-tags "code,pre"
# Content in <code> and <pre> tags won't be split into sentences
# Ignore specific tags and their content (e.g., scripts, styles)
deepl translate file.html --to es --tag-handling xml --ignore-tags "script,style,noscript" --output file.es.html
# Content in <script>, <style>, and <noscript> tags is not translated
# Combine multiple XML tag handling options
deepl translate complex.xml --to de --tag-handling xml \
--outline-detection false \
--splitting-tags "br,hr,div" \
--non-splitting-tags "code,pre,kbd" \
--ignore-tags "script,style" \
--output complex.de.xml
# Fine-tuned control for complex XML/HTML documentsGlossary usage:
# Use glossary for consistent terminology
deepl translate "API documentation" --to es --glossary tech-terms
# Use glossary by ID
deepl translate README.md --to fr --glossary abc-123-def-456 --output README.fr.mdCache control:
# Bypass cache for fresh translation
deepl translate "Hello" --to es --no-cache
# Useful for testing or when you need the latest translation
deepl translate document.md --to es --output document.es.md --no-cacheCost transparency:
# Show actual billed character count (Pro API only)
deepl translate "Hello, world!" --to es --show-billed-characters
# Hola, mundo!
#
# Billed characters: 13
# Use with multiple languages
deepl translate "Hello" --to es,fr,de --show-billed-characters
# [es] Hola
# [fr] Bonjour
# [de] Hallo
#
# Billed characters: 15
# Useful for budget tracking and cost analysis
deepl translate document.md --to es --output document.es.md --show-billed-charactersNote: The --show-billed-characters feature is only available with Pro API accounts. Free API accounts will display "N/A" for character counts.
JSON output:
# Get machine-readable JSON output
deepl translate "Hello" --to es --format json
# {"text":"Hola","detectedSourceLang":"en","targetLang":"es","cached":false}
# JSON output may include modelTypeUsed when the API reports which model was used
deepl translate "Hello" --to es --format json --no-cache
# {"text":"Hola","detectedSourceLang":"en","targetLang":"es","modelTypeUsed":"quality_optimized"}
# Useful for scripting and automation
deepl translate "Test" --to es,fr,de --format jsonTable output:
# Display translations in structured table format (multiple languages)
deepl translate "Hello, world!" --to es,fr,de --format table
# ┌──────────┬──────────────────────────────────────────────────────────────────────┐
# │ Language │ Translation │
# ├──────────┼──────────────────────────────────────────────────────────────────────┤
# │ ES │ ¡Hola mundo! │
# │ FR │ Bonjour le monde! │
# │ DE │ Hallo Welt! │
# └──────────┴──────────────────────────────────────────────────────────────────────┘
# Add --show-billed-characters to display the Characters column
deepl translate "Cost tracking" --to es,fr,de --format table --show-billed-characters --no-cache
# ┌──────────┬────────────────────────────────────────────────────────────────┬────────────┐
# │ Language │ Translation │ Characters │
# ├──────────┼────────────────────────────────────────────────────────────────┼────────────┤
# │ ES │ Seguimiento de costes │ 16 │
# │ FR │ Suivi des coûts │ 16 │
# │ DE │ Kostenverfolgung │ 16 │
# └──────────┴────────────────────────────────────────────────────────────────┴────────────┘
# Long translations automatically wrap in the Translation column
deepl translate "This is a very long sentence that demonstrates word wrapping." --to es,fr --format table
# Wider Translation column (70 chars) when Characters column is not shown
# Useful for:
# - Comparing translations side-by-side across multiple languages
# - Monitoring billed characters per translation for cost transparency (with --show-billed-characters)
# - Human-readable output for reports and documentation
# - Quality assurance - spot-checking consistency across languagesNotes:
- Table format is only available when translating to multiple target languages. For single language translations, use default plain text or JSON format.
- The Characters column is only shown when using
--show-billed-charactersflag. - Without
--show-billed-characters, the Translation column is wider (70 characters vs 60) for better readability. - When the API returns metadata (billed characters, model type used), it is appended below the translated text in plain text output and included as fields in JSON output.
Improve text with DeepL Write API (grammar, style, tone enhancement).
deepl write [OPTIONS] TEXTEnhance text quality with AI-powered grammar checking, style improvement, and tone adjustment. Supports 8 languages.
File Detection: The command automatically detects if the text argument is a file path. If a file exists at that path, it operates on the file; otherwise, it treats the argument as text to improve.
Language:
--lang, -l LANG- Target language:de,en,en-GB,en-US,es,fr,it,pt,pt-BR,pt-PT. Optional — omit to auto-detect the language and rephrase in the original language.
Style Options (mutually exclusive with tone):
--style STYLE- Writing style:default- No style modification (API default)simple- Simpler, more accessible languagebusiness- Professional business languageacademic- Formal academic languagecasual- Conversational, informal languageprefer_simple,prefer_business, etc. - Soft preferences
Tone Options (mutually exclusive with style):
--tone TONE- Tone:default- No tone modification (API default)enthusiastic- More enthusiastic and positivefriendly- Warmer, more approachableconfident- More assertive and certaindiplomatic- More careful and tactfulprefer_enthusiastic,prefer_friendly, etc. - Soft preferences
Output Options:
--alternatives, -a- Show all improvement alternatives--interactive, -i- Interactive mode: choose from multiple alternatives--diff, -d- Show diff between original and improved text--check- Check if text needs improvement without modifying (exits with 0 if no changes, 8 if improvements suggested)--fix- Auto-fix files in place--output, -o FILE- Write output to file--in-place- Edit file in place--backup, -b- Create backup before fixing (use with--fix)--format FORMAT- Output format:text,json(default:text)
Advanced:
--no-cache- Bypass cache for this request (always call API)
de- Germanen- English (generic, defaults to American English)en-GB- British Englishen-US- American Englishes- Spanishfr- Frenchit- Italianpt- Portuguese (generic, defaults to Brazilian Portuguese)pt-BR- Brazilian Portuguesept-PT- European Portuguese
Basic improvement (auto-detect language):
deepl write "Me and him went to store."
# → "He and I went to the store."With explicit language:
deepl write "Me and him went to store." --lang en-US
# → "He and I went to the store."With writing style:
# Business style
deepl write "We want to tell you about our product." --lang en-US --style business
# → "We are pleased to inform you about our product."
# Casual style
deepl write "The analysis demonstrates significant findings." --lang en-US --style casual
# → "The analysis shows some pretty big findings."With tone:
# Confident tone
deepl write "I think this might work." --lang en-US --tone confident
# → "This will work."
# Diplomatic tone
deepl write "Your approach is wrong." --lang en-US --tone diplomatic
# → "Perhaps we could consider an alternative approach."Show alternatives:
deepl write "This is good." --lang en-US --alternativesFile operations:
# Improve file and save to new location
deepl write document.txt --lang en-US --output improved.txt
# Edit file in place
deepl write document.txt --lang en-US --in-place
# Auto-fix with backup
deepl write document.txt --lang en-US --fix --backupInteractive mode:
# Choose from multiple alternatives interactively
deepl write "Text to improve." --lang en-US --interactiveCheck mode:
# Check if file needs improvement (exit code 8 if changes needed)
deepl write document.md --lang en-US --checkDiff view:
# Show differences between original and improved
deepl write file.txt --lang en-US --diffJSON output:
# Get machine-readable JSON output
deepl write "This are good." --lang en-US --format json
# {"original":"This are good.","improved":"This is good.","changes":1,"language":"en-US"}Bypass cache:
# Force a fresh API call, skipping cached results
deepl write "Improve this text." --lang en-US --no-cacheTranslate audio using the DeepL Voice API with real-time WebSocket streaming.
deepl voice [options] <file>
| Argument | Description |
|---|---|
file |
Audio file to translate. Use - for stdin. |
| Option | Short | Description | Default |
|---|---|---|---|
--to <languages> |
-t |
Target language(s), comma-separated, max 5 (required) | - |
--from <language> |
-f |
Source language (auto-detect if not specified) | auto |
--formality <level> |
Formality level: default, formal, more, informal, less, prefer_more, prefer_less |
default |
|
--glossary <name-or-id> |
Use glossary by name or ID | - | |
--content-type <type> |
Audio content type (auto-detected from file extension) | auto | |
--chunk-size <bytes> |
Audio chunk size in bytes | 6400 |
|
--chunk-interval <ms> |
Interval between audio chunks in milliseconds | 200 |
|
--no-stream |
Disable live streaming output, collect and print at end | - | |
--no-reconnect |
Disable automatic reconnection on WebSocket drop | - | |
--max-reconnect-attempts <n> |
Maximum reconnect attempts on WebSocket drop | 3 |
|
--source-language-mode <mode> |
Source language detection mode: auto, fixed |
- | |
--format <format> |
Output format: text, json |
text |
Note: All formality values (
default,formal,informal,more,less,prefer_more,prefer_less) are accepted. The voice API natively usesformal/informal(in addition tomore/less), while the translate API usesprefer_more/prefer_less.
| Extension | Content Type |
|---|---|
.ogg, .opus |
audio/opus;container=ogg |
.webm |
audio/opus;container=webm |
.mka |
audio/opus;container=matroska |
.flac |
audio/flac |
.mp3 |
audio/mpeg |
.pcm, .raw |
audio/pcm;encoding=s16le;rate=16000 |
# Basic audio translation
deepl voice recording.ogg --to de
# Multiple target languages
deepl voice meeting.mp3 --to de,fr,es
# With source language and formality
deepl voice audio.flac --to ja --from en --formality more
# Pipe from ffmpeg
ffmpeg -i video.mp4 -f ogg - | deepl voice - --to es --content-type 'audio/opus;container=ogg'
# Pipe raw PCM from stdin
cat audio.pcm | deepl voice - --to es --content-type 'audio/pcm;encoding=s16le;rate=16000'
# JSON output for scripting
deepl voice speech.ogg --to de --format json | jq .targets[0].text
# Disable live streaming
deepl voice speech.ogg --to de --no-stream{
"sessionId": "session-abc123",
"source": {
"lang": "en",
"text": "Hello world",
"segments": [
{ "text": "Hello world", "startTime": 0, "endTime": 1.5 }
]
},
"targets": [
{
"lang": "de",
"text": "Hallo Welt",
"segments": [
{ "text": "Hallo Welt", "startTime": 0, "endTime": 1.5 }
]
}
]
}- The Voice API requires a DeepL Pro or Enterprise plan.
- Maximum 5 target languages per session.
- Maximum audio chunk size: 100KB, recommended pacing: 200ms between chunks.
- Sessions have a 30-second inactivity timeout and 1-hour maximum duration.
- The Voice API always uses the Pro endpoint (
api.deepl.com).
Watch files or directories for changes and auto-translate.
deepl watch [OPTIONS] PATHMonitor files or directories for changes and automatically translate them. Supports debouncing, glob patterns, and multiple target languages.
Behavior:
- Runs continuously until interrupted (Ctrl+C)
- Shows translation statistics on exit
- Detects file changes using filesystem watch
- Debounces rapid changes to avoid duplicate translations
Watch Options:
--to, -t LANGS- Target language(s), comma-separated (uses configureddefaults.targetLangsif omitted)--output, -o DIR- Output directory (default:<path>/translationsfor directories, same dir for files)--pattern GLOB- File pattern filter (e.g.,*.md,**/*.json)--debounce MS- Debounce delay in milliseconds (default: 500)--concurrency NUM- Maximum parallel translations (default: 5)
Translation Options:
--from, -f LANG- Source language (auto-detect if omitted)--formality LEVEL- Formality level:default,more,less,prefer_more,prefer_less,formal,informal--preserve-code- Preserve code blocks--preserve-formatting- Preserve line breaks and whitespace formatting--glossary NAME-OR-ID- Use glossary by name or ID for consistent terminology
Git Integration:
--auto-commit- Auto-commit translations to git after each change--git-staged- Only watch git-staged files (snapshot taken once at startup)--dry-run- Show what would be watched without starting the watcher
Watch single file:
# Basic watching
deepl watch README.md --to es
# With custom output
deepl watch README.md --to es,fr --output translations/
# With options
deepl watch tutorial.md --to es --preserve-code --formality moreWatch directory:
# Watch all supported files
deepl watch docs/ --to es
# Watch with pattern
deepl watch docs/ --to es,fr --pattern "*.md"
# With custom debounce (wait 1 second after changes)
deepl watch docs/ --to es --debounce 1000With auto-commit:
# Automatically commit translations
deepl watch docs/ --to es --auto-commitWith git-staged filtering:
# Only translate files currently staged in git
deepl watch . --to es --git-staged
# Combine with dry-run to preview staged files
deepl watch . --to es,fr --git-staged --dry-run
# Pre-commit workflow: stage files, then watch only those
git add docs/guide.md docs/faq.md
deepl watch docs/ --to de,ja --git-staged --auto-commitNote:
--git-stagedtakes a one-time snapshot of staged files at startup. Files staged after the watcher starts are not included. Requires a git repository — exits with an error otherwise.
Manage git hooks for translation workflow automation.
deepl hooks <SUBCOMMAND>Install, uninstall, and manage git hooks that validate translations before committing or pushing.
Install a git hook.
Arguments:
hook-type- Hook type:pre-commit,pre-push,commit-msg,post-commit
Examples:
deepl hooks install pre-commit
deepl hooks install pre-push
deepl hooks install commit-msg
deepl hooks install post-commitUninstall a git hook.
Examples:
deepl hooks uninstall pre-commit
deepl hooks uninstall pre-push
deepl hooks uninstall commit-msg
deepl hooks uninstall post-commitList all hooks and their installation status.
Options:
--format <format>- Output format:text,json(default:text)
Examples:
deepl hooks list
# JSON output for CI/CD scripting
deepl hooks list --format json
# { "pre-commit": true, "pre-push": false, "commit-msg": false, "post-commit": false }Show the path to a hook file.
Examples:
deepl hooks path pre-commitManage translation glossaries using the DeepL v3 Glossary API.
The v3 API supports both single-target glossaries (one source → one target language) and multilingual glossaries (one source → multiple target languages).
deepl glossary <SUBCOMMAND>Create a new glossary from a TSV or CSV file.
Arguments:
name- Glossary namesource-lang- Source language code (e.g.,en,de,fr)target-lang- Target language code, comma-separated for multiple (e.g.,es,de,fr,es)file- Path to TSV or CSV file with term pairs
File Format:
- TSV (Tab-Separated Values):
source_term<TAB>target_term - CSV (Comma-Separated Values):
source_term,target_term - One term pair per line
- No header row required
Example file (glossary.tsv):
API API
authentication autenticación
cache caché
Examples:
# Create single-target glossary from TSV file
deepl glossary create tech-terms en es glossary.tsv
# ✓ Glossary created: tech-terms (ID: abc123...)
# Source language: EN
# Target languages: ES
# Type: Single target
# Total entries: 3
# Create multilingual glossary with comma-separated target languages
deepl glossary create tech-terms en de,fr,es glossary.tsv
# Create glossary from CSV file
deepl glossary create product-names en fr terms.csvList all glossaries with their IDs, language pairs, and entry counts.
Options:
--format <format>- Output format:text,json(default:text)
Output Format (text):
- Single-target glossaries:
📖 name (source→target) - N entries - Multilingual glossaries:
📚 name (source→N targets) - N entries
Example:
deepl glossary list
# 📖 tech-terms (en→de) - 3 entries
# 📚 multilingual-terms (en→3 targets) - 15 entries
# JSON output for CI/CD scripting
deepl glossary list --format json
# [{ "glossary_id": "abc123...", "name": "tech-terms", ... }]Show glossary details including name, ID, languages, creation date, and entry count.
Options:
--format <format>- Output format:text,json(default:text)
Output includes:
- Name and ID
- Source language
- Target languages (comma-separated for multilingual glossaries)
- Type (Single target or Multilingual)
- Total entry count
- Language pairs (for multilingual glossaries)
- Creation timestamp
Example:
deepl glossary show tech-terms
# Name: tech-terms
# ID: abc123...
# Source language: en
# Target languages: de
# Type: Single target
# Total entries: 3
# Created: 2024-10-07T12:34:56Z
# Multilingual glossary example
deepl glossary show multilingual-terms
# Name: multilingual-terms
# ID: def456...
# Source language: en
# Target languages: es, fr, de
# Type: Multilingual
# Total entries: 15
#
# Language pairs:
# en → es: 5 entries
# en → fr: 5 entries
# en → de: 5 entries
# Created: 2024-10-08T10:00:00ZDelete a glossary by name or ID.
Options:
-y, --yes- Skip confirmation prompt--dry-run- Show what would be deleted without performing the operation
Example:
deepl glossary delete tech-terms
deepl glossary delete abc-123-def-456
deepl glossary delete tech-terms --dry-runGet glossary entries in TSV format (suitable for backup or editing).
Arguments:
name-or-id- Glossary name or ID
Options:
--target-lang <lang>- Target language (required for multilingual glossaries, optional for single-target)--format <format>- Output format:text,json(default:text)
Behavior:
- For single-target glossaries:
--target-langflag is optional (automatically uses the single target language) - For multilingual glossaries:
--target-langflag is required to specify which language pair to retrieve
Example:
# Single-target glossary (no --target-lang needed)
deepl glossary entries tech-terms > backup.tsv
# View entries
deepl glossary entries tech-terms
# API → API
# REST → REST
# authentication → Authentifizierung
# Multilingual glossary (--target-lang required)
deepl glossary entries multilingual-terms --target-lang es
# API → API
# cache → caché
# ...
deepl glossary entries multilingual-terms --target-lang fr
# API → API
# cache → cache
# ...List all supported glossary language pairs.
Description: Shows which source-target language combinations are available for glossary creation. Not all language pairs supported by DeepL translation are available for glossaries.
Example:
deepl glossary languages
# en → de
# en → es
# en → fr
# de → en
# ...Add a new entry to an existing glossary.
Arguments:
name-or-id- Glossary name or IDsource- Source language termtarget- Target language translation
Options:
--target-lang <lang>- Target language (required for multilingual glossaries, optional for single-target)
Behavior:
- Uses v3 PATCH endpoint for efficient updates (no delete+recreate)
- Glossary ID remains unchanged
- Preserves all other entries
- Fails if entry already exists
Examples:
# Add entry to single-target glossary
deepl glossary add-entry tech-terms "database" "Datenbank"
# Add entry to multilingual glossary (--target-lang required)
deepl glossary add-entry multilingual-terms "cache" "caché" --target-lang es
deepl glossary add-entry multilingual-terms "cache" "cache" --target-lang fr
# Add phrase
deepl glossary add-entry tech-terms "user interface" "Schnittstelle"Note: v3 API uses PATCH for efficient updates. The glossary ID remains unchanged.
Update an existing entry in a glossary.
Arguments:
name-or-id- Glossary name or IDsource- Source language term to updatenew-target- New target language translation
Options:
--target-lang <lang>- Target language (required for multilingual glossaries, optional for single-target)
Behavior:
- Updates existing entry's target text using v3 PATCH endpoint
- Glossary ID remains unchanged
- Fails if entry doesn't exist
Examples:
# Update entry in single-target glossary
deepl glossary update-entry tech-terms "API" "API (Programmierschnittstelle)"
# Update entry in multilingual glossary (--target-lang required)
deepl glossary update-entry multilingual-terms "API" "API (Interfaz)" --target-lang es
deepl glossary update-entry multilingual-terms "API" "API (Interface)" --target-lang frNote: v3 API uses PATCH for efficient updates. The glossary ID remains unchanged.
Remove an entry from a glossary.
Arguments:
name-or-id- Glossary name or IDsource- Source language term to remove
Options:
--target-lang <lang>- Target language (required for multilingual glossaries, optional for single-target)
Behavior:
- Removes entry from glossary using v3 PATCH endpoint
- Glossary ID remains unchanged
- Fails if entry doesn't exist
- Fails if removing the last entry (delete glossary instead)
Examples:
# Remove entry from single-target glossary
deepl glossary remove-entry tech-terms "obsolete-term"
# Remove entry from multilingual glossary (--target-lang required)
deepl glossary remove-entry multilingual-terms "deprecated" --target-lang esNote: You cannot remove the last entry from a glossary. If you need to remove all entries, use deepl glossary delete instead.
Rename a glossary.
Arguments:
name-or-id- Glossary name or IDnew-name- New name for the glossary
Behavior:
- Changes glossary name using v3 PATCH endpoint
- Glossary ID remains unchanged
- Preserves all entries and language pairs
- Fails if new name matches current name
Examples:
# Rename by glossary name
deepl glossary rename tech-terms "Technical Terminology v2"
# Rename by glossary ID
deepl glossary rename abc-123-def-456 "Product Names 2024"Note: v3 API uses PATCH for efficient rename. The glossary ID remains unchanged and all entries are preserved.
Update a glossary's name and/or dictionary entries in a single request.
Arguments:
name-or-id- Glossary name or ID
Options:
--name <name>- New glossary name--target-lang <lang>- Target language for dictionary update (required when using--file)--file <path>- TSV/CSV file with entries for dictionary update
Behavior:
- At least one of
--nameor--file(with--target-lang) must be provided - When both
--nameand--fileare given, the rename and dictionary update happen in a single PATCH request --target-langis required when--fileis specified- Uses v3 PATCH endpoint for efficient updates
- Glossary ID remains unchanged
Examples:
# Rename only
deepl glossary update my-terms --name "Updated Terms"
# Update dictionary entries only
deepl glossary update my-terms --target-lang de --file updated.tsv
# Rename and update dictionary in one request
deepl glossary update my-terms --name new-name --target-lang de --file updated.tsvReplace all entries in a glossary dictionary from a TSV/CSV file (v3 API only). Unlike updating individual entries (which merges), this replaces the entire dictionary contents.
Arguments:
name-or-id- Glossary name or IDtarget-lang- Target language of the dictionary to replace (e.g.,es,fr,de)file- TSV/CSV file path with replacement entries
Examples:
# Replace all Spanish entries from a new file
deepl glossary replace-dictionary my-glossary es new-entries.tsv
# ✓ Dictionary replaced successfully (es)
# Replace by glossary ID
deepl glossary replace-dictionary abc-123-def-456 fr updated-fr.tsvNotes:
- Replaces the entire dictionary via the v3 PUT endpoint (not a merge)
- All existing entries for the specified language pair are removed and replaced with the file contents
- The file format is the same as for
glossary create(TSV or CSV)
Delete a specific language pair from a multilingual glossary (v3 API only).
Arguments:
name-or-id- Glossary name or IDtarget-lang- Target language of the dictionary to delete (e.g.,es,fr,de)
Options:
-y, --yes- Skip confirmation prompt
Behavior:
- Removes a specific language pair from a multilingual glossary using v3 DELETE endpoint
- Glossary ID remains unchanged
- Other language pairs in the glossary are preserved
- Fails if glossary is single-target (use
glossary deleteinstead) - Fails if this would be the last dictionary in the glossary (use
glossary deleteinstead) - Fails if the dictionary doesn't exist in the glossary
Examples:
# Delete Spanish dictionary from multilingual glossary
deepl glossary delete-dictionary multilingual-terms es
# ✓ Dictionary deleted successfully (es)
# Other language pairs (fr, de) remain intact
# Delete by glossary ID
deepl glossary delete-dictionary abc-123-def-456 fr
# ✓ Dictionary deleted successfully (fr)Notes:
- Multilingual glossaries only: This command only works with multilingual glossaries that have multiple target languages. For single-target glossaries, use
deepl glossary deleteto remove the entire glossary. - Preserves glossary: Unlike
glossary delete, this command preserves the glossary and only removes one language pair. - Cannot delete last dictionary: If the glossary would have zero dictionaries after deletion, the command fails. Use
glossary deleteto remove the entire glossary instead.
Manage translation cache.
deepl cache <SUBCOMMAND>Show cache statistics (status, entries count, size, percentage used).
Options:
--format <format>- Output format:text,json,table(default:text)
Clear all cache entries (displays: "✓ Cache cleared successfully").
Options:
-y, --yes- Skip confirmation prompt--dry-run- Show cache stats that would be cleared without performing the operation
Enable cache (displays: "✓ Cache enabled").
Options:
--max-size <size>- Maximum cache size (e.g.,100M,1G,500MB)
Examples:
# Enable cache with default size
deepl cache enable
# Enable cache with custom size
deepl cache enable --max-size 100M
deepl cache enable --max-size 1GNote: You can also configure max cache size separately: deepl config set cache.maxSize <bytes>
Disable cache (displays: "✓ Cache disabled").
Manage CLI configuration.
deepl config <SUBCOMMAND>List all configuration values (same as get without arguments).
Options:
--format <format>- Output format:text,json(default:json)
Examples:
# JSON output (default)
deepl config list
# Human-readable key=value pairs
deepl config list --format text
# auth.apiKey = "xxxx...xxxx"
# cache.enabled = true
# cache.maxSize = 1073741824Get a specific configuration value, or all values if key is omitted.
Arguments:
key(optional) - Configuration key in dot notation (e.g.,cache.maxSize,auth.apiKey)
Options:
--format <format>- Output format:text,json(default:json)
Examples:
# Get all configuration (JSON)
deepl config get
# Get specific value
deepl config get cache.maxSize
# Human-readable output
deepl config get cache.maxSize --format text
# cache.maxSize = 1073741824Set a configuration value.
Arguments:
key- Configuration key in dot notationvalue- Value to set
Examples:
deepl config set cache.maxSize 52428800
deepl config set defaults.formality moreReset configuration to defaults (keeps API key).
Options:
-y, --yes- Skip confirmation prompt
Show API usage statistics.
deepl usageDisplay your DeepL API character usage and remaining quota. Helps you monitor consumption and avoid exceeding your account limits.
--format FORMAT- Output format:text,json,table(default:text)
# Show usage statistics (Free account)
deepl usage
# Character Usage:
# Used: 123,456 / 500,000 (24.7%)
# Remaining: 376,544
# Pro account output (additional sections)
deepl usage
# Character Usage:
# Used: 2,150,000 / 20,000,000 (10.8%)
# Remaining: 17,850,000
#
# Billing Period:
# 2025-04-24 to 2025-05-24
#
# API Key Usage:
# Used: 1,880,000 / unlimited
#
# Speech-to-Text Usage:
# Used: 12m 34s / 1h 0m 0s (20.9%)
# Remaining: 47m 26s
#
# Product Breakdown:
# translate: 900,000 characters (API key: 880,000)
# write: 1,250,000 characters (API key: 1,000,000)
# speech_to_text: 12m 34s (API key: 12m 34s)Output Fields:
- Used: Number of characters translated this billing period
- Limit: Total character limit for your account
- Percentage: Usage as a percentage of total quota
- Remaining: Characters remaining in your quota
Pro accounts show additional fields:
- Billing Period: Start and end dates of the current billing cycle
- API Key Usage: Characters used by this specific API key (vs. the whole account)
- Speech-to-Text Usage: Duration used and remaining for speech-to-text quota (displayed as hours/minutes/seconds)
- Product Breakdown: Per-product character counts (translate, write) and durations (speech_to_text) with API key-level breakdown
Notes:
- Usage resets monthly for most accounts
- Free tier: typically 500,000 characters/month
- Pro accounts: varies by subscription level; additional sections shown automatically
- Shows warning when usage exceeds 80%
List supported source and target languages.
deepl languages [OPTIONS]Display all 121 supported languages grouped by category. Core and regional languages are shown first, followed by extended languages. When an API key is configured, language names are fetched from the DeepL API; otherwise, the local language registry is used.
You can filter to show only source languages, only target languages, or both (default).
--source, -s- Show only source languages--target- Show only target languages--format FORMAT- Output format:text,json,table(default:text)
# Show all supported languages (both source and target)
deepl languages
# Source Languages:
# ar Arabic
# bg Bulgarian
# ...
# zh Chinese
#
# Extended Languages (quality_optimized only, no formality/glossary):
# ace Acehnese
# af Afrikaans
# ...
#
# Target Languages:
# ar Arabic [F]
# ...
# en-gb English (British)
# en-us English (American)
# ...
#
# Extended Languages (quality_optimized only, no formality/glossary):
# ace Acehnese
# ...
#
# [F] = supports formality parameter
# Show only source languages
deepl languages --source
# Show only target languages
deepl languages --target
# Works without API key (shows local registry data)
deepl languages
# Note: No API key configured. Showing local language registry only.Output Format:
- Languages are grouped: core/regional first, then extended in a separate section
- Extended languages are annotated with "quality_optimized only, no formality/glossary"
- Target languages that support the
--formalityparameter are marked with[F](requires API key) - Language codes are left-aligned and padded for readability
Notes:
- Source and target language lists differ: 7 regional variants (en-gb, en-us, es-419, pt-br, pt-pt, zh-hans, zh-hant) are target-only
- Extended languages (82 codes) only support
quality_optimizedmodel type and do not support formality or glossary features - Without an API key, the command shows all languages from the local registry with a warning
Detect the language of text using DeepL API.
deepl detect [OPTIONS] [text]Detect the language of the given text. Under the hood, this command calls the DeepL translate API with a dummy target language and returns only the detected_source_language field from the response.
Text can be provided as a positional argument or piped via stdin.
--format <format>- Output format:text,json(default:text)
# Detect language of French text
deepl detect "Bonjour le monde"
# Detected language: French (fr)
# Detect language with JSON output
deepl detect "Hallo Welt" --format json
# {
# "detected_language": "de",
# "language_name": "German"
# }
# Pipe text via stdin
echo "Ciao mondo" | deepl detect
# Detected language: Italian (it)
# Use in a script
LANG=$(deepl detect "Hola" --format json | jq -r '.detected_language')
echo "$LANG" # esNotes:
- Requires an API key (the detection uses a translate API call)
- Each detection call consumes character quota (the text is translated to produce the detection)
- Very short text (single characters or words) may produce unreliable detection results
- Supports all 121 languages recognized by the DeepL API (core, regional, and extended)
Generate shell completion scripts for bash, zsh, or fish.
deepl completion <shell>shell- Shell type:bash,zsh,fish
# Generate and install bash completions
deepl completion bash > /etc/bash_completion.d/deepl
# Generate and install zsh completions
deepl completion zsh > "${fpath[1]}/_deepl"
# Generate and install fish completions
deepl completion fish > ~/.config/fish/completions/deepl.fish
# Or source directly in your current session:
source <(deepl completion bash)
eval "$(deepl completion zsh)"
deepl completion fish | sourceInteractive setup wizard for first-time users.
deepl initGuides through API key setup, default target language selection, and basic configuration. Validates the API key against the DeepL API before saving.
# Run the interactive setup wizard
deepl init
# Output:
# Welcome to DeepL CLI! Let's get you set up.
# Enter your DeepL API key: ****
# ✓ API key validated (DeepL API Free)
# Select default target language: es
# ✓ Configuration saved
# You're ready! Try: deepl translate "Hello" --to esManage API authentication.
deepl auth <SUBCOMMAND>Set your DeepL API key and validate it with the DeepL API.
Arguments:
api-key(optional) - Your DeepL API authentication key. If omitted, reads from stdin.
Options:
--from-stdin- Read API key from stdin
Examples:
# Pipe key from stdin (recommended - avoids exposing key in process listings)
echo "YOUR-API-KEY" | deepl auth set-key --from-stdin
# Read from file
deepl auth set-key --from-stdin < ~/.deepl-api-key
# Provide key as argument
deepl auth set-key YOUR-API-KEY-HERE
# ✓ API key saved and validated successfullySecurity Note: Prefer --from-stdin over passing the key as a command argument. Command arguments are visible to other users via process listings (ps aux).
Deprecation: Passing the API key as a positional argument is deprecated and will emit a warning. Use
--from-stdininstead for secure key input.
Show current API key (masked for security).
Output Format: API Key: abcd...xyz1 (first 4 and last 4 characters visible)
Examples:
deepl auth show
# API Key: 1234...abcd
deepl auth show
# No API key setClear stored API key from configuration.
Examples:
deepl auth clear
# ✓ API key removedManage DeepL style rules (Pro API only). Style rules are created via the DeepL web UI and applied to translations using their ID.
deepl style-rules <SUBCOMMAND>List all available style rules.
Options:
--detailed- Show detailed information including configured rules and custom instructions--page NUMBER- Page number for pagination--page-size NUMBER- Number of results per page (1-25)--format FORMAT- Output format:text,json(default:text)
Examples:
# List all style rules
deepl style-rules list
# List with details
deepl style-rules list --detailed
# JSON output
deepl style-rules list --format json
# Pagination
deepl style-rules list --page 1 --page-size 10- Style rules are created and managed via the DeepL web interface, not through the API
- Style rules are Pro API only and datacenter-specific (EU and US rules don't cross)
- Use the style ID from
style-rules listwithdeepl translate --style-id <uuid> - Style rules force the
quality_optimizedmodel type
Admin API for managing API keys and viewing organization usage analytics. Requires an admin-level API key.
deepl admin <SUBCOMMAND>List all API keys in the organization.
Options:
--format FORMAT- Output format:text,json(default:text)
Examples:
# List all API keys
deepl admin keys list
# JSON output
deepl admin keys list --format jsonCreate a new API key.
Options:
--label LABEL- Label for the new key--format FORMAT- Output format:text,json(default:text)
Examples:
# Create a key with a label
deepl admin keys create --label "Production Key"
# Create a key without a label
deepl admin keys create
# JSON output
deepl admin keys create --label "CI Key" --format jsonDeactivate an API key (permanent, cannot be undone).
Arguments:
<key-id>- Key ID to deactivate (required)
Options:
-y, --yes- Skip confirmation prompt
Examples:
deepl admin keys deactivate abc123-def456
deepl admin keys deactivate abc123-def456 --yesRename an API key.
Arguments:
<key-id>- Key ID to rename (required)<label>- New label (required)
Examples:
deepl admin keys rename abc123-def456 "New Label"Set character usage limit for an API key.
Arguments:
<key-id>- Key ID (required)<characters>- Character limit (number or "unlimited") (required)
Options:
--stt-limit <milliseconds>- Speech-to-text milliseconds limit (number orunlimited)
Examples:
# Set a limit of 1 million characters
deepl admin keys set-limit abc123-def456 1000000
# Remove the limit
deepl admin keys set-limit abc123-def456 unlimited
# Set character limit and speech-to-text limit together
deepl admin keys set-limit abc123-def456 1000000 --stt-limit 3600000View organization usage analytics with per-product character breakdowns.
Options:
--start DATE- Start date in YYYY-MM-DD format (required)--end DATE- End date in YYYY-MM-DD format (required)--group-by GROUPING- Group results:key,key_and_day--format FORMAT- Output format:text,json(default:text)
Output includes:
- Total characters across all products
- Text translation characters — characters used for
/v2/translate - Document translation characters — characters used for document translation
- Text improvement characters — characters used for DeepL Write
Examples:
# View total usage for a date range
deepl admin usage --start 2024-01-01 --end 2024-12-31
# Group usage by key
deepl admin usage --start 2024-01-01 --end 2024-12-31 --group-by key
# Daily usage per key
deepl admin usage --start 2024-01-01 --end 2024-01-31 --group-by key_and_day
# JSON output
deepl admin usage --start 2024-01-01 --end 2024-12-31 --format jsonExample output:
Period: 2024-01-01 to 2024-01-31
Total Usage:
Total: 10,000
Translation: 7,000
Documents: 2,000
Write: 1,000
Per-Key Usage (2 entries):
Staging Key
Total: 6,000
Translation: 4,000
Documents: 1,500
Write: 500
Production Key
Total: 4,000
Translation: 3,000
Documents: 500
Write: 500
- Admin API endpoints require an admin-level API key (not a regular developer key)
- Key deactivation is permanent and cannot be undone
- Usage analytics show per-product character breakdowns (translation, documents, write)
- The
--group-byoption provides granular breakdowns for cost allocation
Configuration file location:
The CLI resolves configuration and cache paths using the following priority order:
| Priority | Condition | Config path | Cache path |
|---|---|---|---|
| 1 | DEEPL_CONFIG_DIR set |
$DEEPL_CONFIG_DIR/config.json |
$DEEPL_CONFIG_DIR/cache.db |
| 2 | ~/.deepl-cli/ exists |
~/.deepl-cli/config.json |
~/.deepl-cli/cache.db |
| 3 | XDG env vars set | $XDG_CONFIG_HOME/deepl-cli/config.json |
$XDG_CACHE_HOME/deepl-cli/cache.db |
| 4 | Default | ~/.config/deepl-cli/config.json |
~/.cache/deepl-cli/cache.db |
Existing ~/.deepl-cli/ installations continue to work with no changes needed.
{
"auth": {
"apiKey": "your-api-key"
},
"api": {
"baseUrl": "https://api.deepl.com",
"usePro": true
},
"defaults": {
"sourceLang": null,
"targetLangs": [],
"formality": "default",
"preserveFormatting": true
},
"cache": {
"enabled": true,
"maxSize": 1073741824,
"ttl": 2592000
},
"output": {
"format": "text",
"verbose": false,
"color": true
},
"watch": {
"debounceMs": 500,
"autoCommit": false,
"pattern": "*.md"
}
}Configuration Notes:
baseUrloverrides the auto-detected API endpoint. By default, the endpoint is auto-detected from the API key tier: keys ending with:fxuse the Free API (api-free.deepl.com), all others use the Pro API (api.deepl.com). TheuseProflag can also be used to control tier selection explicitly.- Most users configure settings via
deepl config setcommand rather than editing the file directly.
The CLI uses semantic exit codes to enable intelligent error handling in scripts and CI/CD pipelines.
| Code | Meaning | Description | Retryable |
|---|---|---|---|
| 0 | Success | Operation completed successfully | N/A |
| 1 | General Error | Unclassified error | No |
| 2 | Authentication Error | Invalid or missing API key | No |
| 3 | Rate Limit Error | Too many requests (HTTP 429) | Yes |
| 4 | Quota Exceeded | Character limit reached (HTTP 456) | No |
| 5 | Network Error | Connection timeout, refused, or service unavailable (HTTP 503) | Yes |
| 6 | Invalid Input | Missing arguments, unsupported format, or validation error | No |
| 7 | Configuration Error | Invalid configuration file or settings | No |
| 8 | Check Failed | Text needs improvement (deepl write --check) |
No |
| 9 | Voice Error | Voice API error (unsupported plan or session failure) | No |
Special Cases:
deepl write --check: Exits with 0 if no changes needed, 8 (CheckFailed) if improvements suggested
Exit Code Classification:
The CLI automatically classifies errors based on error messages and HTTP status codes:
- Authentication (2): "authentication failed", "invalid api key", "api key not set"
- Rate Limit (3): "rate limit exceeded", "too many requests", HTTP 429. The CLI respects the
Retry-Afterheader when present, falling back to exponential backoff when absent - Quota (4): "quota exceeded", "character limit reached", HTTP 456
- Network (5): "econnrefused", "enotfound", "econnreset", "etimedout", "socket hang up", "network error", "network timeout", "connection refused", "connection reset", "connection timed out", "service temporarily unavailable", HTTP 503
- Invalid Input (6): "cannot be empty", "not found", "unsupported", "not supported", "invalid", "is required", "expected", "cannot specify both"
- Configuration (7): "config file", "config directory", "configuration file", "configuration error", "failed to load config", "failed to save config", "failed to read config"
Trace IDs for Debugging:
API error messages include the DeepL X-Trace-ID header when available. This trace ID is useful for debugging and when contacting DeepL support:
deepl translate "Hello" --to es
# Error: Authentication failed: Invalid API key (Trace ID: abc123-def456-ghi789)The trace ID is also accessible programmatically via DeepLClient.lastTraceId after any API call.
CI/CD Integration:
Use exit codes to implement intelligent retry logic in scripts:
#!/bin/bash
# Retry on rate limit or network errors only
deepl translate "Hello" --to es
EXIT_CODE=$?
case $EXIT_CODE in
0)
echo "Success"
;;
3|5)
echo "Retryable error (code $EXIT_CODE), retrying in 5 seconds..."
sleep 5
deepl translate "Hello" --to es
;;
*)
echo "Non-retryable error (code $EXIT_CODE)"
exit $EXIT_CODE
;;
esacChecking Exit Codes:
# Check if translation succeeded
if deepl translate "Hello" --to es; then
echo "Translation succeeded"
else
EXIT_CODE=$?
echo "Translation failed with exit code: $EXIT_CODE"
fi
# Handle specific errors
deepl translate "Hello" --to invalid
if [ $? -eq 6 ]; then
echo "Invalid input provided"
fiSet your API key via environment variable.
export DEEPL_API_KEY="your-api-key"
deepl translate "Hello" --to esOverride config and cache directory. Takes highest priority over all other path resolution.
export DEEPL_CONFIG_DIR="/custom/path"Override XDG config base directory (default: ~/.config). Config is stored at $XDG_CONFIG_HOME/deepl-cli/config.json. Only used when DEEPL_CONFIG_DIR is unset and legacy ~/.deepl-cli/ does not exist.
export XDG_CONFIG_HOME="$HOME/.config"Override XDG cache base directory (default: ~/.cache). Cache is stored at $XDG_CACHE_HOME/deepl-cli/cache.db. Only used when DEEPL_CONFIG_DIR is unset and legacy ~/.deepl-cli/ does not exist.
export XDG_CACHE_HOME="$HOME/.cache"Disable colored output.
export NO_COLOR=1Force colored output even when the terminal doesn't appear to support it. Note: NO_COLOR takes priority if both are set. Useful in CI environments.
export FORCE_COLOR=1When set to dumb, disables colored output and progress spinners. This is automatically set by some CI environments and editors.
export TERM=dumbLast Updated: February 17, 2026 DeepL CLI Version: 1.0.0