接入文档

SDK 基础地址https://api.tongyuye.com/v1

开始接入与鉴权

先选择有权限的公开模型,再从服务端发起请求。示例不会自动执行;生成调用可能产生费用。

公开服务地址:https://api.tongyuye.com;OpenAI SDK Base URL:https://api.tongyuye.com/v1。手写 HTTP 路径带 /v1;SDK 的 base_url/baseURL 已带 /v1,不要重复拼接。

先在控制台创建 API 密钥,并检查账户与该密钥的模型权限、有效期、余额和 RPM 限制。控制台登录凭据不能直接当作通用 API 密钥。

以下 cURL 使用 Bash 语法(macOS/Linux、Windows Git Bash 或 WSL)。Python 示例需要 Python 3 与 requests:python -m pip install requests。密钥通过环境变量 DONGAI_API_KEY 提供;本文永远只包含占位符。生产环境使用 HTTPS。

环境变量与模型连通检查

# 在你自己的终端设置;不要将真实值贴给 AI 或提交到代码仓库。
export DONGAI_API_KEY='YOUR_DONGAI_API_KEY'
curl --fail-with-body 'https://api.tongyuye.com/v1/models' \
  -H "Authorization: Bearer $DONGAI_API_KEY"

模型 ID、能力与规格

请求中的 model 必须填写平台公开模型 ID。自部署与官 Key 的不同公开 ID 可以分别选择;同一公开 ID 背后的线路由平台调度。

导出目录仅反映当前页面可见模型,不包含供应商、上游模型 ID、成本、密钥或路由配置。账户可见模型不一定在某把受限密钥的允许名单内;最终以使用该密钥请求 GET /v1/models 为准。

GET /v1/models 返回 data[].id 和 data[].capabilities;媒体公开规格在 data[].x_dongai_pricing.media_tiers,包含 input_mode、resolution、aspect_ratio、min_duration_seconds、max_duration_seconds 等。媒体规格表用于计价,不是对所有上游参数的完整承诺。

PUBLIC_*_MODEL 表示当前目录没有对应能力或目录尚未加载,必须替换后才能调用。不要把对话模型填到生图或视频接口,也不要只在 prompt 里写模型名、时长和比例来代替 JSON 参数。

公开模型 ID已发布能力
Deepseek-v4-flash-0731-Official-key对话
Deepseek-v4-flash-0731-Self-deployed对话
Deepseek-v4-pro-0813对话
GLM-5.2对话
GLM-5.3对话
Kimi-K3-Official-key对话
Kimi-K3-Self-deployed对话
MiniMax-H3视频
Qwen3.8-flash对话、Responses
Qwen3.8-max对话
Seedance-2.0视频
Seedance-2.0-fast视频
Seedance-2.0-mini视频
Seedance-2.5视频
Seedream-4.5生图
Seedream-5.0生图
qwen-image-3.0-pro生图
qwen3.8-omni-flash对话
qwen3.8-omni-flash-realtime实时音频

对话与 Responses

Chat Completions 与 Responses 是两个入口,需要模型分别具备 chat 或 responses 能力;不可假定所有对话模型都支持 Responses。

Chat 读取 choices[0].message.content;Responses 读取 output 中的 message/content/output_text。使用 OpenAI SDK 时可使用对应的文本辅助属性。

支持流式的模型可设置 stream: true,以 SSE 逐事件读取。不要对完整流执行一次 JSON.parse;Chat 的 delta 与 Responses 的命名事件格式不同。保留流内错误并确认结束事件,不要把 HTTP 200 当成完整输出已成功。

reasoning_effort、temperature、工具调用与 max_output_tokens/max_tokens 的可用范围取决于模型;不要给所有模型硬塞同一套思考深度和输出上限。

Chat Completions

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/chat/completions' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-raw '{"model":"Deepseek-v4-flash-0731-Official-key","messages":[{"role":"user","content":"你好,请用一句话介绍你自己"}],"stream":false}'

Responses

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/responses' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-raw '{"model":"Qwen3.8-flash","input":"请用一句话解释人工智能","stream":false}'

Python OpenAI SDK(安装:python -m pip install openai)

import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["DONGAI_API_KEY"], base_url="https://api.tongyuye.com/v1")
reply = client.chat.completions.create(model="Deepseek-v4-flash-0731-Official-key",
    messages=[{"role": "user", "content": "你好"}])
print(reply.choices[0].message.content)

Node.js OpenAI SDK(安装:npm install openai)

import OpenAI from "openai";
const client = new OpenAI({apiKey: process.env.DONGAI_API_KEY, baseURL: "https://api.tongyuye.com/v1"});
const reply = await client.chat.completions.create({model: "Deepseek-v4-flash-0731-Official-key",
  messages: [{role: "user", content: "你好"}]});
console.log(reply.choices[0].message.content);

图片生成与参考图

文生图使用 POST /v1/images/generations。先从 images 能力的公开模型开始,确认可用尺寸与张数,再扩展请求。

model 与 prompt 是示例的核心字段。n 是请求张数;size(如 1024x1024)、quality、response_format(url 或 b64_json)等仅在该模型支持时设置。不同模型的尺寸、质量命名和单次张数限制可能不同,不应把示例规格当作通用参数。

常见同步成功响应包含 data[],每项可能提供 url 或 b64_json;有的模型还会提供 revised_prompt。图片响应沿用兼容模型的结构,不能套用视频 media.task 的状态轮询流程。模型特有的流式图片响应须按其 SSE 事件解析。

b64_json 是图片文件的 Base64 数据,解码保存并按真实格式处理;url 可能是有时效的外部资源,应及时保存。下载外部资源时不要发送本站 Authorization 请求头。管理后台的审查归档不等于给客户端提供了永久公开图片链接。

图像编辑 POST /v1/images/edits 和变体 POST /v1/images/variations 使用 multipart/form-data,至少包含 model 与模型要求的文件字段;参考图格式、是否支持 mask、数量限制须确认模型支持。不要给文生图接口随意增加 image 字段并假定它能编辑。

字段使用说明
model当前密钥可用且具有 images 能力的公开模型 ID
prompt主体、构图、风格、光线等内容;敏感内容仍受服务规则约束
n期望张数;先用 1,模型可能限制更小范围
size / quality仅传该模型支持的规格,与模型广场公布的计价规格核对
response_format可选且取决于模型;常见 url / b64_json,不能保证都支持

最小文生图请求

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/images/generations' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-raw '{"model":"Seedream-4.5","prompt":"真实摄影,一只白色陶瓷杯放在木桌上,自然光","n":1}'

识别 URL 或 Base64 结果

import os
import requests

BASE_URL = os.getenv("DONGAI_BASE_URL", "https://api.tongyuye.com/v1").rstrip("/")
HEADERS = {"Authorization": "Bearer " + os.environ["DONGAI_API_KEY"]}
import base64
from pathlib import Path

payload = {
  "model": "Seedream-4.5",
  "prompt": "真实摄影,一只白色陶瓷杯放在木桌上,自然光",
  "n": 1
}
response = requests.post(BASE_URL + "/images/generations", headers=HEADERS,
    json=payload, timeout=(10, 180), allow_redirects=False)
response.raise_for_status()
items = response.json().get("data", [])
if not items: raise RuntimeError("没有标准 data[] 图片结果,请核对模型返回格式")
for index, item in enumerate(items, 1):
    if item.get("b64_json"):
        Path(f"image-{index}.bin").write_bytes(base64.b64decode(item["b64_json"], validate=True))
        print("已保存图片字节;请根据实际图片格式设置文件扩展名")
    elif item.get("url"):
        print("图片地址(及时另行下载,勿携带本站密钥):", item["url"])
    else:
        raise RuntimeError("结果缺少 url/b64_json,请核对模型返回格式")

参考图编辑(仅适用于已确认支持此接口的模型)

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/images/edits' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  --form-string 'model=Seedream-4.5' \
  -F "image=@reference.png" \
  --form-string "prompt=保留主体,将背景改为干净的摄影棚"

视频生成:创建、轮询与下载

视频是异步任务。创建成功只表示任务已记录或接收;必须继续查询,等到 succeeded 后才能下载。

推荐 POST /v1/videos/generations 创建,GET /v1/media/tasks/{taskId} 查询,GET /v1/media/tasks/{taskId}/content 下载。POST /v1/videos、/v1/video/generations 以及 GET /v1/videos/{taskId}(含 /content)等兼容别名也存在;新接入使用推荐流程即可。

请求使用公开视频 model 与 prompt。duration 传数字秒数;resolution、ratio、quality、fps 等按该模型支持的规格设置。此处 720p、16:9、5 秒是未提供规格时的演示值,若目录已含文生视频规格则优先取其值;它们不保证适用于每个模型。

图片/视频参考输入并非所有模型都支持;文件或 URL 字段取决于已确认的模型协议。输入视频计价可能还要求 input_video_duration_seconds。不要让 AI 猜参考素材字段或直接调用上游的私有任务路径。

创建通常返回 HTTP 202 与任务 JSON、Location 查询路径;已成功任务的幂等重放可能返回 200。保存 id(与 task_id 相同)以及原请求的 Idempotency-Key。轮询 GET 返回 200 也可能仍是 processing;判断 JSON 中的 status。

任务属于创建它的 API 密钥;查询、下载和取消都使用同一把密钥,不是仅使用同一账户的任意密钥。content_url / content_path 也需要 Bearer 鉴权,直接在浏览器新标签打开可能返回 401。推荐自己拼接本站内容路径,避免向任意响应 URL 转发密钥。

成功内容包含 content_type、bytes、sha256,可用于选择扩展名和校验下载。progress 可以为 null,不要把未知进度显示成失败。expires_at 是任务记录中的到期时间,不应视为永久下载承诺;成功后及时下载到自己的存储,文件留存由平台策略控制。

状态 / HTTP处理方式
submitting提交正在处理或结果尚未确认;保留任务 ID,不盲目重建
queued / processing排队或生成中;建议每 5 秒查询一次,处理限流退避
storing生成后正在拉取并保存文件;尚不能下载
succeeded文件可下载;使用本站 content 路径且携带同一密钥
failed / cancelled / expired终态,停止轮询,读取 error;不要自动创建新的付费任务
425 media_task_not_ready文件未就绪,继续查询原任务
410失败/取消/过期的任务无可下载内容,或已保存文件到期
503 media_object_unavailable已存对象临时不可读,稍后重试同一次下载,不重新生成

创建一次视频任务(再次执行可能创建新任务)

# 先生成并保存请求标识。同一逻辑请求重试时必须沿用此值和完全相同的请求体。
DONGAI_VIDEO_JOB_ID="$(python -c 'import uuid; print(uuid.uuid4())')"
printf "%s\n" "$DONGAI_VIDEO_JOB_ID" > video-idempotency-key.txt
curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/videos/generations' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $DONGAI_VIDEO_JOB_ID" \
  --data-raw '{"model":"MiniMax-H3","prompt":"真实摄影,镜头缓慢推进蓝色灯光的服务器机房,无文字,无人物","duration":5,"resolution":"768p","ratio":"16:9"}'
# 保存 JSON 中的 id;连接中断时不要换新的请求标识重发。完整恢复流程见 Python。

任务响应字段示意(示意数据,不是一次真实调用)

{
  "id": "media_00000000000000000000000000000000",
  "task_id": "media_00000000000000000000000000000000",
  "object": "media.task",
  "kind": "video",
  "model": "MiniMax-H3",
  "status": "queued",
  "progress": null,
  "error": null,
  "content_type": null,
  "bytes": null,
  "sha256": null,
  "content_url": null,
  "content_path": null,
  "url": null,
  "result_url": null,
  "format": null,
  "created_at": "2026-10-20T00:00:00.000Z",
  "updated_at": "2026-10-20T00:00:00.000Z",
  "completed_at": null,
  "expires_at": "2026-10-20T00:30:00.000Z"
}

完整流程:持久保存请求标识、恢复轮询、鉴权下载

import os
import requests

BASE_URL = os.getenv("DONGAI_BASE_URL", "https://api.tongyuye.com/v1").rstrip("/")
HEADERS = {"Authorization": "Bearer " + os.environ["DONGAI_API_KEY"]}
import hashlib
import json
import time
import uuid
from pathlib import Path
from urllib.parse import quote

# 一个 job 文件对应一次付费生成;修改内容时使用新的文件名,并明确确认要创建新任务。
job_file = Path(os.getenv("DONGAI_VIDEO_JOB_FILE", "video-job.json"))
payload = {
  "model": "MiniMax-H3",
  "prompt": "真实摄影,镜头缓慢推进蓝色灯光的服务器机房,无文字,无人物",
  "duration": 5,
  "resolution": "768p",
  "ratio": "16:9"
}
body_hash = hashlib.sha256(json.dumps(payload, sort_keys=True, ensure_ascii=False).encode()).hexdigest()
key_fingerprint = hashlib.sha256(os.environ["DONGAI_API_KEY"].encode()).hexdigest()
initial_job = {"idempotency_key": str(uuid.uuid4()), "body_hash": body_hash, "base_url": BASE_URL, "key_fingerprint": key_fingerprint}
try:
    # 独占创建,两个进程不会各自分配不同的付费请求标识。文件中从不保存原始密钥。
    with job_file.open("x", encoding="utf-8") as target: json.dump(initial_job, target)
except FileExistsError:
    pass
job = json.loads(job_file.read_text(encoding="utf-8"))
if job.get("body_hash") != body_hash or job.get("base_url") != BASE_URL or job.get("key_fingerprint") != key_fingerprint:
    raise RuntimeError("job 文件属于不同请求、服务地址或密钥;请用原配置恢复,勿自动新建付费任务")
if not job.get("task_id"):
    response = requests.post(BASE_URL + "/videos/generations",
        headers={**HEADERS, "Idempotency-Key": job["idempotency_key"]}, json=payload,
        timeout=(10, 90), allow_redirects=False)
    if response.status_code not in (200, 202):
        raise RuntimeError(f"创建未确认:HTTP {response.status_code} {response.text[:800]};保留 job 文件核对")
    task = response.json()
    job["task_id"] = task["id"]
    job_file.write_text(json.dumps(job), encoding="utf-8")
task_path = "/media/tasks/" + quote(job["task_id"], safe="")
deadline = time.monotonic() + 20 * 60
while time.monotonic() < deadline:
    response = requests.get(BASE_URL + task_path, headers=HEADERS,
        timeout=(10, 30), allow_redirects=False)
    if response.status_code == 429:
        delay = response.headers.get("Retry-After", "5")
        time.sleep(min(60, max(5, int(delay))) if delay.isdigit() else 5)
        continue
    response.raise_for_status()
    task = response.json()
    print(task["id"], task["status"], task.get("progress"))
    if task["status"] == "succeeded": break
    if task["status"] in ("failed", "cancelled", "expired"):
        raise RuntimeError(json.dumps(task.get("error"), ensure_ascii=False))
    time.sleep(5)
else:
    raise TimeoutError("停止本地等待;任务可能仍在执行。保留 job 文件,下次运行恢复查询,不重新生成")

# 用本站固定路径和同一密钥下载,绝不向第三方 content_url 转发密钥。
with requests.get(BASE_URL + task_path + "/content", headers=HEADERS,
        timeout=(10, 90), stream=True, allow_redirects=False) as response:
    response.raise_for_status()
    content_type = response.headers.get("Content-Type", "").split(";", 1)[0]
    if not content_type.startswith("video/"):
        raise RuntimeError("下载并非视频内容,拒绝将错误页面当作视频保存")
    extension = {"video/mp4": ".mp4", "video/webm": ".webm", "video/quicktime": ".mov"}.get(content_type, ".bin")
    output = Path("result" + extension)
    temporary = output.with_suffix(output.suffix + ".part")
    checksum = hashlib.sha256()
    with temporary.open("wb") as target:
        for chunk in response.iter_content(1024 * 1024):
            if chunk: target.write(chunk); checksum.update(chunk)
    if task.get("sha256") and checksum.hexdigest() != task["sha256"]:
        temporary.unlink(missing_ok=True)
        raise RuntimeError("SHA-256 校验失败;请重试下载原任务,不重新生成")
    os.replace(temporary, output)
    print("已保存:", output)

向量、重排、内容审核与语音

这些接口仍需选择匹配能力的公开模型。语音的 audio 标签不能单独保证同一模型同时支持识别、翻译和合成。

Embeddings 读取 data[].embedding,适合向量检索。Rerank 输入 query 与 documents,读取 results[].index/relevance_score;内容审核输入 input,读取 results[].flagged/categories/category_scores。以模型实际返回为准。

语音合成 POST /v1/audio/speech 返回音频二进制,先确认模型支持的 voice 和 response_format。转录和翻译分别用 /v1/audio/transcriptions、/v1/audio/translations,以 multipart/form-data 上传 file 与 model;让 cURL 自动设置带 boundary 的 Content-Type。部分识别模型采用自己的已适配输入约定,应以模型说明为准。

实时音频使用 /v1/realtime?model=公开模型ID 的 WebSocket,需要 realtime 能力和服务端安全鉴权;不能把普通 HTTP 语音模型当成 Realtime 模型。平台还提供原生 /v1/messages 与 /v1beta/models/{model}:generateContent 入口,仅在相应能力可用时使用。

向量

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/embeddings' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-raw '{"model":"PUBLIC_EMBEDDING_MODEL","input":"人工智能知识检索"}'

语义重排

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/rerank' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-raw '{"model":"PUBLIC_RERANK_MODEL","query":"如何接入模型服务","documents":["通过 API 密钥调用公开模型","今天的天气很好"],"top_n":1}'

内容审核

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/moderations' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-raw '{"model":"PUBLIC_MODERATION_MODEL","input":"待检查的文本"}'

语音合成(先确认该模型支持的 voice)

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/audio/speech' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-raw '{"model":"PUBLIC_TTS_MODEL","input":"欢迎使用懂AI","voice":"YOUR_SUPPORTED_VOICE","response_format":"mp3"}' \
  --output speech.mp3

文件转录(需要兼容文件上传的 ASR 模型)

curl --fail-with-body --max-time 180 'https://api.tongyuye.com/v1/audio/transcriptions' \
  -H "Authorization: Bearer $DONGAI_API_KEY" \
  --form-string 'model=PUBLIC_ASR_MODEL' \
  -F "file=@speech.wav"

错误处理、幂等与请求证据

先保留 HTTP 状态码、error.code、error.request_id(或响应头 x-one-api-request-id)以及视频任务 ID,再决定重试方式。不要把真实密钥或敏感提示词发给客服或 AI。

视频创建支持 Idempotency-Key(1–200 个可见 ASCII 字符,不能包含空格)。幂等范围绑定创建密钥;同一 key 与完全相同的规范请求体返回原任务,响应可能含 Idempotent-Replayed: true。同一幂等 key 配不同请求体返回 409 idempotency_key_conflict。不要假定图片生成、Chat 或其他端点也具有该幂等保证。

已发出的付费 POST 如果超时或中断,可能已在执行;视频沿用原幂等 key 恢复查询,不要换 key 重提。普通图片请求不具备相同的任务幂等保证,网络不明时先查调用记录。GET 查询/下载可退避重试,遇到 429 尊重 Retry-After。

DELETE /v1/media/tasks/{taskId} 只在未向上游提交等可确认情形下取消;已提交且无法确认上游取消的任务会拒绝(409)。关闭客户端、删除本地文件或查询失败都不代表上游已停止或自动退款。

HTTP常见原因与处理
400模型/参数/媒体规格不匹配;按 error.code 修正,请勿原样循环重试
401密钥缺失、无效、过期、停用或额度限制;检查 Bearer 格式和密钥状态
402余额不足或预估金额无法冻结;充值后再发起新的操作
403密钥、账户或该模型规格无权限;核对允许模型和授权范围
404模型/任务不存在,或当前密钥不拥有该任务
409幂等请求体冲突或当前任务无法取消;保留原任务核对
429密钥 RPM 或系统容量限制;指数退避并减少并发
502 / 503 / 504上游、协议、存储或系统暂不可用;付费提交结果未知时先核对原任务

计费、留存与安全

模型广场展示当前账户的公开报价;最终费用以调用记录和账单为准。不要把公开价表当作任意规格都可以调用的保证。

文本按可核验的用量与适用价格结算;图片/视频可能按输出、时长、规格或生成 Token 计价,参考图片与输入视频也可能影响费用。重排和内容审核依据适用接口的有效用量或成功请求规则结算。

视频创建会预留预计金额,任务后续按可信结果结算;提交状态不明时会保留核对状态,不能仅凭客户端报错认定没有费用或已经退款。重复创建新任务可能重复计费,查询和文件下载不会创建新一轮生成。

平台的内容审查快照、媒体归档、视频结果文件有各自留存策略,不是永久备份。到期或清理后链接可能失效;客户端应及时将结果下载到自己的受控存储。

这份指南可直接交给 AI 编程助手。它仅包含公开地址、公开模型快照、兼容调用约定和示例;不会从浏览器读取密钥、账户令牌、调用日志、用户提示词、上游配置或媒体内容。导出后仍应核对模型目录是否已变化。

实际密钥只在自己的服务端环境变量中设置,避免放入网页、移动端包、URL、日志、截图或版本库。给不同应用创建独立密钥,设置最小模型权限与速率限制;泄露后立即停用或轮换。