Translate API

POST /detect

Detect the language of one text or a batch of texts without translating.

POST /detect

Detect the language of text without translating it. Send one string as text, or up to 100 strings as texts. Requires authentication.

Detection runs on a local n-gram model, so it is fast and deterministic. It does not consume the monthly character quota, but it is rate-limited per operator token.

Request

POST /api/v1/detect
Authorization: Bearer opt_your-token
Content-Type: application/json

{
  "text": "Bonjour tout le monde, comment allez-vous?",
  "workspace": "my-workspace",
  "project_slug": "marketing"
}

Request Parameters

FieldTypeRequiredDescription
textstringOne of text/textsText to detect. Max 5,000 characters.
textsstring[]One of text/textsBatch of texts. 1–100 items, each non-empty and max 5,000 characters.
workspacestringNoWorkspace slug or id. Required when the token can access multiple workspaces.
project_slugstringNoProject slug to attribute the detection to.
project_idstringNoDeprecated: use project_slug.

Pass either text or texts, not both. Any workspace member can detect; unlike translation, the owner or admin role is not required.

Response (200) — single text

{
  "language": "fr",
  "languageName": "French",
  "confidence": 0.569,
  "reliable": true,
  "supported": true,
  "supportedCode": "fr",
  "candidates": [
    { "language": "fr", "confidence": 0.569 },
    { "language": "hu", "confidence": 0.028 },
    { "language": "en", "confidence": 0.011 }
  ],
  "inputCharacters": 42,
  "logId": "t8npm0CPZfZF78B-Uq3lM",
  "engine": "tinyld",
  "latencyMs": 2
}

Response (200) — batch

Results are returned in the same order as texts.

{
  "results": [
    { "language": "de", "languageName": "German", "confidence": 1, "reliable": true, "supported": true, "supportedCode": "de", "candidates": [{ "language": "de", "confidence": 1 }], "inputCharacters": 49, "logId": "l9oWWkqMkhqaJNj8r5-77" },
    { "language": "hi", "languageName": "Hindi", "confidence": 1, "reliable": true, "supported": false, "supportedCode": null, "candidates": [{ "language": "hi", "confidence": 1 }], "inputCharacters": 43, "logId": "o_dqbp14JHlqPkEhTM6zd" },
    { "language": "und", "languageName": "Undetermined", "confidence": 0, "reliable": false, "supported": false, "supportedCode": null, "candidates": [], "inputCharacters": 2, "logId": "bJ_kJzseQ_NlxwPyCdPqu" }
  ],
  "batchId": "sr1iANYUNPkQJIQT0mKu9",
  "inputCharacters": 94,
  "engine": "tinyld",
  "latencyMs": 1
}

Response Fields

FieldTypeDescription
languagestringISO 639-1 code (e.g. fr, en), or und when the language cannot be determined
languageNamestringEnglish name of the language
confidencenumberEngine score from 0 to 1. Relative, not a calibrated probability
reliablebooleantrue when the text is long enough and the top language clearly wins. Treat false as a guess
supportedbooleanWhether the language can be used as source_lang / target_lang in /translate
supportedCodestring | nullThe Translate language code to use (e.g. en → en-US, no → nb)
candidatesarrayUp to 3 { language, confidence } alternatives, best first
inputCharactersnumberCharacter count of the text
logIdstringDetection log ID for auditing
enginestringDetection engine (tinyld)
latencyMsnumberDetection time in milliseconds
batchIdstringBatch only: shared ID for every item in the request

Short and ambiguous text

Detection needs signal. Very short strings ("ok", "Hola"), numbers, and emoji often return und or reliable: false. For short UI strings, prefer passing an explicit source_lang to /translate over trusting detection.

Example

curl -X POST https://your-domain.com/api/v1/detect \
  -H "Authorization: Bearer opt_your-token" \
  -H "Content-Type: application/json" \
  -d '{"texts":["Bonjour le monde","Hallo Welt, wie geht es dir?"],"workspace":"my-workspace"}'
const res = await fetch("https://your-domain.com/api/v1/detect", {
  method: "POST",
  headers: {
    "Authorization": "Bearer opt_your-token",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ text: "Bonjour tout le monde, comment allez-vous?" }),
});

const { language, reliable, supportedCode } = await res.json();
console.log(language, reliable, supportedCode); // "fr" true "fr"
import requests

response = requests.post(
    "https://your-domain.com/api/v1/detect",
    headers={"Authorization": "Bearer opt_your-token"},
    json={"text": "Bonjour tout le monde, comment allez-vous?"},
    timeout=10,
)

print(response.json()["language"])  # "fr"

Errors

Detection uses the same error shape and status codes as /translate. Detection-specific validation errors:

StatusError
400text (or texts for a batch) is required and must be non-empty
400Pass either text or texts, not both.
400texts must be a non-empty array
400texts must not contain more than 100 items
400texts[N] must be a non-empty string
400texts[N] must not exceed 5000 characters
500Language detection failed

See the Error Reference for authentication, scope, and rate-limit errors.

On this page