API Version: 2025-10-01-preview
Scope: Text Translation (/translate) only — transliterate excluded
Why this guide exists: The official Microsoft documentation has significant gaps for the LLM-based translation workflow. It tells you to use a Foundry resource but only shows the global endpoint, which doesn't authenticate with Foundry keys. The resource-specific endpoint path (
/translator/text/translate) is not documented in the preview API pages. This guide fills those gaps with tested, working examples.Prefer Python over curl? See
translator.py— a ready-to-run Python script with all 16 examples below as callable functions, an interactive menu, and automatic NMT/LLM engine detection from the response.
- Critical Setup Guide (Read This First)
- Endpoints
- Authentication Methods
- Request Headers
- Query Parameters
- Request Body — inputs Fields
- Request Body — targets Fields
- Response Body Structure
- How to Tell Which Engine Handled Your Request
- Response Headers
- Service Limits
- Migration from v3.0 — Breaking Changes
- Example curl Commands
- Python Script (translator.py)
- Endpoint + Key Compatibility Matrix
- Troubleshooting and Gotchas
- Notes
If you want to use LLM-based translation (GPT-4o / GPT-4o-mini) through the Translator API, you need to get several things right that the docs don't clearly explain. Here's the short version:
-
An Azure AI Foundry resource (Kind:
AIServices) — not a standalone Azure OpenAI resource or a standalone Translator resource.- Check in Azure Portal: your resource > Overview > the "Kind" field must say
AIServices - If it says
OpenAI, it won't work — you need to create a Foundry multi-service resource instead
- Check in Azure Portal: your resource > Overview > the "Kind" field must say
-
A GPT-4o or GPT-4o-mini model deployed inside that Foundry resource
- Deploy via: Azure AI Foundry > your project > Model deployments
- Note the exact deployment name (e.g.
gpt-4o-newtest) — this is what you pass asdeploymentName, not the model name
-
The resource-specific endpoint — you cannot use the global
api.cognitive.microsofttranslator.comendpoint for LLM translation- Format:
https://<your-resource>.cognitiveservices.azure.com/translator/text/translate?api-version=2025-10-01-preview - The
/translator/text/translatepath is not documented in the preview API docs but is required
- Format:
-
The Foundry resource's key — found in Azure Portal > your Foundry resource > Keys and Endpoint
| What you might try | What happens | Why |
|---|---|---|
| Global endpoint + Foundry key | 401 Unauthorized |
Global endpoint doesn't accept Foundry/AIServices keys |
Global endpoint + Translator key + deploymentName |
400 "deployment not found" |
Standalone Translator resource can't see Foundry deployments |
Standalone Azure OpenAI resource (Kind: OpenAI) |
400 "deployment not found" |
Translator API only discovers deployments on AIServices/Foundry resources |
| Setup | NMT | LLM |
|---|---|---|
| Resource-specific endpoint + Foundry key | Works | Works |
| Global endpoint + Translator key (no deploymentName) | Works | N/A — NMT only |
Resource-specific (required for AIServices/Foundry resources):
https://<your-resource>.cognitiveservices.azure.com/translator/text/translate?api-version=2025-10-01-preview
Global (works for Neural Machine Translations only + region header):
https://api.cognitive.microsofttranslator.com/translate?api-version=2025-10-01-preview
Regional data zones (NMT only, restricts data processing to specific geography):
Americas: https://api-nam.cognitive.microsofttranslator.com/translate?api-version=2025-10-01-preview
Europe: https://api-eur.cognitive.microsofttranslator.com/translate?api-version=2025-10-01-preview
Asia Pacific: https://api-apc.cognitive.microsofttranslator.com/translate?api-version=2025-10-01-preview
| Header | Value | Required? |
|---|---|---|
Ocp-Apim-Subscription-Key |
Your resource key | Yes |
Ocp-Apim-Subscription-Region |
Your resource region (e.g. eastus) |
Only for global endpoint with regional/multi-service resources |
Region header is not needed when using the resource-specific endpoint.
Step 1: Exchange your key for a token:
- Global:
POST https://api.cognitive.microsoft.com/sts/v1.0/issueToken - Regional:
POST https://<region>.api.cognitive.microsoft.com/sts/v1.0/issueToken - Header:
Ocp-Apim-Subscription-Key: <key>
Step 2: Use the token:
- Header:
Authorization: Bearer <token>
Token is valid for 10 minutes. Refresh every ~8 minutes for long-running operations.
Global endpoint:
| Header | Value |
|---|---|
Authorization |
Bearer <entra-token> |
Ocp-Apim-ResourceId |
/subscriptions/<subId>/resourceGroups/<rgName>/providers/Microsoft.CognitiveServices/accounts/<resourceName>/ |
Ocp-Apim-Subscription-Region |
Your region (optional) |
Resource-specific endpoint:
| Header | Value |
|---|---|
Authorization |
Bearer <entra-token> |
Requires
Cognitive Services Userrole assigned on the resource.
Same headers as Entra ID, but the token is obtained from the managed identity endpoint instead of Entra ID.
- Must use resource-specific (custom domain) endpoint
- Cannot use global endpoint or bearer tokens
- Header:
Ocp-Apim-Subscription-Key: <key> - Warning: LLM-based translation is NOT available with private endpoints
| Header | Required? | Description |
|---|---|---|
Content-Type |
Yes | application/json or application/json; charset=UTF-8 |
Ocp-Apim-Subscription-Key |
Yes* | Your resource key (*unless using Bearer/Entra/MI auth) |
Ocp-Apim-Subscription-Region |
Conditional | Required for global endpoint with regional/multi-service resources |
Ocp-Apim-ResourceId |
Conditional | Required for Entra ID / Managed Identity auth on global endpoint |
Authorization |
Conditional | Bearer <token> — for token/Entra/MI auth |
X-ClientTraceId |
Optional | Client-generated GUID to trace the request |
Content-Length |
Optional | Length of request body |
| Parameter | Required | Value |
|---|---|---|
api-version |
Yes | 2025-10-01-preview |
| Field | Type | Required | Description |
|---|---|---|---|
inputs[].text |
string | Yes | Source text to translate |
inputs[].language |
string | No | Source language code (auto-detected if omitted) |
inputs[].script |
string | No | Script of the source text (e.g. Latn) |
inputs[].textType |
string | No | plain (default) or html |
inputs[].targets |
array | Yes | Array of target language objects |
| Field | Type | Required | Description |
|---|---|---|---|
targets[].language |
string | Yes | Target language code (e.g. es, de, fr) |
targets[].script |
string | No | Target script for transliteration |
targets[].deploymentName |
string | No | general (default, NMT) | your LLM deployment name | categoryID (custom NMT) |
targets[].tone |
string | No | formal | informal | neutral (LLM only) |
targets[].gender |
string | No | female | male | neutral (LLM only) |
targets[].profanityAction |
string | No | NoAction (default) | Marked | Deleted |
targets[].profanityMarker |
string | No | Asterisk (default) | Tag (only when profanityAction=Marked) |
targets[].allowFallback |
boolean | No | true (default) | false — fall back to NMT if LLM unavailable |
targets[].referenceTextPairs |
array | No | Up to 5 source/target pairs for adaptive translation (LLM only) |
targets[].referenceTextPairs[].source |
string | — | Source text in reference pair |
targets[].referenceTextPairs[].target |
string | — | Target text in reference pair |
targets[].adaptiveDatasetId |
string | No | Reference dataset ID (alternative to referenceTextPairs) |
The response fields tell you whether NMT or LLM processed the translation. These fields are mutually exclusive — you'll see one set or the other, never both.
| You see in response... | Engine used | Billing |
|---|---|---|
"sourceCharacters": 19 |
NMT | Per character |
"instructionTokens", "sourceTokens", "responseTokens", "targetTokens" |
LLM (GPT-4o) | Per token |
If you requested a
deploymentNamebut seesourceCharactersin the response, your request fell back to NMT (e.g.allowFallbackwastrueand the LLM was unavailable).
NMT response example:
{
"value": [
{
"translations": [
{
"language": "es",
"text": "Hola, \u00bfqu\u00e9 tal?",
"sourceCharacters": 19
}
]
}
]
}LLM response example:
{
"value": [
{
"translations": [
{
"language": "es",
"text": "El doctor est\u00e1 disponible el pr\u00f3ximo lunes. \u00bfQuieres programar una cita?",
"instructionTokens": 298,
"sourceTokens": 14,
"responseTokens": 10,
"targetTokens": 15
}
]
}
]
}Auto-detected language (appears when inputs[].language is omitted):
{
"value": [
{
"detectedLanguage": { "language": "fr", "score": 1.0 },
"translations": [ "..." ]
}
]
}| Field | Meaning |
|---|---|
instructionTokens |
System prompt tokens — the internal prompt the Translator service sends to GPT-4o (you don't control this) |
sourceTokens |
Your input text tokenized |
responseTokens |
The model's raw response tokens |
targetTokens |
The translation output tokens |
| Header | Description |
|---|---|
X-requestid |
Service-generated GUID for troubleshooting |
X-mt-system |
Custom or Team (indicates which system was used) |
X-metered-usage |
Number of characters charged (NMT) |
sourceTokensCharged |
Source tokens billed (LLM) |
targetTokensCharged |
Target tokens billed (LLM) |
| NMT | LLM (GPT-4o / GPT-4o-mini) | |
|---|---|---|
| Free tier | Yes — F0: 2M chars/month free | No — no free tier for LLM translation |
| Paid tier | S1 (pay-as-you-go) + commitment tiers for volume | Standard pay-as-you-go, Provisioned (PTU), or Batch (50% discount) |
| Billing unit | Per character | Per token (input + output) |
| Max array elements | 1,000 | 50 |
| Max chars per element | 50,000 | 5,000 |
| Max referenceTextPairs | N/A | 5 |
| Pricing page | Azure Translator Pricing | Azure OpenAI Pricing |
Note: S2, S3, and S4 Translator tiers have been deprecated by Microsoft. Only F0 (free) and S1 (paid) remain active.
| What changed | v3.0 (old) | 2025-10-01-preview (new) |
|---|---|---|
| API version | api-version=3.0 |
api-version=2025-10-01-preview |
| Target language | ?to=es (query param) |
targets[].language (in body) |
| Source language | ?from=en (query param) |
inputs[].language (in body) |
| Request body wrapper | [{"Text":"..."}] |
{"inputs":[{"text":"..."}]} |
| Response body wrapper | [{"translations":[...]}] |
{"value":[{"translations":[...]}]} |
| Text field casing | "Text" (capital T) |
"text" (lowercase t) |
Removed endpoints (no longer exist in preview):
/breaksentence— Use sentence delimiters or an NLP library/detect— Use Azure AI Language detection API/dictionary/lookup— Removed/dictionary/examples— Removed
New features (not in v3.0):
- LLM model selection via
deploymentName(GPT-4o, GPT-4o-mini) - Tone control (
formal/informal/neutral) - Gender control (
female/male/neutral) - Adaptive custom translation (
referenceTextPairs/adaptiveDatasetId) - Token-based billing for LLM responses
ENDPOINT="https://newgpt-4o-project-resource-llm.cognitiveservices.azure.com/translator/text/translate?api-version=2025-10-01-preview"
KEY="<your-foundry-resource-key>"curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"Hello, how are you?","language":"en","targets":[{"language":"es"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"Doctor is available next Monday. Do you want to schedule an appointment?","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"Doctor is available next Monday. Do you want to schedule an appointment?","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest","tone":"formal","gender":"female"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"What the hell is going on here?","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest","profanityAction":"NoAction"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"What the hell is going on here?","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest","profanityAction":"Marked","profanityMarker":"Asterisk"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"What the hell is going on here?","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest","profanityAction":"Marked","profanityMarker":"Tag"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"What the hell is going on here?","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest","profanityAction":"Deleted"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"Bonjour, comment allez-vous?","targets":[{"language":"en","deploymentName":"gpt-4o-newtest"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"The meeting is at 3pm tomorrow.","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest"},{"language":"fr","deploymentName":"gpt-4o-newtest"},{"language":"de","deploymentName":"gpt-4o-newtest"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"Good morning.","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest"}]},{"text":"See you later.","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest"}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"<p>Hello <b>world</b>, how are you?</p>","language":"en","textType":"html","targets":[{"language":"es","deploymentName":"gpt-4o-newtest"}]}]}'Provide up to 5 example source/target pairs to guide translation style:
curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"Click Save to continue.","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest","referenceTextPairs":[{"source":"Click OK to proceed.","target":"Pulse Aceptar para continuar."},{"source":"Click Cancel to go back.","target":"Pulse Cancelar para volver atr\u00e1s."}]}]}]}'curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"Hey, what the hell? The doctor said your appointment is next Monday at 10am. Do not forget it!","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest","tone":"formal","gender":"female","profanityAction":"NoAction","allowFallback":true,"referenceTextPairs":[{"source":"Do not forget your appointment.","target":"No olvide su cita m\u00e9dica."}]}]}]}'NMT version:
curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"The quick brown fox jumps over the lazy dog.","language":"en","targets":[{"language":"es"}]}]}'LLM version (same text):
curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d '{"inputs":[{"text":"The quick brown fox jumps over the lazy dog.","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest"}]}]}'# Step 1: Get token (valid 10 min, refresh every ~8 min)
curl -X POST "https://eastus.api.cognitive.microsoft.com/sts/v1.0/issueToken" \
-H "Ocp-Apim-Subscription-Key: $KEY" \
-d ""
# Step 2: Use the token (replace <TOKEN> with response from step 1)
curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <TOKEN>" \
-d '{"inputs":[{"text":"Hello","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest"}]}]}'# Obtain token via: az account get-access-token --resource https://cognitiveservices.azure.com
curl -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <ENTRA_TOKEN>" \
-d '{"inputs":[{"text":"Hello","language":"en","targets":[{"language":"es","deploymentName":"gpt-4o-newtest"}]}]}'If you prefer Python over curl, translator.py provides all 16 examples above as ready-to-run functions.
pip install requests python-dotenvCreate a .env file (or copy .env.example):
AZURE_TRANSLATOR_ENDPOINT="https://<your-resource>.cognitiveservices.azure.com"
AZURE_TRANSLATOR_KEY="<your-foundry-resource-key>"
AZURE_DEPLOYMENT_NAME="gpt-4o-newtest"
AZURE_LOCATION="eastus2"python translator.py # Interactive menu — pick any example
python translator.py all # Run all 16 examples sequentially
python translator.py 3 # Run a specific example (e.g. #3: Tone + Gender)| # | Example | Engine |
|---|---|---|
| 1 | Basic NMT translation | NMT |
| 2 | LLM via deploymentName |
LLM |
| 3 | Tone + Gender | LLM |
| 4–7 | Profanity handling (NoAction, Asterisk, Tag, Deleted) | LLM |
| 8 | Auto-detect source language | LLM |
| 9 | Multi-target (one text → multiple languages) | LLM |
| 10 | Multi-input (batch texts in one call) | LLM |
| 11 | HTML text type | LLM |
| 12 | Adaptive translation (reference pairs) | LLM |
| 13 | Kitchen sink (all options combined) | LLM |
| 14 | NMT vs LLM side-by-side comparison | Both |
| 15 | Bearer token authentication | LLM |
| 16 | Mixed NMT + LLM targets in one call | Both |
The script auto-detects which engine handled each response — if the response contains sourceCharacters it was NMT, if it contains instructionTokens/sourceTokens/responseTokens/targetTokens it was LLM.
You can also
import translatorand call the functions directly (e.g.translator.translate(...)) to integrate into your own code.
Confirmed via testing:
| Scenario | Result |
|---|---|
| Resource-specific endpoint + Foundry key + NMT | Works (sourceCharacters in response) |
| Resource-specific endpoint + Foundry key + LLM | Works (token fields in response) |
| Global endpoint + Foundry key + NMT | 401 Unauthorized |
| Global endpoint + Foundry key + LLM | 401 Unauthorized |
| Global endpoint + Translator key + NMT | Works (sourceCharacters in response) |
| Global endpoint + Translator key + LLM | 400 "deployment not found" |
Conclusion: For LLM translation, you must use the resource-specific endpoint with the Foundry (AIServices) resource key. The global endpoint cannot see Foundry deployments. The Foundry key on the resource-specific endpoint handles both NMT and LLM. The standalone Translator key on the global endpoint is NMT-only.
This is the most common error. It means the Translator API can't find your LLM deployment. Check:
-
Are you using the resource-specific endpoint? The global endpoint (
api.cognitive.microsofttranslator.com) cannot discover Foundry deployments. Usehttps://<your-resource>.cognitiveservices.azure.com/translator/text/translateinstead. -
Is your resource Kind
AIServices? Go to Azure Portal > your resource > Overview. The Kind must beAIServices(Foundry multi-service). If it'sOpenAI(standalone Azure OpenAI), the Translator API can't see its deployments. -
Does the deployment name match exactly? The
deploymentNamein the API call must match the deployment name in your Foundry resource exactly -- not the model name. If you deployed GPT-4o and named itmy-gpt4o, usemy-gpt4o, notgpt-4o. -
Is the deployment in the same resource as the key you're using? If you have multiple resources, make sure the key belongs to the resource that contains the deployment.
- You're using a Foundry/AIServices key on the global endpoint. The global endpoint doesn't accept those keys.
- Switch to the resource-specific endpoint:
https://<your-resource>.cognitiveservices.azure.com/translator/text/translate?api-version=2025-10-01-preview
The preview API docs only document the global endpoint path (/translate). When using a resource-specific endpoint with an AIServices/Foundry resource, Azure Cognitive Services namespaces APIs by service. The Translator service path becomes /translator/text/translate. This pattern is documented in the older GA Translator v3.0 docs but is missing from the preview API documentation.
- For NMT only via global endpoint: Use the Translator resource key +
Ocp-Apim-Subscription-Regionheader - For LLM (or both NMT and LLM): Use the Foundry resource key + resource-specific endpoint
- You cannot mix them (Translator key on Foundry endpoint or vice versa)
- Linux/macOS: Use
curlwith\for line continuation - PowerShell: Use
curl.exewith`(backtick) for line continuation - Windows cmd: Use
curlwith^for line continuation
- LLM-only features:
tone,gender,referenceTextPairs,adaptiveDatasetId - LLM billing: token-based (
instructionTokens+sourceTokens+targetTokens) - NMT billing: character-based (
sourceCharacters) - Max 50 array elements for LLM (vs 1,000 for NMT)
- Max 5,000 chars per element for LLM (vs 50,000 for NMT)
- Max 5
referenceTextPairsper target - LLM translation is NOT available with private endpoints
- LLM requires an AIServices (Foundry) resource, not a standalone Azure OpenAI resource
- Resource-specific endpoint (
/translator/text/translate) is required for AIServices/Foundry resources; global endpoint requiresOcp-Apim-Subscription-Regionheader - 100+ languages supported; LLM/adaptive may support fewer -- check the language support page
- LLM latency depends on computing resources allocated during model deployment
- This is a preview API -- features may change before GA