补充翻译
给一个已有任务再翻译若干新目标语言。等价于前端任务详情页的"补充翻译"按钮流程,但:
- 跳过 TB_SCAN —— 原任务早就扫过术语、相关术语已入库,不会重新走一遍术语扫描
- 自动过滤已翻译语言 —— 你传的
target_languages里,已经翻过的会被丢进skipped_target_languages,只对真正缺失的语言跑 TRANSLATE - 异步语义 —— 和
/tasks/create一样,返回很快;真实工作(CSV 生成 → GCS 上传 → TRANSLATE 触发)在后台 fire-and-forget;过程 / 结果通过节点回调(tmMatching/tbMatching/ ... /task.completed/task.failed)通知集成方
使用时机
典型接入顺序:
POST /tasks/create创建任务,翻[en, ja]- 任务跑完(收到
task.completed回调) - 业务侧后来决定还要
[ko, fr]—— 调本接口即可 - 系统直接跑 TRANSLATE,不会重新扫术语
- 和常规翻译一样,通过节点事件 + 终态
task.completed报告进度 / 结果
此接口可重复调用 —— 每次都是独立的工作流 + 独立的 trace_id;后续再想补更多语言只管再调。
请求地址
POST {BASE_URL}/api/open/v1/tasks/supplement-translate鉴权 Header
和 创建翻译任务 完全一样。
请求参数(Body)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id | string | 是 | 目标任务 ID(必须是同 App Key 创建的开放平台任务) |
target_languages | string[] | 是 | 要补充翻译的目标语言,最多 50 个。已经翻译完成的会被自动过滤 |
skip_tm | boolean | 否 | 跳过 TM 匹配,默认 false |
skip_tb | boolean | 否 | 跳过 TB 匹配,默认 false(术语已在库里,通常不建议开) |
callback_url | string | 否 | 本次补充翻译的回调地址覆盖。留空 → 沿用原 /tasks/create 登记的 callback_url;传了 → 本次触发的所有回调都发到这个地址,原任务的 callback_url 不受影响 |
callback_events | string[] | 否 | 本次回调订阅过滤覆盖,数组形式,每项必须在事件白名单中。留空 → 沿用原任务级订阅 |
源语言不需要传 —— 从 task.source_languages[0] 自动取(原 /tasks/create 时登记的源语言)。
说明:目标语言过滤规则
- 参数去重 + trim
- 若某语言 == 源语言 → 自动进
skipped - 若任务里任一字符串在该语言列已有非空值 → 视为"已翻",进
skipped - 否则进
effective
若 effective 为空(所有语言都已翻 / 全是源语言),不会触发工作流,但仍然会立刻发一个 task.completed 回调,detail.skipped=true、detail.reason="all_languages_already_translated",便于集成方一致地处理完成事件。
响应
成功(HTTP 200):
json
{
"success": true,
"code": 0,
"msg": "ok",
"trace_id": "d3f98b2c...",
"data": {
"task_id": "68a12cb7e1f9a88b4ea23c77",
"job_id": "supplement_translate_...",
"accepted_at": "2026-04-23T07:12:03.441Z",
"requested_target_languages": ["ko", "de", "fr"],
"effective_target_languages": ["ko", "fr"],
"skipped_target_languages": ["de"],
"all_already_translated": false
}
}job_id:本次补充翻译对应的 TRANSLATE job 标识;all_already_translated=true时为nullaccepted_at:服务器接受本次请求的 UTC 时间requested_target_languages:你传过来 + 去重后的列表effective_target_languages:真正会触发 TRANSLATE 的目标语言skipped_target_languages:被过滤掉的(已翻译的 / 等于源语言的)all_already_translated:是否所有请求语言都已翻译过;true时不会跑工作流,但仍会发一次task.completed回调
回调
所有回调发送到:
- 本次请求的
callback_url(若在 body 里传了覆盖) - 否则发到原
/tasks/create登记的callback_url
每次回调携带的 trace_id == 本次响应里的 trace_id(与原任务的 trace_id 不同),方便在集成侧区分"原任务"和"补充翻译"的回调流。
事件序列和 创建翻译任务 一致(但不会发 term_scan.completed,因为补充翻译必然跳过 TB_SCAN):
tmMatching/tbMatching/kbExtraction/translateBatch/lqaBatch/translateEnhanceBatch/aiScoringBatch:各 TRANSLATE 子步骤状态task.completed:补充翻译完成task.failed:出错时发送
若 all_already_translated=true,只会发一个 task.completed,detail 形如:
json
{
"skipped": true,
"reason": "all_languages_already_translated",
"trigger": "supplement",
"requested_target_languages": ["en", "ja"],
"effective_target_languages": [],
"skipped_target_languages": ["en", "ja"]
}错误码
| code | 说明 |
|---|---|
| 400 | 参数缺失或非法(task_id / target_languages / callback_url 格式 / callback_events 含未知事件 / 超过 50 个语言) |
| 401 | 签名校验失败 / 时间戳过期 |
| 403 | 任务不属于该 App Key |
| 404 | 任务不存在 |
| 422 | 任务没有源字符串(task_strings_aggregated 为空),无法补充翻译;或任务未配置源语言 |
| 500 | 系统错误 |
| 502 | 工作流触发失败(通过后台回调 task.failed 报告,不会在本次 HTTP 响应里) |
示例
基础示例
bash
APP_KEY="5685414646a54423c891d87194d87f3f"
APP_SECRET="<你的 App Secret>"
TASK_ID="68a12cb7e1f9a88b4ea23c77"
BASE_URL="https://api.loxily.com"
TIMESTAMP=$(date +%s)
BODY='{"task_id":"'"${TASK_ID}"'","target_languages":["ko","de","fr"]}'
SIGN=$(printf '%s' "${TIMESTAMP}${BODY}${APP_SECRET}" | md5)
curl -s -X POST "${BASE_URL}/api/open/v1/tasks/supplement-translate" \
-H "Content-Type: application/json" \
-H "X-Loxily-AppKey: ${APP_KEY}" \
-H "X-Loxily-Timestamp: ${TIMESTAMP}" \
-H "X-Loxily-Sign: ${SIGN}" \
--data "${BODY}"指定独立 callback_url
本次补充翻译的回调改发到另一个接收地址,不影响原任务的回调:
bash
BODY='{
"task_id": "68a12cb7e1f9a88b4ea23c77",
"target_languages": ["ko", "fr"],
"callback_url": "https://my-hooks.example.com/loxily/supplement"
}'前端联动
- 前端任务详情页有一个"补充翻译"按钮 —— 和本接口触发的是同一条工作流路径(TRANSLATE,
scan_terms=false) - 集成方通过 API 提交后,前端页面会自然看到任务状态和已翻字符串随节点事件推进
- 反之亦然:前端触发的补充翻译,如果该任务是开放平台创建的,也会通过
callback_url回调给集成方(按原任务级订阅)
幂等与重复调用
- 本接口没有幂等键概念(和
/tasks/create的client_task_id不同)—— 每次调用都会启动一次新的 TRANSLATE 工作流,得到独立job_id/trace_id - 若目标语言已被前一次补充覆盖,下一次调用会自动把该语言归入
skipped,不会重复翻译 - 短时间连续调用多次同一组语言可能产生并发的 TRANSLATE 任务;建议集成侧在收到
task.completed回调后再发起下一次补充,以获得清晰的回调时间线