Chat 模型 API
Img2Vid 通过多种公开 API 格式暴露当前激活的 Chat 模型,方便 code agent、后端服务和第三方集成在不依赖浏览器 UI 的情况下调用同一套 Chat 模型配置。
Chat API 与媒体生成 API 是分开的。Chat 模型列表使用 /api/v1/models;图片、视频、音频和音乐生成模型列表使用 /api/v1/media_models。
认证
所有 Chat API 端点都需要服务端 API Key。
Authorization: Bearer $BUBLE_API_KEY
也支持使用 X-API-Key: $BUBLE_API_KEY。
端点
| Method | Endpoint | 格式 | 用途 |
|---|---|---|---|
GET |
/api/v1/models |
OpenAI 风格模型列表 | 列出当前激活的 Chat 模型。 |
POST |
/api/v1/chat/completions |
OpenAI Chat Completions 风格 | 创建 Chat 回复或流式 chunk。 |
POST |
/api/v1/messages |
Anthropic Messages 风格 | 创建 Message 回复或流式事件。 |
POST |
/api/v1beta/models/{model}:generateContent |
Gemini generateContent 风格 | 生成非流式模型内容。 |
POST |
/api/v1beta/models/{model}:streamGenerateContent |
Gemini streamGenerateContent 风格 | 流式生成模型内容。 |
OpenAI 兼容和 Anthropic 兼容端点使用 stream: true 开启流式输出。Gemini 兼容流式输出使用标准 :streamGenerateContent 方法,而不是在 :generateContent 中传 stream: true。
获取 Chat 模型列表
GET /api/v1/models
请求示例
curl https://img2vid.net/api/v1/models \
-H "Authorization: Bearer $BUBLE_API_KEY"
响应结构
{
"object": "list",
"data": [
{
"id": "openai/gpt-5.5",
"object": "model",
"created": 1778716800,
"owned_by": "OpenAI",
"name": "GPT-5.5",
"description": "High-capability chat model.",
"capabilities": {
"reasoning": true,
"attachments": true,
"tools": true
},
"tags": ["chat"]
}
]
}
模型字段
| 字段 | 说明 |
|---|---|
id |
稳定模型 key,调用 Chat API 时作为 model 传入。 |
object |
固定为 model。 |
created |
模型创建时间,Unix 秒级时间戳。 |
owned_by |
Vendor 或 Provider 展示名称。 |
name |
模型展示名称。 |
description |
可选的模型描述。 |
capabilities |
基于当前 Chat 模型配置生成的公开能力标记。 |
tags |
模型配置中的可选标签。 |
OpenAI 兼容 Chat Completions
POST /api/v1/chat/completions
Content-Type: application/json
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model |
string | 是 | 来自 /api/v1/models 的 Chat 模型 key。 |
messages |
array | 是 | OpenAI 风格 Chat 消息。转换后至少需要一条非 system 消息。 |
stream |
boolean | 否 | 为 true 时返回 OpenAI 兼容的 Server-Sent Events。 |
temperature |
number | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
top_p |
number | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
stop |
string 或 array | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
presence_penalty |
number | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
frequency_penalty |
number | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
response_format |
object | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
seed |
number | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
options |
object | 否 | 所选 Chat 模型配置中定义的模型专属 options。 |
extra_body |
object | 否 | 会在校验前合并到模型 options 中。 |
tools |
array | 否 | OpenAI 兼容工具定义。需要模型支持 capabilities.tools。 |
tool_choice |
string 或 object | 否 | OpenAI 兼容工具选择。需要模型支持 capabilities.tools。 |
parallel_tool_calls |
boolean | 否 | OpenAI 兼容并行工具调用控制。需要模型支持 capabilities.tools。 |
reasoning |
boolean | 否 | 仅当模型配置支持 reasoning 时启用推理能力。 |
reasoning_effort |
string 或 boolean | 否 | 当前按 reasoning 开关处理;provider 专属 effort 值应通过已配置的 options 传递。 |
max_tokens |
number | 否 | 请求输出上限,可能会被 Img2Vid 计费预留上限进一步收紧。 |
max_completion_tokens |
number | 否 | OpenAI 风格的另一种输出上限字段。 |
支持的消息内容
messages[].content 可以是字符串,也可以是内容 part 数组。
| Part 类型 | 支持字段 | 在 Img2Vid 内部的转换结果 |
|---|---|---|
text |
text |
文本 part。 |
input_text |
text |
文本 part。 |
image_url |
image_url 字符串,或 { "url": "..." } |
图片类型文件附件。 |
file |
file.file_data、file.url 或 url |
文件附件,可带 media type 和文件名。 |
附件是否真正可用取决于所选 Chat 模型配置中允许的附件类型。
请求示例
curl https://img2vid.net/api/v1/chat/completions \
-H "Authorization: Bearer $BUBLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.5",
"messages": [
{
"role": "system",
"content": "You are a concise product analyst."
},
{
"role": "user",
"content": "Summarize the main tradeoffs in this launch plan."
}
],
"temperature": 0.4,
"reasoning": true,
"max_completion_tokens": 800
}'
响应结构
{
"id": "chatcmpl-8c3d1f6b-5f04-4a8f-b75a-80f1c49e0a8d",
"object": "chat.completion",
"created": 1778716800,
"model": "openai/gpt-5.5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Here are the main tradeoffs..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 120,
"completion_tokens": 260,
"total_tokens": 380
}
}
如果 provider 返回 reasoning 文本且模型支持该能力,响应中可能包含 message.reasoning_content。如果 provider 返回 reasoning token 或 cached input token,响应中可能包含 usage.completion_tokens_details.reasoning_tokens 和 usage.prompt_tokens_details.cached_tokens。
流式响应
设置 stream: true 可以接收 OpenAI 兼容的 Server-Sent Events:
curl https://img2vid.net/api/v1/chat/completions \
-H "Authorization: Bearer $BUBLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.5",
"stream": true,
"messages": [
{
"role": "user",
"content": "Write a short launch summary."
}
]
}'
流式 chunk 使用 chat.completion.chunk 对象,并以 data: [DONE] 结束。
Anthropic 兼容 Messages
POST /api/v1/messages
Content-Type: application/json
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model |
string | 是 | 来自 /api/v1/models 的 Chat 模型 key。 |
system |
string | 否 | 会转换为 system 消息。 |
messages |
array | 是 | Anthropic 风格消息。转换后至少需要一条非 system 消息。 |
stream |
boolean | 否 | 为 true 时返回 Anthropic 兼容的 Server-Sent Events。 |
max_tokens |
number | 否 | 请求输出上限,可能会被 Img2Vid 计费预留上限进一步收紧。 |
temperature |
number | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
top_p |
number | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
top_k |
number | 否 | 仅当所选模型配置暴露该 option 时才会转发。 |
stop_sequences |
array | 否 | 当所选模型支持时,会映射为内部 stop option。 |
options |
object | 否 | 所选 Chat 模型配置中定义的模型专属 options。 |
tools |
array | 否 | Anthropic 兼容工具定义。需要模型支持 capabilities.tools。 |
tool_choice |
object | 否 | Anthropic 兼容工具选择。需要模型支持 capabilities.tools。 |
thinking |
boolean/object | 否 | 仅当模型配置支持 reasoning 时启用推理能力。 |
reasoning |
boolean | 否 | 另一种 reasoning 开关。 |
支持的消息内容
messages[].content 可以是字符串,也可以是内容 block 数组。
| Block 类型 | 支持字段 | 在 Img2Vid 内部的转换结果 |
|---|---|---|
text |
text |
文本 part。 |
image |
source.type: "url" 和 source.url |
图片文件附件。 |
image |
source.type: "base64" 和 source.data |
Data URL 图片文件附件。 |
document |
source.type: "url" 和 source.url |
文档文件附件。 |
请求示例
curl https://img2vid.net/api/v1/messages \
-H "Authorization: Bearer $BUBLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.5",
"system": "You are a concise product analyst.",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Summarize the main tradeoffs in this launch plan."
}
]
}
],
"max_tokens": 800,
"temperature": 0.4
}'
响应结构
{
"id": "msg_8c3d1f6b5f044a8fb75a80f1c49e0a8d",
"type": "message",
"role": "assistant",
"model": "openai/gpt-5.5",
"content": [
{
"type": "text",
"text": "Here are the main tradeoffs..."
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 120,
"output_tokens": 260
}
}
如果返回 reasoning 文本,响应中还会包含:
{
"thinking": [
{
"type": "thinking",
"thinking": "Reasoning text returned by the provider."
}
]
}
流式响应
设置 stream: true 可以接收 Anthropic 兼容的 Server-Sent Events:
curl https://img2vid.net/api/v1/messages \
-H "Authorization: Bearer $BUBLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.5",
"stream": true,
"messages": [
{
"role": "user",
"content": "Write a short launch summary."
}
]
}'
流式事件包括 message_start、content_block_delta、message_delta 和 message_stop。
Gemini 兼容 generateContent
POST /api/v1beta/models/{model}:generateContent
Content-Type: application/json
路径中的 {model} 是 Img2Vid Chat 模型 key。如果模型 key 中包含 /,可以作为路径层级传入,例如 /api/v1beta/models/openai/gpt-5.5:generateContent。
:generateContent 用于非流式 Gemini 兼容请求。流式请求使用 :streamGenerateContent。不要在 :generateContent 中使用 stream: true。
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
contents |
array | 是 | Gemini 风格内容列表。转换后至少需要一条非 system 消息。 |
systemInstruction |
object | 否 | 其中的 parts 会转换为 system 消息。 |
generationConfig |
object | 否 | 支持 temperature、topP、topK、stopSequences 和 maxOutputTokens。 |
generation_config |
object | 否 | generationConfig 的 snake-case 替代字段。 |
options |
object | 否 | 所选 Chat 模型配置中定义的模型专属 options。 |
tools |
array | 否 | Gemini 兼容工具声明。需要模型支持 capabilities.tools。 |
toolConfig |
object | 否 | Gemini 兼容工具配置。需要模型支持 capabilities.tools。 |
reasoning |
boolean | 否 | 仅当模型配置支持 reasoning 时启用推理能力。 |
thinkingConfig |
object | 否 | 当前按 reasoning 开关处理;provider 专属字段需要通过已配置的 options 传递。 |
支持的 parts
| Part 字段 | 在 Img2Vid 内部的转换结果 |
|---|---|
text |
文本 part。 |
fileData.fileUri |
文件附件 URL。 |
file_data.file_uri |
文件附件 URL。 |
inlineData.data |
Base64 Data URL 附件。 |
inline_data.data |
Base64 Data URL 附件。 |
contents[].role 为 model 时会转换为 assistant 消息,其他 role 会转换为 user 消息。
请求示例
curl https://img2vid.net/api/v1beta/models/openai/gpt-5.5:generateContent \
-H "Authorization: Bearer $BUBLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"systemInstruction": {
"parts": [
{
"text": "You are a concise product analyst."
}
]
},
"contents": [
{
"role": "user",
"parts": [
{
"text": "Summarize the main tradeoffs in this launch plan."
}
]
}
],
"generationConfig": {
"temperature": 0.4,
"maxOutputTokens": 800
}
}'
响应结构
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"text": "Here are the main tradeoffs..."
}
]
},
"finishReason": "STOP",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 120,
"candidatesTokenCount": 260,
"totalTokenCount": 380
},
"modelVersion": "openai/gpt-5.5"
}
Gemini 兼容 streamGenerateContent
POST /api/v1beta/models/{model}:streamGenerateContent
Content-Type: application/json
请求体与 :generateContent 保持一致,但响应通过 Server-Sent Events 返回。
请求示例
curl https://img2vid.net/api/v1beta/models/openai/gpt-5.5:streamGenerateContent \
-H "Authorization: Bearer $BUBLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{
"role": "user",
"parts": [
{
"text": "Write a short launch summary."
}
]
}
],
"generationConfig": {
"maxOutputTokens": 800
}
}'
每个流式 chunk 都是一个 Gemini 兼容的 GenerateContentResponse JSON 对象。
SDK 示例
SDK 暴露与 HTTP API 相同的三类 Chat 协议。OpenAI 兼容和 Anthropic 兼容流式调用会由 SDK 自动设置 stream: true。Gemini 兼容流式调用使用专门的 streamGenerateContent / stream_generate_content 方法,并调用 /api/v1beta/models/{model}:streamGenerateContent。
下面的片段假设你已经按快速开始初始化了 SDK client,并引入了对应语言需要的 SDK 类型。
JavaScript / TypeScript
const completion = await buble.chat.completions.create({
model: 'openai/gpt-5.5',
messages: [{ role: 'user', content: 'Write a short launch summary.' }],
max_completion_tokens: 800,
});
const stream = await buble.chat.completions.stream({
model: 'openai/gpt-5.5',
messages: [{ role: 'user', content: 'Write one sentence at a time.' }],
});
for await (const text of stream.toTextStream()) {
process.stdout.write(text);
}
Python
completion = client.chat.completions.create(
model="openai/gpt-5.5",
messages=[{"role": "user", "content": "Write a short launch summary."}],
max_completion_tokens=800,
)
for text in client.chat.completions.stream_text(
model="openai/gpt-5.5",
messages=[{"role": "user", "content": "Write one sentence at a time."}],
):
print(text, end="")
Go
completion, err := client.Chat.Completions.Create(ctx, buble.ChatRequest{
"model": "openai/gpt-5.5",
"messages": []any{
map[string]any{"role": "user", "content": "Write a short launch summary."},
},
"max_completion_tokens": 800,
})
if err != nil {
return err
}
stream, err := client.Chat.Completions.Stream(ctx, buble.ChatRequest{
"model": "openai/gpt-5.5",
"messages": []any{
map[string]any{"role": "user", "content": "Write one sentence at a time."},
},
})
if err != nil {
return err
}
defer stream.Close()
for stream.Next() {
fmt.Print(stream.Text())
}
Rust
use futures_util::StreamExt;
let completion = client.chat().completions().create(serde_json::json!({
"model": "openai/gpt-5.5",
"messages": [
{ "role": "user", "content": "Write a short launch summary." }
],
"max_completion_tokens": 800
})).await?;
let mut stream = client.chat().completions().stream_text(serde_json::json!({
"model": "openai/gpt-5.5",
"messages": [
{ "role": "user", "content": "Write one sentence at a time." }
]
})).await?;
while let Some(chunk) = stream.next().await {
print!("{}", chunk?);
}
Swift
let completion = try await client.chat.completions.create([
"model": "openai/gpt-5.5",
"messages": [
["role": "user", "content": "Write a short launch summary."]
],
"max_completion_tokens": 800
])
let stream = try await client.chat.completions.streamText([
"model": "openai/gpt-5.5",
"messages": [
["role": "user", "content": "Write one sentence at a time."]
]
])
for try await text in stream {
print(text, terminator: "")
}
Dart / Flutter
final completion = await client.chat.completions.create({
'model': 'openai/gpt-5.5',
'messages': [
{'role': 'user', 'content': 'Write a short launch summary.'},
],
'max_completion_tokens': 800,
});
final stream = await client.chat.completions.streamText({
'model': 'openai/gpt-5.5',
'messages': [
{'role': 'user', 'content': 'Write one sentence at a time.'},
],
});
await for (final text in stream) {
print(text);
}
Elixir
{:ok, completion} =
Buble.Chat.Completions.create(client, %{
model: "openai/gpt-5.5",
messages: [%{role: "user", content: "Write a short launch summary."}],
max_completion_tokens: 800
})
{:ok, stream} =
Buble.Chat.Completions.stream_text(client, %{
model: "openai/gpt-5.5",
messages: [%{role: "user", content: "Write one sentence at a time."}]
})
Enum.each(stream, &IO.write/1)
Java
var completion = client.chat().completions().create(Map.of(
"model", "openai/gpt-5.5",
"messages", List.of(Map.of("role", "user", "content", "Write a short launch summary.")),
"max_completion_tokens", 800));
try (BubleStream stream = client.chat().completions().stream(Map.of(
"model", "openai/gpt-5.5",
"messages", List.of(Map.of("role", "user", "content", "Write one sentence at a time."))))) {
while (stream.next()) {
System.out.print(stream.text());
}
}
.NET
var completion = await client.Chat.Completions.CreateAsync(new Dictionary<string, object?>
{
["model"] = "openai/gpt-5.5",
["messages"] = new[]
{
new Dictionary<string, object?>
{
["role"] = "user",
["content"] = "Write a short launch summary."
}
},
["max_completion_tokens"] = 800
});
await foreach (var text in client.Chat.Completions.StreamTextAsync(new Dictionary<string, object?>
{
["model"] = "openai/gpt-5.5",
["messages"] = new[]
{
new Dictionary<string, object?>
{
["role"] = "user",
["content"] = "Write one sentence at a time."
}
}
}))
{
Console.Write(text);
}
PHP
$completion = $client->chat()->completions()->create([
'model' => 'openai/gpt-5.5',
'messages' => [
['role' => 'user', 'content' => 'Write a short launch summary.'],
],
'max_completion_tokens' => 800,
]);
foreach ($client->chat()->completions()->streamText([
'model' => 'openai/gpt-5.5',
'messages' => [
['role' => 'user', 'content' => 'Write one sentence at a time.'],
],
]) as $text) {
echo $text;
}
Ruby
completion = client.chat.completions.create(
model: "openai/gpt-5.5",
messages: [
{ role: "user", content: "Write a short launch summary." }
],
max_completion_tokens: 800
)
client.chat.completions.stream_text(
model: "openai/gpt-5.5",
messages: [
{ role: "user", content: "Write one sentence at a time." }
]
).each do |text|
print text
end
Gemini 方法名
| 语言 | 非流式 | 流式 |
|---|---|---|
| JavaScript / TypeScript | buble.chat.gemini.generateContent(model, body) |
buble.chat.gemini.streamGenerateContent(model, body) |
| Python | client.chat.gemini.generate_content(model, **body) |
client.chat.gemini.stream_generate_content(model, **body) |
| Go | client.Chat.Gemini.GenerateContent(ctx, model, body) |
client.Chat.Gemini.StreamGenerateContent(ctx, model, body) |
| Rust | client.chat().gemini().generate_content(model, body) |
client.chat().gemini().stream_generate_content(model, body) |
| Swift | client.chat.gemini.generateContent(model, body) |
client.chat.gemini.streamGenerateContent(model, body) |
| Dart / Flutter | client.chat.gemini.generateContent(model, body) |
client.chat.gemini.streamGenerateContent(model, body) |
| Elixir | Buble.Chat.Gemini.generate_content(client, model, body) |
Buble.Chat.Gemini.stream_generate_content(client, model, body) |
| Java | client.chat().gemini().generateContent(model, body) |
client.chat().gemini().streamGenerateContent(model, body) |
| .NET | client.Chat.Gemini.GenerateContentAsync(model, body) |
client.Chat.Gemini.StreamGenerateContentAsync(model, body) |
| PHP | $client->chat()->gemini()->generateContent($model, $body) |
$client->chat()->gemini()->streamGenerateContent($model, $body) |
| Ruby | client.chat.gemini.generate_content(model, body) |
client.chat.gemini.stream_generate_content(model, body) |
Options 与能力开关
Chat 模型 options 会根据所选模型的 UI options 配置进行校验。temperature、top_p、top_k、stop 等标准字段只有在所选模型暴露对应 option 时才会被转发。模型专属参数应放在 options 中传递。
reasoning 是请求级能力开关。它只有在所选模型的 capabilities 标记支持时才会生效。
Tool calling 使用各公开协议的标准字段。如果请求包含标准 tool 字段,但所选模型没有暴露 capabilities.tools,API 会返回 tools_not_supported。
错误格式
Chat API 使用与媒体 API 相同的公开错误结构。
{
"error": {
"code": "missing_model",
"message": "model is required."
}
}
常见 Chat API 错误:
| Code | HTTP | 含义 |
|---|---|---|
missing_api_key |
401 | 未提供 API Key。 |
invalid_api_key |
401 | API Key 无效、未激活或已删除。 |
invalid_request_body |
400 | 请求体不是 JSON object。 |
missing_model |
400 | 缺少必填模型 key。 |
invalid_messages |
400 | 没有提供有效消息。 |
invalid_message_role |
400 | 消息 role 不是 system、user、assistant 或 tool。 |
unsupported_method |
404 | Gemini 兼容路由不是 :generateContent 或 :streamGenerateContent。 |
model_not_found |
404 | 模型未激活、不存在,或不可作为 Chat 模型调用。 |
tools_not_supported |
400 | 请求向不支持 tool calling 的模型传入了工具字段。 |
internal_error |
500 | 服务端非预期错误。 |