Document Translation, Custom Translator and Adaptive Translation
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. See the section bibliography for the reference material consulted while preparing these pages. |
This page targets Azure CLI 2.90.0 and the Document Translation REST API 2026-03-01, with the client libraries
azure-ai-translation-document 2.0.0 (Python), Azure.AI.Translation.Document 3.0.0 (.NET),
com.azure:azure-ai-translation-document 2.0.1 (Java) and @azure-rest/ai-translation-document 1.0.0 (JavaScript),
checked on 2026-10-06.
Text translation handles strings. Document translation handles whole files (Word, PowerPoint, Excel, PDF, HTML, Markdown and more) and keeps their layout: fonts, tables, headers and images stay where they were. It also covers how you customize translations with Custom Translator (NMT) and adaptive custom translation (LLM).
Asynchronous batch translation
Batch translation reads every document in a source Blob container (or a single blob, or a prefix filter) and writes translated copies to one target container per language.
-
Access: give the Translator resource’s system-assigned managed identity
Storage Blob Data Readeron the source andStorage Blob Data Contributoron the targets, and pass plain container URLs. Alternatively pass SAS URLs (read/list on source, write/list on target). Managed identity is preferred: no tokens to expire. -
Glossaries: a CSV, TSV or XLF file of term pairs, applied to every document in the job (for example series names and character names that must not be translated).
-
Limits: 40 MB per document, 1,000 files per batch, 250 MB per batch total. Results are written to Blob, so nothing is kept in the service.
-
Images and scans: with
translateTextWithinImagethe service translates text inside images embedded in DOCX and PPTX files (billed as image scans). Scanned PDFs are OCRed and translated.
TOKEN=$(az account get-access-token --resource https://cognitiveservices.azure.com --query accessToken -o tsv)
curl -s -i -X POST \
"https://$FOUNDRY.cognitiveservices.azure.com/translator/document/batches?api-version=2026-03-01" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"inputs": [{
"source": {"sourceUrl": "https://stbookshelf.blob.core.windows.net/press-kits", "language": "en"},
"targets": [
{"targetUrl": "https://stbookshelf.blob.core.windows.net/press-kits-es", "language": "es",
"glossaries": [{"glossaryUrl": "https://stbookshelf.blob.core.windows.net/glossaries/series-es.tsv", "format": "tsv"}]},
{"targetUrl": "https://stbookshelf.blob.core.windows.net/press-kits-fr", "language": "fr"}
]
}],
"options": {"translateTextWithinImage": true}
}'
# Poll the Operation-Location header URL until "status" is "Succeeded"
Source: Start batch translation
from azure.ai.translation.document import DocumentTranslationClient
from azure.ai.translation.document.models import TranslationGlossary
from azure.identity import DefaultAzureCredential
client = DocumentTranslationClient(
"https://foundry-bookshelf.cognitiveservices.azure.com/", DefaultAzureCredential()
)
poller = client.begin_translation(
"https://stbookshelf.blob.core.windows.net/press-kits",
"https://stbookshelf.blob.core.windows.net/press-kits-es",
"es",
glossaries=[TranslationGlossary(
"https://stbookshelf.blob.core.windows.net/glossaries/series-es.tsv", file_format="tsv")],
)
for doc in poller.result():
print(doc.status, doc.translated_document_url)
using Azure.AI.Translation.Document;
using Azure.Identity;
var client = new DocumentTranslationClient(
new Uri("https://foundry-bookshelf.cognitiveservices.azure.com/"), new DefaultAzureCredential());
var input = new DocumentTranslationInput(
new Uri("https://stbookshelf.blob.core.windows.net/press-kits"),
new Uri("https://stbookshelf.blob.core.windows.net/press-kits-fr"),
"fr");
DocumentTranslationOperation operation = await client.StartTranslationAsync(input);
await operation.WaitForCompletionAsync();
await foreach (DocumentStatusResult doc in operation.Value)
Console.WriteLine($"{doc.Status} {doc.TranslatedDocumentUri}");
import com.azure.ai.translation.document.DocumentTranslationClient;
import com.azure.ai.translation.document.DocumentTranslationClientBuilder;
import com.azure.ai.translation.document.models.*;
import com.azure.identity.DefaultAzureCredentialBuilder;
import java.util.List;
DocumentTranslationClient client = new DocumentTranslationClientBuilder()
.endpoint("https://foundry-bookshelf.cognitiveservices.azure.com/")
.credential(new DefaultAzureCredentialBuilder().build())
.buildClient();
TranslationSource source = new TranslationSource("https://stbookshelf.blob.core.windows.net/press-kits");
TranslationTarget target = new TranslationTarget("https://stbookshelf.blob.core.windows.net/press-kits-de", "de");
BatchRequest batch = new BatchRequest(source, List.of(target));
TranslationStatus status = client.beginTranslation(
new StartTranslationDetails(List.of(batch))).getFinalResult();
System.out.println(status.getStatus());
Synchronous single-document translation
For one small document that a user waits for (for example a contract preview), call the synchronous endpoint. It returns the translated file in the response body, with no Blob storage involved:
curl -s -X POST \
"https://$FOUNDRY.cognitiveservices.azure.com/translator/document:translate?targetLanguage=es&api-version=2026-03-01" \
-H "Authorization: Bearer $TOKEN" \
-F "document=@sample-chapter.docx;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document" \
-F "glossary=@series-es.tsv;type=text/tab-separated-values" \
-o sample-chapter.es.docx
Source: Use document translation APIs
Synchronous translation has smaller limits than batch (one document, around 10 MB). Check the service limits page.
Custom Translator
Custom Translator (https://portal.customtranslator.azure.ai) trains an NMT model on your own data:
-
Create a workspace connected to the Translator resource, and a project for a language pair and domain.
-
Upload parallel documents (aligned source and target sentences, at least 10,000 pairs for good results) and optionally phrase and sentence dictionaries that force exact translations.
-
Train, review the BLEU score against the baseline, and publish the model to one or more regions.
-
Call text or document translation with the model’s
categoryID.
curl -s -X POST \
"https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=es&category=$CATEGORY_ID" \
-H "Ocp-Apim-Subscription-Key: $TRANSLATOR_KEY" -H "Ocp-Apim-Subscription-Region: eastus2" \
-H "Content-Type: application/json" -d '[{"Text":"The Archivist returns in book three."}]'
Source: Custom Translator overview
Adaptive custom translation
Adaptive custom translation is the LLM-era alternative. Instead of training a model, you give the LLM examples: a handful of reference pairs in each request, or a dataset index of translation pairs uploaded once in the Foundry portal and referenced by ID. The model follows your terminology and style without a training run. It works with LLM targets in text translation, and with document translation that uses an LLM deployment.
Source: Adaptive custom translation
Containers
Translator text and document translation containers run on your own infrastructure. They are gated: you request
access with an application form, and they must be billed against a single-service TextTranslation resource,
optionally with a commitment tier for disconnected use. See
Pricing, Quotas, Containers and Monitoring.
Provisioning
In the Azure portal
-
Use the Foundry resource
foundry-bookshelfand turn on its System assigned managed identity. -
On storage account
stbookshelf, open Access control (IAM) and assignStorage Blob Data Reader(source) andStorage Blob Data Contributor(targets) to the managed identity offoundry-bookshelf. -
Create the containers
press-kits,press-kits-es,press-kits-fr,press-kits-deandglossaries. -
In the Foundry portal, Playgrounds → Translator playground → Document translation translates a single file interactively.
With the Azure CLI
PRINCIPAL=$(az cognitiveservices account show --name "$FOUNDRY" --resource-group "$RG" --query identity.principalId -o tsv)
SCOPE=$(az storage account show --name stbookshelf --resource-group "$RG" --query id -o tsv)
az role assignment create --assignee-object-id "$PRINCIPAL" --assignee-principal-type ServicePrincipal \
--role "Storage Blob Data Contributor" --scope "$SCOPE"
for c in press-kits press-kits-es press-kits-fr press-kits-de glossaries; do
az storage container create --account-name stbookshelf --name "$c" --auth-mode login
done
Use cases
| Scenario | Feature | Why this feature | Example input → output |
|---|---|---|---|
Bookshelf: translate publisher press kits and sample chapters |
Batch translation with a glossary of series and character names |
Layout must survive; names must not be translated. |
|
Legal and contract translation |
Synchronous single-document translation |
Preserves numbering, tables and signatures; reviewer gets the file at once. |
Contract.pdf → Contrato.pdf |
Manuals in a technical domain |
Custom Translator |
Consistent terminology across thousands of pages. |
Service manual DOCX → localized DOCX with approved terms |
Slide decks with screenshots |
|
Text inside images is translated too. |
Sales deck PPTX → Japanese PPTX |
When not to use it
-
For short strings, call text translation (Text Translation with Translator); it is cheaper and synchronous.
-
When the goal is a summary in another language, not a faithful translation, prompt a Foundry Model directly. See Choosing a Foundry Tool (or a Foundry Model).
Clean up
for c in press-kits press-kits-es press-kits-fr press-kits-de glossaries; do
az storage container delete --account-name stbookshelf --name "$c" --auth-mode login
done
Related pages
-
Text Translation with Translator covers the
2026-06-06text API and LLM targets. -
Blob Storage covers
stbookshelf, containers and SAS. -
Identity and Access covers managed identities and role assignments.