01
接入总览
所有公网模型能力共用同一个 Base URL 和 Bearer API Key。推荐先查询 Key 可用模型,再选择具体接口发起请求。
/v1认证方式Bearer nx_live_...请求格式JSON / multipart字符编码UTF-8- 创建 API Key在控制台的 API Key 页面创建应用专用密钥。
- 保存到服务端写入环境变量,不要放进浏览器或客户端包。
- 查询可用模型请求
GET /v1/models,不要硬编码未授权模型。 - 调用并处理错误按接口发送 JSON 或 multipart,并实现超时与有限重试。
curl /v1/chat/completions \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "用三句话介绍你自己"}],
"max_tokens": 256,
"stream": false
}'02
认证与环境变量
每次 /v1 请求都必须携带 Authorization: Bearer <API_KEY>。正式 Key 以 nx_live_ 开头;Key 无效、过期、被吊销或所属用户停用时返回 HTTP 401。
export FLASHFRAME_BASE_URL=""
export FLASHFRAME_API_KEY="nx_live_replace_me"| 请求头 | 是否必填 | 说明 |
|---|---|---|
Authorization | 必填 | Bearer $FLASHFRAME_API_KEY |
Content-Type | 按接口 | JSON 接口使用 application/json;上传接口由 HTTP 客户端自动生成 multipart boundary。 |
Accept | 可选 | 流式文本可设置 text/event-stream。 |
03
获取当前可用模型
GET /v1/models 只返回当前 Key 被允许且平台当前有可用 Provider 的模型。模型权限或平台配置变化后,返回列表也会变化。
/v1/models建议在应用启动时读取并短期缓存curl /v1/models \
-H "Authorization: Bearer $FLASHFRAME_API_KEY"{
"object": "list",
"data": [
{
"id": "deepseek-chat",
"object": "model",
"owned_by": "deepseek"
}
]
}不要使用展示名称调用。请求中的 model 必须与返回结果中的 data[].id 完全一致,包括大小写和空格。
04
SDK 初始化
文本接口可以直接使用 OpenAI 官方 SDK,只需把 base_url 指向本平台的 /v1。图片与视频也可以使用普通 HTTP 客户端调用。
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["FLASHFRAME_API_KEY"],
base_url=os.environ["FLASHFRAME_BASE_URL"].rstrip("/") + "/v1",
timeout=300.0,
)
result = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": "你好"}],
)
print(result.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.FLASHFRAME_API_KEY,
baseURL: `${process.env.FLASHFRAME_BASE_URL.replace(/\/$/, "")}/v1`,
timeout: 300_000,
});
const result = await client.chat.completions.create({
model: "deepseek-chat",
messages: [{ role: "user", content: "你好" }],
});
console.log(result.choices[0].message.content);dangerouslyAllowBrowser,否则 API Key 会暴露给访问者。05
文本与推理
/v1/chat/completionsJSON · 支持普通响应与 SSE| 字段 | 类型 | 必填 | 默认值与约束 |
|---|---|---|---|
model | string | 是 | 必须使用 /v1/models 返回的文本模型 ID。 |
messages | array | 是 | 最多 100 条;全部消息内容合计不超过 200,000 字符。 |
messages[].role | enum | 是 | system、user 或 assistant。 |
messages[].content | string | 是 | 单条最多 50,000 字符。 |
max_tokens | integer | 否 | 最小 1,服务端上限 8,192;不传时由服务端设置。 |
stream | boolean | 否 | 默认 false。 |
stream_options.include_usage | boolean | 否 | 流式时设为 true,末尾块包含 Token 用量。 |
temperature / top_p | number | 否 | 默认均为 1;具体有效范围由模型决定,建议只调整其中一个。 |
stop | string[] | 否 | 停止序列数组。 |
presence_penalty / frequency_penalty | number | 否 | 默认 0,具体支持程度取决于模型。 |
user | string | 否 | 你方终端用户标识,不要传手机号、身份证等敏感信息。 |
curl /v1/chat/completions \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "你是严谨的技术助手。"},
{"role": "user", "content": "解释什么是幂等请求。"}
],
"temperature": 0.3,
"max_tokens": 512,
"stream": false
}'06
连续对话
接口本身无会话状态。要继续对话,客户端必须保存上一轮的用户消息和模型回复,并在下一次请求中按顺序重新发送完整 messages。
system → user保存回复assistant第 2 轮system → user → assistant → usermessages = [
{"role": "system", "content": "你是产品顾问。"},
{"role": "user", "content": "给我的记账应用起三个名字。"},
]
first = client.chat.completions.create(
model="deepseek-chat", messages=messages
)
messages.append({
"role": "assistant",
"content": first.choices[0].message.content,
})
messages.append({"role": "user", "content": "选择第二个,并写一句宣传语。"})
second = client.chat.completions.create(
model="deepseek-chat", messages=messages
)
print(second.choices[0].message.content)- 在你方数据库保存会话与消息顺序,平台不会返回可续聊的
conversation_id。 - 长对话应先总结早期内容,再裁剪旧消息,确保不超过模型上下文和平台字符上限。
- 不要只发送最后一句,否则模型无法知道上一轮内容。
- 服务端数据库应保存角色、内容、创建时间和使用的模型 ID。
07
流式输出
设置 "stream": true 后返回 text/event-stream。每个普通事件以 data: {JSON} 表示,增量文本位于 choices[0].delta.content,最终以 data: [DONE] 结束。
curl -N /v1/chat/completions \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "写一个短故事"}],
"stream": true,
"stream_options": {"include_usage": true}
}'| 事件 | 处理方式 |
|---|---|
data: {chunk} | 解析 JSON,追加 choices[0].delta.content。 |
event: error | 解析下一行 data: 中的 OpenAI 风格错误对象,停止正常拼接。 |
data: [DONE] | 结束读取,持久化最终完整文本。 |
| 客户端中断 | 如果已经产生内容,平台可能按已生成的实际用量结算。 |
反向代理必须关闭响应缓冲并允许长连接;平台响应已设置 X-Accel-Buffering: no。
08
图片生成
/v1/images/generationsJSON · 成功后按次计费| 字段 | 类型 | 说明 |
|---|---|---|
model | string | 必填,使用图片模型 ID。 |
prompt | string | 必填,1–20,000 字符。 |
n | integer | 当前固定为 1。 |
size | enum | auto、比例值或支持的像素尺寸;不同模型可能只支持其中一部分。 |
response_format | enum | 接受 url 或 b64_json;当前统一响应结构返回可访问 URL。 |
user | string | 可选的你方用户标识。 |
curl /v1/images/generations \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Seedream 5.0 Lite",
"prompt": "现代建筑室内,清晨自然光,写实摄影",
"n": 1,
"size": "1024x1024",
"response_format": "url"
}'09
图片编辑
/v1/images/editsmultipart/form-data上传字段支持 image 和 image[]。单图最大 20 MiB,最多 40,000,000 像素;支持 PNG、JPEG、BMP、TIFF 和 WebP,文件内容必须与 MIME 类型一致。
curl /v1/images/edits \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-F "model=Seedream 5.0 Lite" \
-F "prompt=保留第一张图主体,使用第二张图的色彩风格" \
-F "size=1024x1024" \
-F "response_format=url" \
-F "image=@subject.png;type=image/png" \
-F "image[]=@style.jpg;type=image/jpeg"不要手工写 Content-Type: multipart/form-data,让 cURL、浏览器 FormData 或 HTTP SDK自动添加 boundary。
10
音频合成与私有音色
IndexTTS2 与 VoxCPM2 共用音色库和上传接口。上传 WAV 只执行一次并返回可复用的 voice_id;真正生成时由 JSON 中的 model 决定使用哪一个引擎。
/v1/audio/voices查询公共音色和当前账号私有音色/v1/audio/voices/clonemultipart 上传 WAV,创建私有音色/v1/audio/generationsJSON 提交异步音频任务/v1/audio/generations/{task_id}轮询状态与成品地址/v1/audio/generations/{task_id}/cancel取消未完成任务voice_id。6–30 秒样本可在两个模型间复用;3–6 秒样本只兼容 VoxCPM2。IndexTTS2 将样本作为说话人音色参考,VoxCPM2 将样本作为克隆参考音频。上传 WAV 并获得 voice_id
curl /v1/audio/voices/clone \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-F "file=@voice.wav;type=audio/wav" \
-F "display_name=旁白音色" \
-F "language=zh-CN"响应对象中的 id 就是生成请求的 voice。私有音色仅属于当前账号,删除后旧 ID 不可用于新任务。
通用生成参数
| 字段 | 类型 | 必填 | 约束与说明 |
|---|---|---|---|
model | enum | 是 | speech-index-tts2 或 voxcpm2。 |
input | string | 是 | IndexTTS2 与 VoxCPM2 单次均最多 600 字符。 |
voice | string | 是 | 公共音色形如 public:1;私有音色使用上传返回的 UUID。 |
response_format | enum | 否 | 当前只允许 wav。 |
speed | number | 否 | 默认 1.0,范围 0.5–2.0。 |
IndexTTS2 情感控制
| 字段 | 默认值 | 说明 |
|---|---|---|
emo_control_method | 0 | 0 跟随音色参考;2 使用 8 维向量;3 使用情感描述文本。 |
emo_weight | 0.65 | 情感影响权重,范围 0–1;约 0.6 通常更自然。 |
emo_vec | - | 方式 2 必填,必须恰好 8 个 0–1 浮点数,8 项总和不得超过 1.5。 |
emo_text | - | 方式 3 的情感描述,最多 200 字;留空时使用 input 自动推断。 |
emo_random | false | 是否加入情感随机采样。 |
公网不开放单独的“情感参考音频”第二上传口,也不开放方式 1。需要让情感独立于音色时,请使用方式 2 的向量或方式 3 的文本描述。
emo_vec 顺序固定为:喜、怒、哀、惧、厌恶、低落、惊讶、平静,即 [happy, angry, sad, afraid, disgusted, melancholic, surprised, calm];总和上限为 1.5。
curl /v1/audio/generations \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-H "Idempotency-Key: speech-order-10001" \
-H "Content-Type: application/json" \
-d '{
"model": "speech-index-tts2",
"input": "欢迎使用闪帧开放平台。",
"voice": "VOICE_ID_FROM_UPLOAD",
"response_format": "wav",
"speed": 1.0,
"emo_control_method": 2,
"emo_weight": 0.65,
"emo_vec": [0.15, 0, 0, 0, 0, 0, 0.1, 0.75],
"emo_random": false
}'VoxCPM2 专属控制
| 字段 | 类型 | 说明 |
|---|---|---|
control_instruction | string | 最多 1,000 字,例如“低沉、克制,语速稍慢,句尾自然停顿”。 |
options.usePromptText | boolean | 是否发送参考音频对应文本。 |
options.promptText | string | 启用参考文本时必填,最多 1,000 字,应与上传 WAV 一致。 |
options.cfg | number | 默认 2,范围 1–3。 |
options.ditSteps | integer | 默认 10,范围 1–50。 |
options.normalize | boolean | 是否进行响度标准化。 |
options.denoise | boolean | 是否对参考音频降噪。 |
curl /v1/audio/generations \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-H "Idempotency-Key: speech-order-10002" \
-H "Content-Type: application/json" \
-d '{
"model": "voxcpm2",
"input": "这是一段需要生成的正文。",
"voice": "VOICE_ID_FROM_UPLOAD",
"response_format": "wav",
"control_instruction": "沉稳自然,语速稍慢",
"options": {"usePromptText": true, "promptText": "这是参考音频中的原文。"}
}'任务轮询
curl /v1/audio/generations/$TASK_ID \
-H "Authorization: Bearer $FLASHFRAME_API_KEY"
# status: queued | running | success | failed | canceled
# success 时读取 audio_url,mime_type 为 audio/wav音频按实际输入字符数、以管理端配置的“每万字符价格”等比例结算。相同幂等键只能用于完全相同的请求体。
10
视频生成与图生视频
/v1/videos/generationsJSON 文生视频/v1/videos/editsmultipart 图生视频,最多 10 张参考图| 字段 | 类型 | 默认值与约束 |
|---|---|---|
model | string | 必填,使用视频模型 ID。 |
prompt | string | 必填,1–20,000 字符。 |
duration | integer | 默认 4,允许 4–15 秒;还必须满足具体模型限制。 |
ratio | enum | auto、1:1、3:4、4:3、9:16、16:9、21:9。 |
image / image[] | file | 仅图生视频;每张最大 20 MiB,格式同图片编辑。 |
curl /v1/videos/generations \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Seedance 2.0 Mini",
"prompt": "雨后城市街道,镜头缓慢向前推进",
"duration": 5,
"ratio": "16:9"
}'curl /v1/videos/edits \
-H "Authorization: Bearer $FLASHFRAME_API_KEY" \
-F "model=Seedance 2.0 Mini" \
-F "prompt=人物看向镜头并自然微笑" \
-F "duration=5" \
-F "ratio=9:16" \
-F "image=@portrait.png;type=image/png"11
响应结构
文本接口使用 OpenAI Chat Completions 结构;图片和视频接口返回 created 与 data 数组。当前图片固定一项,视频返回一项。
{
"id": "chatcmpl_...",
"object": "chat.completion",
"created": 1786400000,
"model": "deepseek-chat",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "..."},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 20,
"completion_tokens": 42,
"total_tokens": 62
}
}{
"created": 1786400000,
"data": [{
"url": "https://cdn.example/video.mp4",
"vid": "provider-video-id",
"cover_url": "https://cdn.example/cover.jpg",
"width": 1280,
"height": 720,
"duration": 5
}]
}- 把媒体 URL 当作交付结果及时下载或转存,不要假设第三方 URL 永久有效。
vid、cover_url、宽高等视频字段可能为空,业务代码必须允许缺省。- 流式
usage仅在请求stream_options.include_usage=true且模型返回用量时出现。
12
错误格式与重试
所有 /v1 错误均使用统一 JSON。业务判断优先读取 error.code,展示给用户时使用 error.message。
{
"error": {
"message": "Insufficient wallet balance",
"type": "invalid_request_error",
"param": null,
"code": "insufficient_balance"
}
}| HTTP | 常见 code / 原因 | 客户端处理 |
|---|---|---|
| 400 | model_not_found、model_not_priced、invalid_image、invalid_size、unsupported_mask | 修正请求,不要自动重试。 |
| 401 | Key 缺失、无效、过期、吊销或所属账号停用 | 停止请求并更换 Key。 |
| 403 | 模型不在 Key 白名单 | 选择允许模型或调整 Key 权限。 |
| 422 | validation_error | 检查字段类型、必填项和范围。 |
| 429 | insufficient_balance、RPM、并发或月额度限制 | 余额问题先充值;限流读取原因后延迟重试。 |
| 502 | upstream_error | 文本可有限重试;媒体先确认调用日志,避免重复生成。 |
| 503 | 数据库、Redis、限流器或服务未就绪 | 指数退避后重试。 |
| 504 | 上游超时 | 有限重试,并记录首次请求结果。 |
1s → 2s → 4s + 0–500ms 抖动文本请求最多重试 2–3 次图片 / 视频默认不自动重试,先查调用日志13
钱包、预占与结算
钱包使用人民币,内部以整数微元计算:¥1 = 1,000,000 micros。调用开始前先预占最大可能费用,结束后再按实际结果结算或释放差额。
按实际输入 / 输出 Token 结算图片每次请求预占成功后按次结算视频按请求秒数预占成功后按实际请求时长结算error.code = insufficient_balance。Provider 调用失败或响应开始前取消时,预占金额会释放;流式文本已开始输出后中断,可能按已生成用量结算。14
生产上线检查
- 密钥隔离:每个应用、环境和团队使用独立 Key,发生泄漏时可以单独吊销。
- 模型发现:从
/v1/models获取可用模型,缓存时间保持较短,并准备模型下线回退。 - 超时设置:文本建议 60–300 秒,图片和视频至少 300 秒;连接超时与响应超时分别配置。
- 连续对话:会话历史保存在你方服务端,限制消息数量并对旧内容做摘要。
- 流式代理:关闭 Nginx/CDN 缓冲、压缩聚合和过短的 idle timeout。
- 错误观测:记录接口、模型、HTTP 状态、
error.code、耗时和你方关联 ID,禁止记录 API Key。 - 媒体落库:保存任务状态、最终 URL、模型、prompt 摘要与扣费结果,并及时转存成品。
- 重试控制:文本使用有限指数退避;媒体请求没有幂等键时不要盲目自动重试。
- 额度保护:设置 Key 的 RPM、并发、模型白名单和应用侧预算告警。
- 发布前验证:依次验证 models、非流式文本、流式文本、图片、视频、错误处理和余额结算。
15
把完整文档交给 AI 接入
顶部按钮复制的是独立 Markdown 接入包,不依赖网页样式。内容包含接口契约、参数、代码示例、连续对话、SSE、错误处理和交付要求,并自动写入当前站点 Base URL。
请按这份文档为我的项目接入闪帧开放平台。先读取现有项目结构和依赖,API Key 仅从服务端环境变量读取;完成文本连续对话、流式输出、错误重试和日志,并提供可运行测试。
