DeepL.net
1.13.0
dotnet add package DeepL.net --version 1.13.0
NuGet\Install-Package DeepL.net -Version 1.13.0
<PackageReference Include="DeepL.net" Version="1.13.0" />
paket add DeepL.net --version 1.13.0
#r "nuget: DeepL.net, 1.13.0"
// Install DeepL.net as a Cake Addin #addin nuget:?package=DeepL.net&version=1.13.0 // Install DeepL.net as a Cake Tool #tool nuget:?package=DeepL.net&version=1.13.0
DeepL .NET Library
The DeepL API is a language AI API that allows other computer programs to send texts and documents to DeepL's servers and receive high-quality translations and improvements to the text. This opens a whole universe of opportunities for developers: any translation product you can imagine can now be built on top of DeepL's best-in-class translation technology.
The DeepL .NET library offers a convenient way for applications written in .NET to interact with the DeepL API. We intend to support all API functions with the library, though support for new features may be added to the library after they’re added to the API.
Getting an authentication key
To use the DeepL .NET Library, you'll need an API authentication key. To get a key, please create an account here. With a DeepL API Free account you can consume up to 500,000 characters/month for free.
Installation
Using the .NET Core command-line interface (CLI) tools:
dotnet add package DeepL.net
Using the NuGet Command Line Interface (CLI):
nuget install DeepL.net
Usage
All entities in the DeepL .NET library are in the DeepL
namespace:
using DeepL;
Create a DeepLClient
object providing your DeepL API authentication key.
Be careful not to expose your key, for example when sharing source code.
var authKey = "f63c02c5-f056-..."; // Replace with your key
var client = new DeepLClient(authKey);
This example is for demonstration purposes only. In production code, the authentication key should not be hard-coded, but instead fetched from a configuration file or environment variable.
DeepLClient
accepts options as the second argument, see Configuration for more information.
Translating text
To translate text, call TranslateTextAsync()
. The first argument is a string containing the text to translate, or
IEnumerable
of strings to translate multiple texts.
The second and third arguments are case-insensitive language codes for the source and target language respectively,
for example "DE"
, "FR"
.
The LanguageCode
static class defines constants for the currently supported languages, for example
LanguageCode.German
, LanguageCode.French
.
To auto-detect the input text language, specify null
as the source language.
Additional TextTranslateOptions
can also be provided, see Text translation options below.
TranslateTextAsync()
returns a TextResult
or TextResult
array corresponding to the input text(s).
The TextResult
contains:
- the translated text,
- the detected source language code,
- the number of characters billed for the text, and
- the translation model type used (only non-null if the ModelType option is specified.)
// Translate text into a target language, in this case, French:
var translatedText = await client.TranslateTextAsync(
"Hello, world!",
LanguageCode.English,
LanguageCode.French);
Console.WriteLine(translatedText); // "Bonjour, le monde !"
// Note: printing or converting the result to a string uses the output text.
// Translate multiple texts into British English:
var translations = await client.TranslateTextAsync(
new[] { "お元気ですか?", "¿Cómo estás?" }, null, "EN-GB");
Console.WriteLine(translations[0].Text); // "How are you?"
Console.WriteLine(translations[0].DetectedSourceLanguageCode); // "JA"
Console.WriteLine(translations[0].BilledCharacters); // 7 - the number of characters in the source text "お元気ですか?"
Console.WriteLine(translations[1].Text); // "How are you?"
Console.WriteLine(translations[1].DetectedSourceLanguageCode); // "ES"
Console.WriteLine(translations[1].BilledCharacters); // 12 - the number of characters in the source text "¿Cómo estás?"
// Translate into German with less and more Formality:
foreach (var formality in new[] { Formality.Less, Formality.More }) {
Console.WriteLine(
await client.TranslateTextAsync(
"How are you?",
null,
LanguageCode.German,
new TextTranslateOptions { Formality = formality }));
}
// Will print: "Wie geht es dir?" "Wie geht es Ihnen?"
Text translation options
TextTranslateOptions
has the following properties that impact text translation:
SentenceSplittingMode
: specifies how input text should be split into sentences, default:'SentenceSplittingMode.All'
.SentenceSplittingMode.All
: input text will be split into sentences using both newlines and punctuation.SentenceSplittingMode.Off
: input text will not be split into sentences. Use this for applications where each input text contains only one sentence.SentenceSplittingMode.NoNewlines
: input text will be split into sentences using punctuation but not newlines.
PreserveFormatting
: controls automatic-formatting-correction. Set totrue
to prevent automatic-correction of formatting, default:false
.Formality
: controls whether translations should lean toward informal or formal language. This option is only available for some target languages, see Listing available languages.Formality.Less
: use informal language.Formality.More
: use formal, more polite language.Formality.Default
: standard level of formality.Formality.PreferLess
: less formality, if available for the specified target language, otherwise default.Formality.PreferMore
: more formality, if available for the specified target language, otherwise default.
GlossaryId
: specifies a glossary to use with translation, as a string containing the glossary ID.Context
: specifies additional context to influence translations, that is not translated itself. Characters in thecontext
parameter are not counted toward billing. See the API documentation for more information and example usage.ModelType
: specifies the type of translation model to use, options are:'quality_optimized'
(ModelType.QualityOptimized
): use a translation model that maximizes translation quality, at the cost of response time. This option may be unavailable for some language pairs.'prefer_quality_optimized'
(ModelType.PreferQualityOptimized
): use the highest-quality translation model for the given language pair.'latency_optimized'
(ModelType.LatencyOptimized
): use a translation model that minimizes response time, at the cost of translation quality.
TagHandling
: type of tags to parse before translation, options are"html"
and"xml"
.
The following options are only used if TagHandling
is set to 'xml'
:
OutlineDetection
: set tofalse
to disable automatic tag detection, default istrue
.SplittingTags
:List
of XML tags that should be used to split text into sentences. Tags may be specified individually (['tag1', 'tag2']
), or a comma-separated list of strings ('tag1,tag2'
). The default is an empty list.NonSplittingTags
:List
of XML tags that should not be used to split text into sentences. Format and default are the same as for splitting tags.IgnoreTags
:List
of XML tags that containing content that should not be translated. Format and default are the same as for splitting tags.
For a detailed explanation of the XML handling options, see the API documentation.
Improving text (Write API)
You can use the Write API to improve or rephrase text. This is implemented in
the RephraseTextAsync()
method. The first argument is a string containing the text
you want to translate, or a list of strings if you want to translate multiple texts.
targetLanguageCode
optionally specifies the target language, e.g. when you want to change
the variant of a text (for example, you can send an english text to the write API and
use targetLanguageCode
to turn it into British or American English). Please note that the
Write API itself does NOT translate. If you wish to translate and improve a text, you
will need to make multiple calls in a chain.
Language codes are the same as for translating text.
Example call:
WriteResult result = await client.RephraseTextAsync("A rainbouw has seven colours.", "EN-US");
Console.WriteLine(result);
Additionally, you can optionally specify a style OR a tone (not both at once) that the
improvement should be in. The following styles are supported (default
will be used if
nothing is selected):
academic
business
casual
default
simple
The following tones are supported (default
will be used if nothing is selected):
confident
default
diplomatic
enthusiastic
friendly
You can also prefix any non-default style or tone with prefer_
(prefer_academic
, etc.),
in which case the style/tone will only be applied if the language supports it. If you do not
use prefer_
, requests with targetLanguageCode
s or detected languages that do not support
styles and tones will fail. The current list of supported languages can be found in our
[API documentation][api-docs]. We plan to also expose this information via an API endpoint
in the future.
You can pass a style like so:
var options = new TextRephraseOptions { WritingStyle = "business" }
var result = await client.RephraseTextAsync("A rainbouw has seven colours.", "EN-US", options);
Console.WriteLine(result);
Translating documents
To translate documents, call TranslateDocumentAsync()
with the input and output files as FileInfo
objects, and provide the source and target language as above.
Additional DocumentTranslateOptions
are also available, see Document translation options below.
Note that file paths are not accepted as strings, to avoid mixing up the file and language arguments.
// Translate a formal document from English to German
try {
await client.TranslateDocumentAsync(
new FileInfo("Instruction Manual.docx"),
new FileInfo("Bedienungsanleitung.docx"),
"EN",
"DE",
new DocumentTranslateOptions { Formality = Formality.More });
} catch (DocumentTranslationException exception) {
// If the error occurs *after* upload, the DocumentHandle will contain the document ID and key
if (exception.DocumentHandle != null) {
var handle = exception.DocumentHandle.Value;
Console.WriteLine($"Document ID: {handle.DocumentId}, Document key: {handle.DocumentKey}");
} else {
Console.WriteLine($"Error occurred during document upload: {exception.Message}");
}
}
Alternatively the input and output files may be provided as Stream
objects; in
that case the input file name (or extension) is required, so the DeepL API can
determine the file type:
...
await client.TranslateDocumentAsync(
new MemoryStream(buffer),
"Input file.docx", // An extension like ".docx" is also sufficient
File.OpenWrite(outputDocumentPath),
"EN",
"DE",
new DocumentTranslateOptions { Formality = Formality.More });
TranslateDocumentAsync()
manages the upload, wait until translation is complete, and download steps. If your
application needs to execute these steps individually, you can instead use the following functions directly:
TranslateDocumentUploadAsync()
,TranslateDocumentStatusAsync()
(orTranslateDocumentWaitUntilDoneAsync()
), andTranslateDocumentDownloadAsync()
Document translation options
DocumentTranslateOptions
has the following properties that impact text translation:
Formality
: same as in Text translation options.GlossaryId
: same as in Text translation options.EnableDocumentMinification
: Abool
value. If set totrue
, the library will try to minify a document before translating it through the API, sending a smaller document if the file contains a lot of media. This is currently only supported forpptx
anddocx
files. See also Document minification. Note that this only works in the high-levelTranslateDocumentDownloadAsync
method, notTranslateDocumentUploadAsync
. However, the behavior can be emulated by creating a newDocumentMinifier
object and calling the minifier's methods in between.
Document minification
In some contexts, one can end up with large document files (e.g. PowerPoint presentations
or Word files with many contributors, especially in a larger organization). However, the
DeepL API enforces a limit of 30 MB for most of these files (see Usage Limits in the docs).
In the case that most of this size comes from media included in the documents (e.g. images,
videos, animations), document minification can help.
In this case, the library will create a temporary directory to extract the document into,
replace the large media with tiny placeholders, create a minified document, translate that
via the API, and re-insert the original media into the original file. Please note that this
requires a bit of additional (temporary) disk space, we recommend at least 2x the file size
of the document to be translated.
To use document minification, simply pass the option to the TranslateDocumentAsync
function:
await client.TranslateDocumentAsync(
inFile, outFile, "EN", "DE", new DocumentTranslateOptions { EnableDocumentMinification = true }
);
In order to use document minification with the lower-level TranslateDocumentUploadAsync
,
TranslateDocumentWaitUntilDoneAsync
and TranslateDocumentDownloadAsync
methods as well as other details,
see the DocumentMinifier
class.
Currently supported document types for minification:
pptx
docx
Currently supported media types for minification:png
jpg
jpeg
emf
bmp
tiff
wdp
svg
gif
mp4
asf
avi
m4v
mpg
mpeg
wmv
mov
aiff
au
mid
midi
mp3
m4a
wav
wma
Glossaries
Glossaries allow you to customize your translations using defined terms. Multiple glossaries can be stored with your account, each with a user-specified name and a uniquely-assigned ID.
Creating a glossary
You can create a glossary with your desired terms and name using
CreateGlossaryAsync()
. Each glossary applies to a single source-target language
pair. Note: Glossaries are only supported for some language pairs, see
Listing available glossary languages
for more information. The entries should be specified as a Dictionary
.
If successful, the glossary is created and stored with your DeepL account, and
a GlossaryInfo
object is returned including the ID, name, languages and entry
count.
// Create an English to German glossary with two terms:
var entriesDictionary = new Dictionary<string, string>{{"artist", "Maler"}, {"prize", "Gewinn"}};
var glossaryEnToDe = await client.CreateGlossaryAsync(
"My glossary", "EN", "DE",
new GlossaryEntries(entriesDictionary));
Console.WriteLine($"Created {glossaryEnToDe.Name}' ({glossaryEnToDe.GlossaryId}) " +
$"{glossaryEnToDe.SourceLanguageCode}->{glossaryEnToDe.TargetLanguageCode} " +
$"containing {glossaryEnToDe.EntryCount} entries"
);
// Example: Created 'My glossary' (559192ed-8e23-...) en->de containing 2 entries
You can also upload a glossary downloaded from the DeepL website using
CreateGlossaryFromCsvAsync()
. Instead of supplying the entries as a dictionary,
specify the CSV data as a Stream
containing file content:
var csvStream = File.OpenRead("myGlossary.csv");
var csvGlossary = await client.CreateGlossaryFromCsvAsync("My CSV glossary", "EN", "DE", csvStream);
The API documentation explains the expected CSV format in detail.
Getting, listing and deleting stored glossaries
Functions to get, list, and delete stored glossaries are also provided:
GetGlossaryAsync()
takes a glossary ID and returns aGlossaryInfo
object for a stored glossary, or raises an exception if no such glossary is found.ListGlossariesAsync()
returns aList
ofGlossaryInfo
objects corresponding to all of your stored glossaries.DeleteGlossaryAsync()
takes a glossary ID orGlossaryInfo
object and deletes the stored glossary from the server, or raises an exception if no such glossary is found.
// Retrieve a stored glossary using the ID
var myGlossary = await client.GetGlossaryAsync("559192ed-8e23-...");
// Find and delete glossaries named 'Old glossary'
var glossaries = await client.ListGlossariesAsync();
foreach (var glossaryInfo in glossaries) {
if (glossaryInfo.Name == "Old glossary")
await client.DeleteGlossaryAsync(glossaryInfo);
}
Listing entries in a stored glossary
The GlossaryInfo
object does not contain the glossary entries, but instead
only the number of entries in the EntryCount
property.
To list the entries contained within a stored glossary, use
GetGlossaryEntriesAsync()
providing either the GlossaryInfo
object or glossary ID:
var entries = await client.GetGlossaryEntriesAsync(myGlossary);
foreach (KeyValuePair<string, string> entry in entries.ToDictionary()) {
Console.WriteLine($"{entry.Key}: {entry.Value}");
}
// prints:
// artist: Maler
// prize: Gewinn
Using a stored glossary
You can use a stored glossary for text (or document) translation by setting the
TextTranslationOptions
(or DocumentTranslationOptions
) GlossaryId
property
to the glossary ID. You must also specify the source_lang
argument (it is
required when using a glossary):
var resultWithGlossary = await client.TranslateTextAsync(
"The artist was awarded a prize.",
"EN",
"DE",
new TextTranslateOptions { GlossaryId = glossaryEnToDe.GlossaryId });
// resultWithGlossary.Text == "Der Maler wurde mit einem Gewinn ausgezeichnet."
// Without using a glossary: "Der Künstler wurde mit einem Preis ausgezeichnet."
Check account usage
var usage = await client.GetUsageAsync();
if (usage.AnyLimitReached) {
Console.WriteLine("Translation limit exceeded.");
} else if (usage.Character != null) {
Console.WriteLine($"Character usage: {usage.Character}");
} else {
Console.WriteLine($"{usage}");
}
Listing available languages
You can request the list of languages supported by DeepL for text and documents
using the GetSourceLanguagesAsync()
and GetTargetLanguagesAsync()
functions.
They both return a list of Language
objects.
The Name
property gives the name of the language in English, and the Code
property gives the language code. The SupportsFormality
property only appears
for target languages, and indicates whether the target language supports the
optional Formality
parameter.
// Source and target languages
var sourceLanguages = await client.GetSourceLanguagesAsync();
foreach (var lang in sourceLanguages) {
Console.WriteLine($"{lang.Name} ({lang.Code})"); // Example: "English (EN)"
}
var targetLanguages = await client.GetTargetLanguagesAsync();
foreach (var lang in targetLanguages) {
if (lang.SupportsFormality ?? false) {
Console.WriteLine($"{lang.Name} ({lang.Code}) supports formality");
// Example: "German (DE) supports formality"
}
}
Listing available glossary languages
Glossaries are supported for a subset of language pairs. To retrieve those
languages use the GetGlossaryLanguagesAsync()
function, which returns an array
of GlossaryLanguagePair
objects. Use the SourceLanguage
and
TargetLanguage
properties to check the pair of language codes supported.
// Glossary languages
var glossaryLanguages = await client.GetGlossaryLanguagesAsync();
foreach (var languagePair in glossaryLanguages) {
Console.WriteLine($"{languagePair.SourceLanguage} to {languagePair.TargetLanguage}");
// Example: "EN to DE", "DE to EN", etc.
}
You can also find the list of supported glossary language pairs in the API documentation.
Note that glossaries work for all target regional-variants: a glossary for the
target language English ("EN"
) supports translations to both American English
("EN-US"
) and British English ("EN-GB"
).
Exceptions
All library functions may raise DeepLException
or one of its subclasses. If
invalid arguments are provided, they may raise the standard exceptions
ArgumentException
.
Writing a Plugin
If you use this library in an application, please identify the application with
DeepLClientOptions.appInfo
, which needs the name and version of the app:
var options = new DeepLClientOptions {
appInfo = new AppInfo { AppName = "my-dotnet-test-app", AppVersion = "1.2.3"}
};
var client = new DeepLClient(AuthKey, options);
This information is passed along when the library makes calls to the DeepL API.
Both name and version are required. Please note that setting the User-Agent
header
via DeepLClientOptions.Headers
will override this setting, if you need to use this,
please manually identify your Application in the User-Agent
header.
Configuration
The DeepLClient
constructor accepts DeepLClientOptions
as a second argument,
for example:
var options = new DeepLClientOptions {
MaximumNetworkRetries = 5,
PerRetryConnectionTimeout = TimeSpan.FromSeconds(10),
};
var client = new DeepLClient(authKey, options);
See the DeepLClientOptions
class for details about the available options.
Proxy configuration
To use the library with a proxy, override the ClientFactory
with a function returning a custom HttpClient
:
var proxyUrl = "http://localhost:3001";
var handler = new System.Net.Http.HttpClientHandler {
Proxy = new System.Net.WebProxy(proxyUrl), UseProxy = true,
};
var options = new DeepLClientOptions {
ClientFactory = () => new HttpClientAndDisposeFlag {
HttpClient = new HttpClient(handler), DisposeClient = true,
}
};
var client = new DeepLClient(authKey, options);
Anonymous platform information
By default, we send some basic information about the platform the client library is running
on with each request, see here for an explanation.
This data is completely anonymous and only used to improve our product, not track any
individual users. If you do not wish to send this data, you can opt-out when creating
your DeepLClient
object by setting the sendPlatformInfo
flag in the
DeepLClientOptions
to false
like so:
var options = new DeepLClientOptions { sendPlatformInfo = false };
var client = new DeepLClient(authKey, options);
Issues
If you experience problems using the library, or would like to request a new feature, please open an issue.
Development
We welcome Pull Requests, please read the contributing guidelines.
Tests
Execute the tests using dotnet test
. The tests communicate with the DeepL API using the auth key defined by the
DEEPL_AUTH_KEY
environment variable.
Be aware that the tests make DeepL API requests that contribute toward your API usage.
The test suite may instead be configured to communicate with the mock-server provided by
deepl-mock. Although most test cases work for either, some test cases work
only with the DeepL API or the mock-server and will be otherwise skipped. The test cases that require the mock-server
trigger server errors and test the client error-handling. To execute the tests using deepl-mock, run it in another
terminal while executing the tests. Execute the tests using dotnet test
with the DEEPL_MOCK_SERVER_PORT
and
DEEPL_SERVER_URL
environment variables defined referring to the mock-server.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Http.Polly (>= 5.0.1)
- System.Text.Json (>= 5.0.2)
-
net5.0
- Microsoft.Extensions.Http.Polly (>= 5.0.1)
- System.Text.Json (>= 5.0.2)
NuGet packages (9)
Showing the top 5 NuGet packages that depend on DeepL.net:
Package | Downloads |
---|---|
Volo.Abp.Cli.Core
Package Description |
|
Jumoo.TranslationManager.Connector.DeepL
DeepL Translation Api Connector for Translation Manager for Umbraco |
|
MO.Shared.Service
Package Description |
|
AutoDictionaries
Auto dictionaries is a Umbraco package that finds static content in templates and replaces them with dictionary items. |
|
MO.Shared.Api
Package Description |
GitHub repositories (5)
Showing the top 5 popular GitHub repositories that depend on DeepL.net:
Repository | Stars |
---|---|
abpframework/abp
Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
|
|
VRCWizard/TTS-Voice-Wizard
Speech to Text to Speech. Song now playing. Sends text as OSC messages to VRChat to display on avatar. (STTTS) (Speech to TTS) (VRC STT System) (VTuber TTS)
|
|
lingarr-translate/lingarr
Lingarr is an application that supports both local and SaaS translation services to translate subtitle files into a specified target language. With automated translation options, Lingarr simplifies translating subtitles.
|
|
drizzle-mizzle/CharacterAI-Discord-Bot
CharacterAI for your Discord server
|
|
signumsoftware/framework
Open Source framework for writing data-centric applications using the latest versions of .Net Core, C# (not-nullable), ASP.NET Web API, Typescript (strict), React, D3 and Sql Server or PostgreeSQL
|
Version | Downloads | Last updated |
---|---|---|
1.13.0 | 115 | 1/28/2025 |
1.12.0 | 3,822 | 1/9/2025 |
1.11.0 | 16,763 | 11/15/2024 |
1.10.0 | 39,300 | 9/17/2024 |
1.9.0 | 159,536 | 3/15/2024 |
1.8.0 | 120,247 | 11/3/2023 |
1.7.1 | 110,442 | 4/17/2023 |
1.7.0 | 5,769 | 3/31/2023 |
1.6.0 | 57,618 | 1/26/2023 |
1.5.1 | 461 | 1/25/2023 |
1.5.0 | 172,281 | 9/30/2022 |
1.4.0 | 14,952 | 9/9/2022 |
1.3.0 | 2,631 | 8/2/2022 |
1.2.1 | 443 | 8/2/2022 |
1.2.0 | 21,092 | 5/18/2022 |
1.1.0 | 8,230 | 4/13/2022 |
1.0.5 | 796 | 4/12/2022 |
1.0.4 | 15,460 | 1/27/2022 |
1.0.3 | 1,859 | 1/19/2022 |
1.0.2 | 1,583 | 1/3/2022 |
1.0.1 | 2,603 | 12/7/2021 |
1.0.0 | 652 | 11/18/2021 |
0.1.0 | 936 | 11/5/2021 |
Release notes can be found at https://github.com/DeepLcom/deepl-dotnet/blob/main/CHANGELOG.md