上传大模型网关资源
curl --request POST \
--url https://api.chenyu.cn/v1/assets \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file='@example-file' \
--form purpose=temp_input \
--form ttl_hours=48import requests
url = "https://api.chenyu.cn/v1/assets"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"purpose": "temp_input",
"ttl_hours": "48"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('purpose', 'temp_input');
form.append('ttl_hours', '48');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.chenyu.cn/v1/assets', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.chenyu.cn/v1/assets",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\ntemp_input\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"ttl_hours\"\r\n\r\n48\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.chenyu.cn/v1/assets"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\ntemp_input\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"ttl_hours\"\r\n\r\n48\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.chenyu.cn/v1/assets")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\ntemp_input\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"ttl_hours\"\r\n\r\n48\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chenyu.cn/v1/assets")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\ntemp_input\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"ttl_hours\"\r\n\r\n48\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"asset_id": "<string>",
"asset_uri": "asset://asset_38d2ff7769fb3b7267039941547e6a78",
"url": "<string>",
"content_url": "<string>",
"signed_url": "<string>",
"media_type": "<string>",
"mime_type": "<string>",
"size_bytes": 123,
"purpose": "<string>",
"persistent": true,
"expires_at": "2023-11-07T05:31:56Z",
"status": "<string>",
"original_filename": "<string>"
}{
"error": {
"message": "<string>",
"type": "<string>",
"param": "<string>",
"code": "<string>"
}
}资源管理
上传资源
上传用于大模型网关输入的临时资源
POST
/
v1
/
assets
上传大模型网关资源
curl --request POST \
--url https://api.chenyu.cn/v1/assets \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form file='@example-file' \
--form purpose=temp_input \
--form ttl_hours=48import requests
url = "https://api.chenyu.cn/v1/assets"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"purpose": "temp_input",
"ttl_hours": "48"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('purpose', 'temp_input');
form.append('ttl_hours', '48');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.chenyu.cn/v1/assets', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.chenyu.cn/v1/assets",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\ntemp_input\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"ttl_hours\"\r\n\r\n48\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.chenyu.cn/v1/assets"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\ntemp_input\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"ttl_hours\"\r\n\r\n48\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.chenyu.cn/v1/assets")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\ntemp_input\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"ttl_hours\"\r\n\r\n48\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chenyu.cn/v1/assets")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"purpose\"\r\n\r\ntemp_input\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"ttl_hours\"\r\n\r\n48\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"asset_id": "<string>",
"asset_uri": "asset://asset_38d2ff7769fb3b7267039941547e6a78",
"url": "<string>",
"content_url": "<string>",
"signed_url": "<string>",
"media_type": "<string>",
"mime_type": "<string>",
"size_bytes": 123,
"purpose": "<string>",
"persistent": true,
"expires_at": "2023-11-07T05:31:56Z",
"status": "<string>",
"original_filename": "<string>"
}{
"error": {
"message": "<string>",
"type": "<string>",
"param": "<string>",
"code": "<string>"
}
}上传资源
上传图片、视频、音频或文件,生成可在大模型网关请求中使用的临时资源地址。适用于视频首帧、尾帧、参考图等输入素材。上传成功后使用返回的
asset_uri 字段值,例如 asset://asset_xxx。提交模型请求时直接把这个字符串放入图片、视频或音频字段,不需要再包一层对象。临时资源默认 48 小时有效。图片资源支持形式
大模型网关对外统一推荐两种写法:普通字段直接传资源字符串;需要声明素材角色或在提示词里引用素材时,使用{ "uri": "...", "role": "...", "label": "..." } 对象。
公网 URL
图片地址必须能被服务端访问。{
"image": "https://example.com/input.png"
}
Base64 Data URL
使用data:image/<format>;base64,<data>,其中 <format> 使用小写格式名,例如 png、jpeg、webp。
{
"image": "data:image/png;base64,iVBORw0KGgo..."
}
资源 ID
先调用本接口上传本地文件,再把返回的asset_uri 字段值放入图片字段。
{
"image": "asset://asset_38d2ff7769fb3b7267039941547e6a78"
}
带角色或引用标签的对象
只有需要声明首帧、尾帧、参考图等素材角色,或需要在提示词里用@标签 指向素材时,才使用对象写法。对象里统一使用 uri 存资源字符串。
{
"first_frame": {
"uri": "asset://asset_38d2ff7769fb3b7267039941547e6a78",
"role": "first_frame",
"label": "首帧"
}
}
label 是素材显示名,不需要带 @。在 prompt 里用 @首帧 引用时,服务端会把它绑定到当前请求中的这张图片。
支持图片资源的字段
以下字段会被网关识别并转为上游模型可访问的地址:| 接口 | 字段 |
|---|---|
/v1/images/generations | image、images、input_image、input_image_url、reference_image、reference_images、mask |
/v1/images/edits | image、images、input_image、input_image_url、reference_image、reference_images、mask |
/v1/videos | first_frame、last_frame、image、image_url、images、image_urls、reference_image、reference_images、reference_image_url、reference_image_urls、image_with_roles、images_with_roles |
| Chat Completions / Responses | content 数组里的 image_url、image、input_image |
multipart/form-data 文件上传,文件字段包括 image、image[] 和 mask。
请求参数
请求类型为multipart/form-data。
file
required
要上传的本地文件,单个文件最大 100MB
string
资源类型。常用值:
image、video、audio、file。不传时服务端会根据文件类型推断string
资源用途。当前对外接口仅支持
temp_input,不传时默认 temp_inputinteger
临时资源有效小时数。不传时默认 48 小时
响应参数
string
资源 ID
string
资源 ID,与
id 含义一致string
资源引用地址,提交模型请求时优先使用,例如
asset://asset_xxxstring
资源访问地址
string
资源内容访问地址,与
url 含义一致string
带签名的临时访问地址
string
资源类型,例如
imagestring
MIME 类型,例如
image/pnginteger
文件大小,单位字节
string
资源用途,当前为
temp_inputboolean
是否为长期资源。临时输入资源一般为
falsestring
临时资源过期时间
string
资源状态。可用状态通常为
confirmed代码示例
import requests
url = "https://api.chenyu.cn/v1/assets"
headers = {"Authorization": "Bearer your_api_key"}
files = {"file": open("first-frame.png", "rb")}
data = {
"media_type": "image",
"purpose": "temp_input"
}
response = requests.post(url, headers=headers, files=files, data=data)
print(response.json()["asset_uri"])
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');
const form = new FormData();
form.append('file', fs.createReadStream('first-frame.png'));
form.append('media_type', 'image');
form.append('purpose', 'temp_input');
axios.post('https://api.chenyu.cn/v1/assets', form, {
headers: {
Authorization: 'Bearer your_api_key',
...form.getHeaders()
}
}).then((response) => {
console.log(response.data.asset_uri);
});
curl -X POST "https://api.chenyu.cn/v1/assets" \
-H "Authorization: Bearer your_api_key" \
-F "file=@first-frame.png" \
-F "media_type=image" \
-F "purpose=temp_input"
响应示例
{
"id": "asset_38d2ff7769fb3b7267039941547e6a78",
"asset_id": "asset_38d2ff7769fb3b7267039941547e6a78",
"asset_uri": "asset://asset_38d2ff7769fb3b7267039941547e6a78",
"url": "https://www.chenyu.team/assets/asset_38d2ff7769fb3b7267039941547e6a78/content",
"content_url": "https://www.chenyu.team/assets/asset_38d2ff7769fb3b7267039941547e6a78/content",
"signed_url": "https://www.chenyu.team/assets/asset_38d2ff7769fb3b7267039941547e6a78/content?expires=1781295600&signature=xxxx",
"media_type": "image",
"mime_type": "image/png",
"size_bytes": 102400,
"purpose": "temp_input",
"persistent": false,
"expires_at": "2026-06-16T12:00:00+08:00",
"status": "confirmed",
"original_filename": "first-frame.png"
}
在模型请求中使用
媒体字段支持三种写法:{
"first_frame": "https://example.com/first-frame.png"
}
{
"first_frame": "data:image/png;base64,iVBORw0KGgo..."
}
{
"first_frame": "asset://asset_38d2ff7769fb3b7267039941547e6a78"
}
@标签 引用素材时,可以使用对象写法:
{
"first_frame": {
"uri": "asset://asset_38d2ff7769fb3b7267039941547e6a78",
"role": "first_frame",
"label": "首帧"
}
}
{
"model": "doubao-seedance-2-0-fast-260128",
"generation_category": "reference_to_video",
"prompt": "@阿九 和 @沈渡 在舞台上跳舞",
"images": [
{
"uri": "asset://asset_person_a",
"label": "阿九",
"role": "reference_image"
},
{
"uri": "asset://asset_person_b",
"label": "沈渡",
"role": "reference_image"
}
]
}
label 不能重复;label 可写成 阿九,不要写成普通文本占位。提示词中引用时写 @阿九,也兼容 {{阿九}}。Authorizations
API Key,格式:Bearer your_api_key
Body
multipart/form-data
Response
上传结果
资源 ID;大模型网关响应包含此字段
资源 ID
提交工作流或模型请求时使用的资源引用地址
Example:
"asset://asset_38d2ff7769fb3b7267039941547e6a78"
资源访问地址
资源内容访问地址
带签名的临时访问地址
资源类型
MIME 类型
文件大小,单位字节
资源用途
是否为长期资源
临时资源过期时间
资源状态
原始文件名