如果你现在就需要把一段字符串,或一个只包含少量字符串的小对象,转成另一种语言——比如表单标签、通知,或用户正在等待的一小段界面文案——你肯定不想为了这一趟请求去跑一个 webhook 端点,或者轮询一个任务。你想要的是发出文本,直接拿回翻译。
这正是同步 Localize 端点的用途:一次请求,按原结构返回翻译后的数据。 你使用源语言区域设置和目标语言区域设置 POST 键值内容,请求会在引擎完成翻译前保持阻塞,响应则返回同一个对象,只翻译其中的值,结构完全不变。没有需要跟踪的任务,也不需要第二次调用。
这不是一次普通的模型调用。它会经过你配置好的本地化引擎——包括它的 glossary、brand voice、instructions,以及按区域设置配置的 model selection——也就是 async API 使用的同一套引擎。区别只在返回形式:异步调用会把一次请求分发到多个区域设置,并在结果完成后陆续交付;而这个调用只处理一组区域设置,并直接内联返回结果。
如果一个区域设置加一次阻塞调用就够了?那你来对地方了。
当你只需要单个区域设置组合,并且可以等待一次往返时,就该用这个端点。如果你有多个目标区域设置、内容较长,或者希望把失败按区域设置隔离开,那么 async Localization API 会更适合:它接收一次请求,立即返回一个 202,并将每个区域设置作为独立、持久的后台工作流运行。除了延迟之外,还有一点不同:localization pipeline——预编辑、人工审核、回译以及其他可选阶段——只会在异步任务中运行。这个同步调用会忽略 pipeline 配置。
本页内容
请求#
POST /process/localize使用 X-API-Key 请求头进行身份验证。密钥按组织范围生效,可访问你组织中的所有引擎——关于在哪里生成密钥,请参阅 Authentication;关于完整的错误模型,请参阅 Errors and status codes。
| 参数 | 类型 | 说明 |
|---|---|---|
engineId | string(可选) | 本地化引擎 ID(eng_...)。如果省略,则使用你组织的默认引擎。 |
sourceLocale | string | BCP-47 源语言区域设置(例如 en)。 |
targetLocale | string | BCP-47 目标语言区域设置(例如 de)。 |
data | object | 要翻译的键值内容。支持嵌套对象和数组;你发送什么结构,响应就按什么结构返回。 |
context | string(可选) | 这批翻译内容的整体上下文,例如产品界面、受众或用途。适用于整个请求。 |
hints | object(可选) | 按键提供的上下文提示。键与 data 中的键对应;值是面包屑字符串数组(例如 { "nav.home": ["Navbar", "Home link"] }),用于告诉引擎字符串所在的位置,从而帮助它消解简短文本或多义文本的歧义。 |
{
"engineId": "eng_abc123",
"sourceLocale": "en",
"targetLocale": "de",
"data": {
"greeting": "Hello, world!",
"cta": "Get started"
},
"hints": {
"cta": ["Landing page", "Primary button"]
}
}响应#
响应会按你发送时的原始结构返回翻译后的内容,同时附带生成该翻译的模型和本次请求的成本。返回的键不变,嵌套层级也不变——你的代码可以直接从它已经熟悉的结构中读取翻译结果。
| 字段 | 类型 | 说明 |
|---|---|---|
sourceLocale | string | BCP-47 源语言区域设置,原样回显请求中的值。 |
targetLocale | string | BCP-47 目标语言区域设置,原样回显请求中的值。 |
data | object | 翻译后的键值内容,与输入结构一致。 |
model | string(可选) | 生成此翻译的 LLM model,格式为 provider/model(例如 anthropic/claude-sonnet-4.5)。通过它,你可以知道回退链中实际运行的是哪个模型。如果未发生 LLM 调用,则该字段不会出现——参见下方提示。 |
usage | object(可选) | token 计数以及本次请求的美元成本明细。如果未发生 LLM 调用,则该字段不会出现。 |
usage 对象会逐项列出本次调用的成本,方便你无需单独查询账单就能归因支出:
| 字段 | 类型 | 说明 |
|---|---|---|
inputTokens | number | 所有分块合计消耗的输入 token 总数。 |
outputTokens | number | 所有分块合计生成的输出 token 总数。 |
cacheReadTokens | number | 当模型提供该数据时,由服务商 prompt cache 提供的输入 token 数。 |
cacheWriteTokens | number | 当模型提供该数据时,写入服务商 prompt cache 的输入 token 数。 |
llmCost | number | 上游 LLM 服务商的美元成本。未报告成本时为 0。 |
localizationCost | number | Lingo.dev 的按 token 计费美元成本,根据 outputTokens 计算得出。 |
cost | number | 请求总成本(美元)(llmCost + localizationCost)。 |
{
"sourceLocale": "en",
"targetLocale": "de",
"data": {
"greeting": "Hallo, Welt!",
"cta": "Jetzt starten"
},
"model": "anthropic/claude-sonnet-4.5",
"usage": {
"inputTokens": 2789,
"outputTokens": 861,
"cacheReadTokens": 0,
"cacheWriteTokens": 0,
"llmCost": 0.02129,
"localizationCost": 0.001722,
"cost": 0.023012
}
}何时 `model` 和 `usage` 会缺失
如果 data 为空——也就是没有需要翻译的键——端点会直接短路返回,不会调用 LLM,因此响应中会省略 model 和 usage。这是成本字段缺失的唯一情况,原因也很简单:没有产生任何成本。没有内容被翻译,也就没有任何花费。凡是触发翻译的请求,这两个字段都会包含在内。在解析器里把它们视为可选字段,就不会在空输入场景下感到意外。
示例#
同一个调用的五种语言示例。为便于说明,每个示例都发送一个扁平对象;data 也支持嵌套对象和数组,响应会按你发送的结构原样返回。
const response = await fetch(
"https://api.lingo.dev/process/localize",
{
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
engineId: "eng_abc123",
sourceLocale: "en",
targetLocale: "de",
data: {
greeting: "Hello, world!",
cta: "Get started",
},
}),
}
);
const { data } = await response.json();
// { greeting: "Hallo, Welt!", cta: "Jetzt starten" }本地化过程中会发生什么#
一次 POST 背后其实隐藏着一连串步骤,了解它们很有价值——因为正是这些步骤,确保输出结果与你其余的本地化内容保持一致,而不是一次性的模型猜测。当请求到达该端点时,引擎会按顺序应用完整配置:
模型选择——选择与该区域设置组合匹配的最高优先级 LLM model。特定区域设置的模型优先于通配符(
*)模型。如果主模型失败,引擎会自动回退到下一个已排序的模型。品牌语调——为目标区域设置加载 brand voice;如果不存在该区域设置专用的品牌语调,则回退到通配符品牌语调。
指令——加载所有与目标区域设置匹配的 instruction,包括通配符指令。
术语表查找——将输入值拆分为可搜索的分块,生成嵌入,并对引擎的 glossary 执行向量相似度搜索。匹配到的术语会强制使用精确译法,或将术语标记为不可翻译,从而原样保留。
生成——将组合好的提示发送给所选模型,然后解析并验证 JSON 响应。
这与 async API 对每个任务执行的引擎步骤完全相同。选择同步而不是异步,改变的是交付形式,而不是翻译的生成方式——因此,在这里翻译的字符串和在异步任务中翻译的同一字符串,会落到相同的术语表条目和相同的语调上。
模型回退是自动的,响应会告诉你实际运行了哪一个
如果主模型失败,引擎会按排序顺序尝试下一个模型。这个过程完全透明——无论最终由哪个模型生成翻译,响应结构都一模一样。是否发生回退,唯一的信号就是响应中的 model 字段:当你需要准确知道链路中究竟是哪个模型处理了某个请求时,读取它即可。
