Realtime Translation
Translate a small batch of text synchronously and get the translations back in seconds. No task is created, nothing is written to the project, nothing enters a published version, and nothing reaches the SDK.
This is the only synchronous translation endpoint on the Open Platform. It and Create Translation Task do different jobs:
| Realtime translation | Create translation task | |
|---|---|---|
| Response | Synchronous, seconds | Asynchronous — returns task_id, then poll or wait for callbacks |
| Where results go | The response only — nothing is persisted | Into the project: reviewable, publishable, exportable, fetched by the SDK |
| Scale | ≤ 50 texts per call | Tens of thousands per task |
| Quality pipeline | Term injection + deterministic structure checks | Full pipeline: term scan → translate → QA scoring → smart optimization |
| Repeated content | 7-day translation cache — free and instant on a hit | Every run is a new task |
To bring translations into the project you must use /tasks/create. This endpoint cannot do that.
When to use it
- Someone wants to see how a few lines read in another language, and creating a task for that is overkill
- A support or ops console needs an answer right now
- An AI agent is connected (MCP tool
loxily_translate) and should answer "how do you say this in English?" inside the conversation
Endpoint
POST {BASE_URL}/api/open/v1/translateAuth headers
Identical to Create Translation Task.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
texts | string[] | Yes | Source strings. Up to 50, each ≤ 2000 characters. Blank entries are ignored |
source_language | string | No | Source language. Empty = the root of the project's language tree |
target_language | string | one of these | The target language — this is the normal case: one language per call |
target_languages | string[] | one of these | Advanced: several at once, up to 10. Cannot be combined with target_language |
mode | string | No | standard (default) or fast — see below |
glossary | object[] | No | Caller-supplied terms, up to 200 — see below |
no_cache | boolean | No | Skip the translation cache and force a fresh call. Defaults to false |
mode: what you trade
standard (default) | fast | |
|---|---|---|
| Termbase | Matched and injected into the prompt; term choices match the project | Not injected |
| Extra cost | One concurrent round of term lookups | None — straight to the model |
Terminology is on by default: standard costs one concurrent round of term lookups over fast. Unless you are certain the batch contains no proper nouns, there is no reason to drop to fast.
Target language: one at a time by default
target_language (singular) is the normal case — one language per call:
{ "texts": ["确定要退出战斗吗?"], "target_language": "en" }Several at once is the advanced path, via target_languages (up to 10):
{ "texts": ["确定要退出战斗吗?"], "target_languages": ["en", "ja", "ko"] }You cannot pass both, and you cannot omit both — this endpoint has no "empty means every language on the project" default.
Extra languages cost you almost nothing in latency (they run concurrently; 12 languages take about as long as 1), but billing scales with the language count: three languages is three times the words. Only reach for the array when you actually need it.
glossary: bring your own terms
Systems that call realtime translation — support consoles, ops tools — usually have their own term conventions. You do not have to load them into the platform first:
"glossary": [
{ "source": "战斗", "target": "バトル", "language": "ja" },
{ "source": "金币", "target": "Coin" }
]- Merged on top of the project termbase; for the same source term, yours wins
- Entries without
languageapply to every target language - Under
mode: "fast"the project termbase is not queried, but yourglossarystill applies (it needs no lookup)
Translation cache
The same (project + source text + language pair + mode + terms) requested again within 7 days comes straight back: instant, and not billed (source: "cache" in the response).
Changing terminology invalidates the cache immediately — the cache key includes the set of terms that actually matched this text, so adding, editing, or deleting a term changes the key. You will never be served a translation built from stale terminology. Likewise, a different glossary or a different mode is a different cache entry.
To force a fresh translation (say, to get different wording), pass no_cache: true.
The cache is unrelated to the platform's translation memory: it neither reads nor writes TM. It is purely a performance layer.
Response
Success (HTTP 200):
{
"success": true,
"code": 0,
"msg": "ok",
"trace_id": "d3f98b2c...",
"data": {
"results": [
{
"index": 0,
"text": "确定要退出战斗吗?",
"translations": {
"en": {
"translation": "Leave the battle?",
"source": "model",
"structure_ok": true,
"structure_issues": []
},
"ja": {
"translation": "戦闘を終了しますか?",
"source": "tm",
"structure_ok": true,
"structure_issues": []
}
}
}
],
"billed_credits": 10,
"billed_words": 8,
"elapsed_ms": 1840,
"mode": "standard",
"source_language": "zh-hans",
"target_languages": ["en", "ja"]
}
}Check each entry — the HTTP status alone is not enough
Inside results[].translations[language]:
| Field | Description |
|---|---|
translation | The translation |
source | model = translated by the model; cache = served from the translation cache (not billed) |
structure_ok | false means the placeholders or rich-text tags do not line up with the source — do not put it on screen unreviewed |
structure_issues | The specific mismatches when structure_ok is false |
error | This target language failed for this entry. One language failing does not affect the others; the call still returns 200 |
Top-level fields
billed_credits— credits actually charged for this callbilled_words— words sent to the model (cache hits excluded)cache_hits— number of (text × language) cells served from cacheelapsed_ms— server-side duration
Billing
The same rate as batch translation: words × number of target languages. There is no realtime surcharge.
- Cache hits are not billed (
source: "cache"in the response) - Failed or timed-out calls are not billed
- Every call carries the platform-wide 10-credit ($0.01) minimum charge, the same as every other resource type
Rate limits
Per App Key, 60 requests per minute by default. Exceeding it returns HTTP 429 with a Retry-After header (seconds).
Hard per-request limits: ≤ 50 texts, ≤ 2000 characters each, ≤ 10 target languages. Split larger workloads, or use /tasks/create.
Measured latency
Server-side, from the test environment (excludes your network round trip to the API):
| Scenario | Server time |
|---|---|
| All cache hits | 78ms |
mode: "fast", cache miss | ~660ms |
standard, cache miss, 2 texts × 2 languages | ~1.7s |
Error codes
| HTTP | Meaning |
|---|---|
| 400 | Invalid parameters (count, length, language code, or mode out of range) |
| 401 / 404 | Auth failed (signature, timestamp, or AppKey) |
| 402 | Insufficient pay-as-you-go balance — top up to continue |
| 422 | The project has no language tree configured |
| 429 | Rate limited — see Retry-After |
| 502 / 504 | Translation service error or timeout; safe to retry |
Examples
BODY='{
"texts": ["确定要退出战斗吗?", "获得 {0} 金币"],
"target_language": "en"
}'
curl -X POST "${BASE_URL}/api/open/v1/translate" \
-H "Content-Type: application/json" \
-H "X-Loxily-AppKey: ${APP_KEY}" \
-H "X-Loxily-Timestamp: ${TIMESTAMP}" \
-H "X-Loxily-Sign: ${SIGN}" \
--data "${BODY}"Several languages at once (advanced)
BODY='{
"texts": ["确定要退出战斗吗?"],
"target_languages": ["en", "ja", "ko"]
}'Optimize for latency (drops terminology)
BODY='{ "texts": ["确定要退出战斗吗?"], "target_language": "en", "mode": "fast" }'Bring your own terms
BODY='{
"texts": ["获得 {0} 金币"],
"target_language": "en",
"glossary": [{ "source": "金币", "target": "Gold Pieces" }]
}'Force a fresh translation
BODY='{ "texts": ["确定要退出战斗吗?"], "target_language": "en", "no_cache": true }'FAQ
Can I find these translations in the platform UI?
No. This endpoint writes nothing, so the translations are not searchable and never appear in tasks, versions, or exports. Use /tasks/create if you need them kept.
Am I billed twice for the same sentence?
No. The second call hits the translation cache (source: "cache") — instant and free — as long as the source text, languages, mode and matched terms are unchanged and you are within the 7-day window.
The translation differs from what's in the project.
Terminology matches (standard injects the project's terms), but the surrounding wording can differ — the realtime path uses a lean prompt and a low-latency model, trading the batch pipeline's style rules for speed. When you need whole-sentence parity with the project, translate the content properly via /tasks/create.
mode: "fast" does not query the project termbase at all, so expect larger differences (a caller-supplied glossary still applies).