OneSky External API v1

Programmatically upload XLIFF / XLSX / DOCX / PPTX files for machine translation, poll job progress, and download the translated results.

通过 API 上传 XLIFF / XLSX / DOCX / PPTX 文件进行机器翻译,轮询任务进度,并下载翻译结果。

Overview概述

The API exposes four endpoints under the base path /v1. A typical integration uploads a file, receives a jobId, polls job status until it is Done, then downloads the returned files.

该 API 在基础路径 /v1 下提供四个端点。典型集成流程为:上传文件,获得 jobId,轮询任务状态直到变为 Done,然后下载返回的文件。

EnvironmentBase URL
Productionhttps://ext-api.oneskyai.net
环境Base URL
生产环境https://ext-api.oneskyai.net

All requests and responses use application/json unless noted (file uploads use multipart/form-data). All endpoints must be called on the ext-api host above — requests to any other OneSky host are rejected.

除特别说明外,所有请求和响应均使用 application/json(文件上传使用 multipart/form-data)。所有端点必须通过上方的 ext-api 主机调用——发往其他 OneSky 主机的请求会被拒绝。

Authentication身份验证

Every request must include your API key in the x-api-key header. Keys are generated in the OneSky MTPE Portal (one-time reveal on creation) and scope which projects and languages you may access.

每个请求都必须在 x-api-key 请求头中携带你的 API key。Key 在 OneSky MTPE Portal 生成(创建时仅显示一次),并决定你可访问的项目与语言范围。

curl https://ext-api.oneskyai.net/v1/projects \
  -H "x-api-key: osk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Note — Keep your key secret. A missing, invalid, or disabled key returns 401 Unauthorized. Requests that do not reach the API through the official host return 403 Forbidden.
注意 — 请妥善保管你的 key。缺失、无效或已禁用的 key 会返回 401 Unauthorized。未通过官方主机访问的请求会返回 403 Forbidden

Create an API key创建 API key

API keys are self-managed in the OneSky MTPE Portal.

API key 由你在 OneSky MTPE Portal 自助管理。

EnvironmentPortal URL
Productionhttps://api.oneskyai.net/mtpe-portal/mtpe-platform/api-keys
环境Portal URL
生产环境https://api.oneskyai.net/mtpe-portal/mtpe-platform/api-keys
  1. Sign in to the MTPE Portal with your OneSky account, then open the API Keys page from the top navigation (or go directly to the URL above).
  2. Click Generate Key, enter a descriptive label (e.g. integration-prod) to identify the key later, and confirm.
  3. The full key (osk_…) is shown once. Copy it immediately and store it in a secret manager — it is never displayed again and cannot be recovered.
  4. Send it in the x-api-key header of every request.
  1. 用你的 OneSky 账号登录 MTPE Portal,从顶部导航打开 API Keys 页面(或直接访问上方 URL)。
  2. 点击 Generate Key,填写一个便于识别的 label(例如 integration-prod),然后确认。
  3. 完整的 key(osk_…)只会显示一次。请立即复制并保存到密钥管理工具——之后不会再显示,且无法找回。
  4. 在每个请求的 x-api-key 请求头中携带它。
Managing keys — Up to 10 active keys per account. You can disable (toggle) or delete a key at any time; a disabled or deleted key immediately returns 401 Unauthorized. To rotate, create a new key, switch your integration over, then disable the old one.
管理 key — 每个账号最多 10 个启用中的 key。 你可以随时禁用(开关)或删除 key;被禁用或删除的 key 会立即返回 401 Unauthorized。轮换时:先创建新 key,切换集成,再禁用旧 key。

Conventions约定

HTTP status codesHTTP 状态码

200Success.
400Invalid request (missing/invalid parameter, unsupported language or file type).
401Missing or invalid API key.
403Project not in your scope, or request did not reach the API host.
404Job not found.
413Uploaded file exceeds the 30 MB binary limit.
500Unexpected server error.
200成功。
400请求无效(参数缺失/无效、不支持的语言或文件类型)。
401缺失或无效的 API key。
403项目不在你的权限范围内,或请求未到达 API 主机。
404找不到任务。
413上传文件超过 30 MB 二进制上限。
500服务器异常。

Error body shapes错误响应结构

Errors raised during authentication use a message field; errors raised by an endpoint use an error field.

身份验证阶段产生的错误使用 message 字段;端点产生的错误使用 error 字段。

// auth-layer error (401 / 403 / 500 before reaching an endpoint)
{ "message": "Unauthorized" }

// endpoint error (validation, not found, etc.)
{ "error": "projectId is required" }

Typical workflow典型流程

1.  GET  /v1/projects      → pick a projectId
2.  GET  /v1/languages     → confirm supported languages
3.  POST /v1/upload        → returns { "jobId": "..." }
4.  GET  /v1/jobs/status?jobId=...   (poll every ~5s)
       status: Pending → Processing → Done
5.  When status = Done, download each URL in the "files" array
1.  GET  /v1/projects      → 选择一个 projectId
2.  GET  /v1/languages     → 确认支持的语言
3.  POST /v1/upload        → 返回 { "jobId": "..." }
4.  GET  /v1/jobs/status?jobId=...   (约每 5 秒轮询一次)
       status: Pending → Processing → Done
5.  当 status = Done 时,下载 "files" 数组中的每个 URL

List projects列出项目

GET /v1/projects

Returns the projects accessible to your API key. Use a returned id as the projectId when uploading.

返回你的 API key 可访问的项目。上传时使用返回的 id 作为 projectId

200 — Success200 — 成功
{
  "projects": [
    { "id": "recGItPC9oapMIyyX", "name": "My Project" }
  ]
}
401 — Unauthorized401 — 未授权
{ "message": "Unauthorized" }

List languages列出语言

GET /v1/languages

Returns the source → target language pairs allowed for your account (the pairs array — the source of truth), plus flattened sourceLanguages / targetLanguages lists for convenience (e.g. dropdowns). Codes are lowercase and must be used when uploading XLSX files. (XLIFF files carry their own language attributes.) An account whose organization configured no pairs gets empty lists — meaning no pair restriction on upload.

返回你账号允许的源 → 目标语言语言对pairs 数组——以此为准), 另外附带扁平化的 sourceLanguages / targetLanguages 列表以便使用(例如下拉框)。语言代码为小写, 上传 XLSX 文件时必须使用。(XLIFF 文件自带语言属性。)若你的组织未配置任何语言对,则返回空列表—— 即上传时不做语言对限制。

200 — Success200 — 成功
{
  "pairs": [
    { "source": { "code": "en",    "name": "English" },             "target": { "code": "zh-cn", "name": "Chinese Simplified" } },
    { "source": { "code": "en",    "name": "English" },             "target": { "code": "ja",    "name": "Japanese" } },
    { "source": { "code": "zh-tw", "name": "Chinese Traditional" }, "target": { "code": "ko",    "name": "Korean" } }
  ],
  "sourceLanguages": [
    { "code": "en",    "name": "English" },
    { "code": "zh-tw", "name": "Chinese Traditional" }
  ],
  "targetLanguages": [
    { "code": "zh-cn", "name": "Chinese Simplified" },
    { "code": "ja",    "name": "Japanese" },
    { "code": "ko",    "name": "Korean" }
  ]
}
500 — Server error500 — 服务器错误
{ "error": "Failed to fetch languages" }

Upload a file上传文件

POST /v1/upload

Uploads an XLIFF, XLSX, DOCX or PPTX file and starts the automation pipeline (Source Upload → Word Count → Machine Translation → Export). Provide the file either as a binary multipart/form-data upload or as a public fileUrl (JSON body). Returns a jobId to poll.

上传 XLIFF、XLSX、DOCX 或 PPTX 文件并启动自动化流程(Source Upload → Word Count → Machine Translation → Export)。文件可通过二进制 multipart/form-data 上传,或提供可公开访问的 fileUrl (JSON body)。返回用于轮询的 jobId

Parameters参数

FieldTypeRequiredDescription
filebinaryeither / or The file itself (multipart/form-data). .xliff, .xlf, .xlsx, .docx, or .pptx. Max 30 MB.
fileUrlstringeither / or Public URL to the file (JSON body). Use this for files larger than 30 MB.
projectIdstringrequired A project id from GET /projects.
sourceLanguagestringXLSX / DOCX / PPTX Source language code. Required for XLSX, DOCX and PPTX; ignored for XLIFF (read from the file).
targetLanguagesstringXLSX / DOCX / PPTX Comma-separated target codes, e.g. zh-CN,ja. Required for XLSX, DOCX and PPTX; ignored for XLIFF.
columnsSchemaobjectXLSX only Maps a language code to its column letter, e.g. { "en": "A", "zh-CN": "B" }. Must include the source language (its column is the source text). Target-language columns are optional — include one only when the sheet already has pre-translated text to import; omit it for a plain MT job (MT generates the translation). Required for XLSX. For multipart/form-data, send it as a JSON string.
sheetNamesstring[]XLSX only Which sheet(s) to read — column letters are sheet-agnostic, so this is mandatory. JSON array ["Sheet1"] or comma-separated Sheet1,Sheet2. Required for XLSX.
keyColstringXLSX optional Column letter holding a string ID/key. When omitted, keys fall back to <sheet>-<row>.
importExistingTranslationbooleanXLIFF only When true, existing <target> values in the XLIFF are imported as already-translated segments. Default false.
字段类型必填说明
filebinary二选一 文件本体(multipart/form-data)。.xliff.xlf.xlsx.docx.pptx。最大 30 MB。
fileUrlstring二选一 文件的公开 URL(JSON body)。大于 30 MB 的文件请用此方式。
projectIdstring必填 来自 GET /projects 的项目 id
sourceLanguagestringXLSX / DOCX / PPTX 源语言代码。XLSX、DOCX、PPTX 必填;XLIFF 会忽略(从文件读取)。
targetLanguagesstringXLSX / DOCX / PPTX 逗号分隔的目标语言代码,例如 zh-CN,jaXLSX、DOCX、PPTX 必填;XLIFF 会忽略。
columnsSchemaobject仅 XLSX 将语言代码映射到其列字母,例如 { "en": "A", "zh-CN": "B" }必须包含源语言(其列为原文)。目标语言的列为选填——仅当表格中已有可导入的预翻译文本时才填写;纯 MT 任务可省略(由 MT 生成译文)。XLSX 必填。使用 multipart/form-data 时请以 JSON 字符串传入。
sheetNamesstring[]仅 XLSX 要读取的工作表——列字母与工作表无关,因此必须指定。JSON 数组 ["Sheet1"] 或逗号分隔 Sheet1,Sheet2XLSX 必填
keyColstringXLSX 选填 存放字符串 ID/键的列字母。省略时,键回退为 <sheet>-<row>
importExistingTranslationboolean仅 XLIFF true 时,XLIFF 中已有的 <target> 值会作为已翻译片段导入。默认 false
XLIFF multi-language — An XLIFF may contain multiple <file> blocks with different target-language attributes. The server parses each and creates an independent task per target language. Each source → target pair is validated against your organization's allowed pairs (case-insensitive); when your organization configured no pairs, no pair restriction is applied.
XLIFF 多语言 — 一个 XLIFF 可包含多个具有不同 target-language 属性的 <file> 块。服务器会逐个解析,并为每个目标语言创建独立任务。 每个源 → 目标语言对会与你组织的允许语言对校验(不区分大小写);若你的组织未配置任何语言对,则不做语言对限制。
XLSX column mapping — Unlike XLIFF (a structured format the parser self-describes), an XLSX is just a grid, so columnsSchema must tell the server which column letter holds the source text (the sourceLanguage entry, always required). A target-language column is only needed when the sheet already contains pre-translated text — omit it and MT will generate the translation. Column letters are case-insensitive and apply across every sheet listed in sheetNames.
XLSX 列映射 — 与 XLIFF(结构化格式,解析器自带描述)不同, XLSX 只是一张表格,因此必须通过 columnsSchema 告诉服务器原文在哪一列(sourceLanguage 对应项,必填)。仅当表格中已有预翻译文本时才需要填写目标语言的列;省略则由 MT 生成译文。列字母不区分大小写, 并对 sheetNames 中列出的每一张工作表生效。
DOCX / PPTX (OOXML) — Like XLSX, a Word/PowerPoint file carries no embedded target language, so you must supply sourceLanguage and targetLanguages. Unlike XLSX it needs no columnsSchema, sheetNames or keyCol — the whole document is a single implicit source and the parser reads every text run. Each source → target pair is validated against your organization's allowed pairs, same as XLSX.
DOCX / PPTX(OOXML) — 与 XLSX 一样,Word/PowerPoint 文件本身不含目标语言,因此必须提供 sourceLanguagetargetLanguages。但与 XLSX 不同, 它无需 columnsSchemasheetNameskeyCol——整份文档即 单一原文,解析器会读取每一个文本 run。每个源 → 目标语言对同样会与你组织的允许语言对校验。

Example — by URL (DOCX)示例 — 通过 URL(DOCX)

curl -X POST https://ext-api.oneskyai.net/v1/upload \
  -H "x-api-key: osk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
        "fileUrl": "https://example.com/file.docx",
        "projectId": "recGItPC9oapMIyyX",
        "sourceLanguage": "en",
        "targetLanguages": "zh-CN,ja"
      }'

PPTX is identical — just point fileUrl at a .pptx (or send a .pptx binary via -F "file=@..."). No column or sheet fields apply.

PPTX 完全相同——只需将 fileUrl 指向 .pptx (或用 -F "file=@..." 上传 .pptx 二进制)。不涉及任何列或工作表字段。

Example — binary upload (XLIFF)示例 — 二进制上传(XLIFF)

curl -X POST https://ext-api.oneskyai.net/v1/upload \
  -H "x-api-key: osk_xxx" \
  -F "file=@/path/to/merge_en.xliff" \
  -F "projectId=recGItPC9oapMIyyX" \
  -F "importExistingTranslation=false"

Example — by URL (XLSX)示例 — 通过 URL(XLSX)

curl -X POST https://ext-api.oneskyai.net/v1/upload \
  -H "x-api-key: osk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
        "fileUrl": "https://example.com/file.xlsx",
        "projectId": "recGItPC9oapMIyyX",
        "sourceLanguage": "en",
        "targetLanguages": "zh-CN,ja",
        "columnsSchema": { "en": "A" },
        "sheetNames": ["Sheet1"]
      }'

Source-only mapping (above) is the typical MT case — no target column, MT generates the translations. To import pre-translated text, add the target column(s), e.g. "columnsSchema": { "en": "A", "zh-CN": "B" }, and optionally "keyCol": "D".

仅映射源语言(如上)是常见的 MT 场景——不填目标列,由 MT 生成译文。如需导入预翻译文本, 请加上目标列,例如 "columnsSchema": { "en": "A", "zh-CN": "B" },并可选填 "keyCol": "D"

200 — Success200 — 成功
{ "jobId": "20260618153243-8528" }
400 — Language pair not allowed400 — 语言对不被允许
{ "error": "Language pair(s) not supported: en>fr" }

Each source → target pair must be in your organization's allowed pairs (configured by OneSky). This is separate from the project auto-MT check below — a pair can be allowed for your account yet still be rejected if the project itself does not support MT for it. When your organization configured no pairs, this check is skipped.

每个源 → 目标语言对都必须在你组织的允许语言对内(由 OneSky 配置)。这与下方的项目自动 MT 校验是两回事——某语言对可能在你账号允许范围内,但若项目本身不支持该语言对的 MT,仍会被拒绝。若你的组织未配置任何语言对,则跳过此校验。

400 — Project not found400 — 项目未找到
{ "error": "Project not found: rectMWcKtHHymDygX" }
400 — Auto-MT not supported for language pair400 — 该语言对不支持自动 MT
{ "error": "MT not support for en to ja" }

Every upload is an auto-MT job, and auto-MT support is project-specific. The request is rejected up front if the resolved project does not support machine translation for a requested source → target pair.

每次上传都是自动 MT 任务,而自动 MT 的支持范围因项目而异。若所解析的项目不支持某个 源 → 目标语言对的机器翻译,请求会被提前拒绝。

403 — Project not accessible403 — 无项目权限
{ "error": "projectId is not accessible" }
413 — File too large413 — 文件过大
{ "error": "File too large. Max 30MB for binary upload. Use fileUrl for larger files." }

Check job status查询任务状态

GET /v1/jobs/status?jobId=<jobId>

Polls the automation job returned by POST /upload. Poll roughly every 5 seconds until status is a terminal value.

轮询 POST /upload 返回的自动化任务。约每 5 秒轮询一次,直到 status 变为终态。

Query paramRequiredDescription
jobIdrequiredThe jobId returned from POST /upload.
查询参数必填说明
jobId必填POST /upload 返回的 jobId
Download links — The files array appears only when the job is Done and the export files are ready. If the job is otherwise complete but exports are still generating, the aggregate status is reported as Processing — keep polling.
下载链接files 数组在任务为 Done 且导出文件就绪时出现。如果任务其余部分已完成但导出仍在生成中,聚合 status 会显示为 Processing——请继续轮询。
serverTime — Every response includes a serverTime field (ISO 8601 UTC, e.g. 2026-06-24T08:15:30.123Z) set to the moment the server produced the response. While a job stays in Processing the rest of the payload may look unchanged — a moving serverTime confirms the response is fresh, not cached.
serverTime — 每个响应都包含 serverTime 字段(ISO 8601 UTC,例如 2026-06-24T08:15:30.123Z),即服务器生成该响应的时刻。当任务长时间 停留在 Processing 时,其余字段看起来可能没有变化——不断变化的 serverTime 可确认响应是实时的,而非缓存。
errorMessage — A per-language entry includes an errorMessage field only when that language's status is Failed. It describes why that language failed (e.g. MT is not supported for the language pair). The field is omitted for all non-failed languages.
errorMessage — 仅当某分语言条目的 statusFailed 时,该条目才会包含 errorMessage 字段,用于说明该语言失败的原因(例如该语言 对不支持机器翻译)。非失败的语言不会返回该字段。
200 — Done (files ready)200 — Done(文件就绪)
{
  "jobId": "20260618153243-8528",
  "status": "Done",
  "languages": [
    { "sourceLanguage": "en", "targetLanguage": "zh-cn", "status": "Done" }
  ],
  "files": [
    "https://file.oneskyai.net/mtpe-export/f02cd3b9-.../merge-en.xliff"
  ],
  "serverTime": "2026-06-24T08:15:30.123Z"
}
200 — Processing200 — Processing
{
  "jobId": "20260618153243-8528",
  "status": "Processing",
  "languages": [
    { "sourceLanguage": "en", "targetLanguage": "zh-cn", "status": "Done" },
    { "sourceLanguage": "en", "targetLanguage": "ja",    "status": "Processing" }
  ],
  "serverTime": "2026-06-24T08:15:30.123Z"
}
200 — Failed (per-language error)200 — Failed(分语言错误)
{
  "jobId": "20260618153243-8528",
  "status": "Failed",
  "languages": [
    { "sourceLanguage": "en", "targetLanguage": "zh-cn", "status": "Done" },
    { "sourceLanguage": "en", "targetLanguage": "ja",    "status": "Failed",
      "errorMessage": "MT is not supported for this language pair" }
  ],
  "serverTime": "2026-06-24T08:15:30.123Z"
}
404 — Job not found404 — 找不到任务
{ "error": "Job not found" }

Job statuses任务状态

Each per-language task and the aggregate job carry one of these statuses:

每个分语言任务以及聚合任务都会是以下状态之一:

StatusTerminal?Meaning
PendingnoQueued, not started.
ProcessingnoIn progress (or exports still generating).
DoneyesCompleted; files available.
FailedyesA step failed; the job will not complete.
StoppedyesManually stopped.
状态终态?含义
Pending已排队,尚未开始。
Processing处理中(或导出仍在生成)。
Done已完成;files 可用。
Failed某步骤失败;任务无法完成。
Stopped已手动停止。

The aggregate status is derived from all per-language tasks: Stopped if any is stopped, else Failed if any failed, else Processing if any is still running, else Done when all are done.

聚合 status 由所有分语言任务推导:任一为 Stopped 则为 Stopped; 否则任一为 Failed 则为 Failed;否则任一仍在运行则为 Processing; 全部完成则为 Done

Error reference错误参考

Authentication (all endpoints)身份验证(所有端点)

StatusBodyCause
401{ "message": "Unauthorized" }Missing / invalid / disabled API key.
403{ "message": "Forbidden" }Request did not reach the API through the official host.
500{ "message": "Internal server error" }Server misconfiguration / account lookup failure.
状态响应体原因
401{ "message": "Unauthorized" }缺失 / 无效 / 已禁用的 API key。
403{ "message": "Forbidden" }请求未通过官方主机到达 API。
500{ "message": "Internal server error" }服务器配置错误 / 账号查询失败。

POST /upload

StatusExample error
400projectId is required · Either file (binary) or fileUrl is required · Unsupported file type. Must be .xliff, .xlf, .xlsx, .docx, or .pptx · XLIFF file has no translation units · Language pair(s) not supported: <source>><target> · Project not found: <projectId> · MT not support for <source> to <target>
400
xlsx
sourceLanguage is required for xlsx files · targetLanguages is required for xlsx files · At least one targetLanguage is required · columnsSchema is required for xlsx files, e.g. { "en": "A", "cn": "B" } · columnsSchema must be valid JSON, e.g. { "en": "A", "cn": "B" } · columnsSchema must contain a valid column letter for source language '<x>' · columnsSchema column for target language '<x>' must be a column letter (e.g. "B") · sheetNames is required for xlsx files, e.g. ["Sheet1"] · keyCol must be a column letter (e.g. "A"), got '<x>'
403projectId is not accessible
413File too large. Max 30MB for binary upload. Use fileUrl for larger files.
状态error 示例
400projectId is required · Either file (binary) or fileUrl is required · Unsupported file type. Must be .xliff, .xlf, .xlsx, .docx, or .pptx · XLIFF file has no translation units · Language pair(s) not supported: <source>><target> · Project not found: <projectId> · MT not support for <source> to <target>
400
xlsx
sourceLanguage is required for xlsx files · targetLanguages is required for xlsx files · At least one targetLanguage is required · columnsSchema is required for xlsx files, e.g. { "en": "A", "cn": "B" } · columnsSchema must be valid JSON, e.g. { "en": "A", "cn": "B" } · columnsSchema must contain a valid column letter for source language '<x>' · columnsSchema column for target language '<x>' must be a column letter (e.g. "B") · sheetNames is required for xlsx files, e.g. ["Sheet1"] · keyCol must be a column letter (e.g. "A"), got '<x>'
403projectId is not accessible
413File too large. Max 30MB for binary upload. Use fileUrl for larger files.

GET /jobs/status

StatusExample error
400jobId query parameter is required
403Forbidden (job's project is out of your scope)
404Job not found
500Failed to get job status
状态error 示例
400jobId query parameter is required
403Forbidden(任务的项目不在你的权限范围内)
404Job not found
500Failed to get job status
OneSky External API v1 — generated for external engineering integration. For API keys and access, contact your OneSky representative.